@stll/stdnum 0.0.1 → 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/LICENSE +1 -5
- package/README.md +28 -4
- package/dist/_checksums/mod112.js +5 -5
- package/dist/_checksums/mod112.js.map +1 -1
- package/dist/_util/generate.d.ts +13 -1
- package/dist/_util/generate.js +23 -1
- package/dist/_util/generate.js.map +1 -1
- package/dist/ad/mod.d.ts +3 -2
- package/dist/ad/nrt.js +3 -2
- package/dist/ad/nrt.js.map +1 -1
- package/dist/ae/eid.d.ts +0 -1
- package/dist/ae/mod.d.ts +3 -2
- package/dist/ai/mod.d.ts +3 -2
- package/dist/al/mod.d.ts +3 -2
- package/dist/am/mod.d.ts +3 -2
- package/dist/ar/cbu.d.ts +0 -1
- package/dist/ar/cbu.js +1 -1
- package/dist/ar/cbu.js.map +1 -1
- package/dist/ar/cuit.d.ts +0 -1
- package/dist/ar/cuit.js +12 -12
- package/dist/ar/cuit.js.map +1 -1
- package/dist/ar/mod.d.ts +3 -2
- package/dist/at/mod.d.ts +3 -2
- package/dist/at/tin.d.ts +0 -1
- package/dist/at/uid.d.ts +0 -1
- package/dist/at/vnr.d.ts +3 -2
- package/dist/at/vnr.js +20 -3
- package/dist/at/vnr.js.map +1 -1
- package/dist/au/abn.d.ts +0 -1
- package/dist/au/acn.d.ts +0 -1
- package/dist/au/mod.d.ts +3 -2
- package/dist/au/tfn.d.ts +0 -1
- package/dist/az/mod.d.ts +3 -2
- package/dist/az/voen.d.ts +0 -1
- package/dist/az/voen.js.map +1 -1
- package/dist/ba/jmbg.d.ts +1 -2
- package/dist/ba/jmbg.js +1 -0
- package/dist/ba/jmbg.js.map +1 -1
- package/dist/ba/mod.d.ts +3 -2
- package/dist/bd/mod.d.ts +3 -2
- package/dist/bd/nid.js +10 -11
- package/dist/bd/nid.js.map +1 -1
- package/dist/be/bis.d.ts +0 -1
- package/dist/be/mod.d.ts +3 -2
- package/dist/be/nn.d.ts +0 -1
- package/dist/be/vat.d.ts +0 -1
- package/dist/bg/egn.d.ts +1 -2
- package/dist/bg/egn.js +10 -3
- package/dist/bg/egn.js.map +1 -1
- package/dist/bg/mod.d.ts +3 -2
- package/dist/bg/pnf.d.ts +0 -1
- package/dist/bg/vat.d.ts +0 -1
- package/dist/bh/cpr.d.ts +3 -2
- package/dist/bh/cpr.js +8 -2
- package/dist/bh/cpr.js.map +1 -1
- package/dist/bh/mod.d.ts +3 -2
- package/dist/bic.js +13 -15
- package/dist/bic.js.map +1 -1
- package/dist/br/cnpj.d.ts +0 -1
- package/dist/br/cpf.d.ts +0 -1
- package/dist/br/mod.d.ts +3 -2
- package/dist/by/mod.d.ts +3 -2
- package/dist/by/unp.d.ts +0 -1
- package/dist/by/unp.js +6 -3
- package/dist/by/unp.js.map +1 -1
- package/dist/bz/mod.d.ts +3 -2
- package/dist/bz/tin.d.ts +3 -2
- package/dist/bz/tin.js +9 -1
- package/dist/bz/tin.js.map +1 -1
- package/dist/ca/bn.d.ts +0 -1
- package/dist/ca/mod.d.ts +3 -2
- package/dist/ca/sin.d.ts +0 -1
- package/dist/ch/mod.d.ts +3 -2
- package/dist/ch/ssn.d.ts +0 -1
- package/dist/ch/uid.d.ts +0 -1
- package/dist/ch/vat.d.ts +0 -1
- package/dist/cl/mod.d.ts +3 -2
- package/dist/cl/rut.d.ts +0 -1
- package/dist/cl/rut.js +1 -1
- package/dist/cl/rut.js.map +1 -1
- package/dist/cn/mod.d.ts +3 -2
- package/dist/cn/ric.d.ts +1 -2
- package/dist/cn/ric.js +1 -0
- package/dist/cn/ric.js.map +1 -1
- package/dist/cn/uscc.d.ts +0 -1
- package/dist/cn/uscc.js +7 -6
- package/dist/cn/uscc.js.map +1 -1
- package/dist/co/mod.d.ts +3 -2
- package/dist/co/nit.d.ts +0 -1
- package/dist/co/nit.js +4 -1
- package/dist/co/nit.js.map +1 -1
- package/dist/cr/cpf.js +4 -3
- package/dist/cr/cpf.js.map +1 -1
- package/dist/cr/mod.d.ts +3 -2
- package/dist/creditcard.d.ts +0 -1
- package/dist/cu/mod.d.ts +3 -2
- package/dist/cu/ni.d.ts +4 -3
- package/dist/cu/ni.js +11 -1
- package/dist/cu/ni.js.map +1 -1
- package/dist/cy/mod.d.ts +3 -2
- package/dist/cy/vat.d.ts +0 -1
- package/dist/cz/dic.d.ts +0 -1
- package/dist/cz/ico.d.ts +0 -1
- package/dist/cz/mod.d.ts +3 -2
- package/dist/cz/rc.d.ts +1 -2
- package/dist/cz/rc.js +33 -8
- package/dist/cz/rc.js.map +1 -1
- package/dist/de/handelsreg.js +9 -9
- package/dist/de/handelsreg.js.map +1 -1
- package/dist/de/idnr.d.ts +0 -1
- package/dist/de/idnr.js.map +1 -1
- package/dist/de/mod.d.ts +3 -2
- package/dist/de/stnr.d.ts +0 -1
- package/dist/de/stnr.js.map +1 -1
- package/dist/de/svnr.d.ts +0 -1
- package/dist/de/svnr.js +2 -2
- package/dist/de/svnr.js.map +1 -1
- package/dist/de/vat.d.ts +0 -1
- package/dist/dk/cpr.d.ts +4 -3
- package/dist/dk/cpr.js +12 -2
- package/dist/dk/cpr.js.map +1 -1
- package/dist/dk/cvr.d.ts +0 -1
- package/dist/dk/mod.d.ts +3 -2
- package/dist/dk/vat.d.ts +0 -1
- package/dist/do/mod.d.ts +3 -2
- package/dist/do/rnc.d.ts +0 -1
- package/dist/do/rnc.js +1 -1
- package/dist/do/rnc.js.map +1 -1
- package/dist/ec/mod.d.ts +3 -2
- package/dist/ec/ruc.d.ts +0 -1
- package/dist/ec/ruc.js +1 -1
- package/dist/ec/ruc.js.map +1 -1
- package/dist/ee/ik.d.ts +1 -2
- package/dist/ee/ik.js +12 -4
- package/dist/ee/ik.js.map +1 -1
- package/dist/ee/mod.d.ts +3 -2
- package/dist/ee/registrikood.d.ts +0 -1
- package/dist/ee/registrikood.js +8 -7
- package/dist/ee/registrikood.js.map +1 -1
- package/dist/ee/vat.d.ts +0 -1
- package/dist/eg/mod.d.ts +3 -2
- package/dist/es/cif.d.ts +0 -1
- package/dist/es/cif.js +2 -2
- package/dist/es/cif.js.map +1 -1
- package/dist/es/dni.d.ts +0 -1
- package/dist/es/mod.d.ts +3 -2
- package/dist/es/nie.d.ts +0 -1
- package/dist/es/nie.js +13 -13
- package/dist/es/nie.js.map +1 -1
- package/dist/es/nss.d.ts +0 -1
- package/dist/es/vat.d.ts +0 -1
- package/dist/eu/mod.d.ts +3 -2
- package/dist/eu/vat.d.ts +3 -2
- package/dist/eu/vat.js +43 -2
- package/dist/eu/vat.js.map +1 -1
- package/dist/fi/hetu.d.ts +4 -3
- package/dist/fi/hetu.js +17 -2
- package/dist/fi/hetu.js.map +1 -1
- package/dist/fi/mod.d.ts +3 -2
- package/dist/fi/vat.d.ts +0 -1
- package/dist/fi/ytunnus.d.ts +0 -1
- package/dist/fr/mod.d.ts +3 -2
- package/dist/fr/nif.d.ts +0 -1
- package/dist/fr/nir.d.ts +1 -2
- package/dist/fr/nir.js +1 -0
- package/dist/fr/nir.js.map +1 -1
- package/dist/fr/siren.d.ts +0 -1
- package/dist/fr/siret.d.ts +0 -1
- package/dist/fr/tva.d.ts +0 -1
- package/dist/gb/mod.d.ts +3 -2
- package/dist/gb/nino.js +7 -7
- package/dist/gb/nino.js.map +1 -1
- package/dist/gb/sedol.d.ts +0 -1
- package/dist/gb/sedol.js +8 -7
- package/dist/gb/sedol.js.map +1 -1
- package/dist/gb/utr.d.ts +0 -1
- package/dist/gb/vat.d.ts +0 -1
- package/dist/ge/mod.d.ts +3 -2
- package/dist/gh/mod.d.ts +3 -2
- package/dist/gh/tin.d.ts +0 -1
- package/dist/gh/tin.js +9 -9
- package/dist/gh/tin.js.map +1 -1
- package/dist/gr/amka.d.ts +0 -1
- package/dist/gr/mod.d.ts +3 -2
- package/dist/gr/vat.d.ts +0 -1
- package/dist/gt/mod.d.ts +3 -2
- package/dist/gt/nit.d.ts +0 -1
- package/dist/gt/nit.js +5 -2
- package/dist/gt/nit.js.map +1 -1
- package/dist/hk/hkid.d.ts +0 -1
- package/dist/hk/hkid.js +1 -0
- package/dist/hk/hkid.js.map +1 -1
- package/dist/hk/mod.d.ts +3 -2
- package/dist/hr/mod.d.ts +3 -2
- package/dist/hr/vat.d.ts +0 -1
- package/dist/hu/mod.d.ts +3 -2
- package/dist/hu/vat.d.ts +0 -1
- package/dist/iban.d.ts +0 -1
- package/dist/id/mod.d.ts +3 -2
- package/dist/id/npwp.d.ts +0 -1
- package/dist/ie/mod.d.ts +3 -2
- package/dist/ie/pps.d.ts +0 -1
- package/dist/ie/vat.d.ts +0 -1
- package/dist/il/idnr.d.ts +0 -1
- package/dist/il/mod.d.ts +3 -2
- package/dist/in/aadhaar.d.ts +0 -1
- package/dist/in/gstin.d.ts +0 -1
- package/dist/in/gstin.js +3 -1
- package/dist/in/gstin.js.map +1 -1
- package/dist/in/mod.d.ts +3 -2
- package/dist/in/pan.js +2 -2
- package/dist/in/pan.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/iq/mod.d.ts +3 -2
- package/dist/ir/mod.d.ts +3 -2
- package/dist/ir/nid.d.ts +0 -1
- package/dist/is/kennitala.d.ts +0 -1
- package/dist/is/mod.d.ts +3 -2
- package/dist/isin.d.ts +0 -1
- package/dist/isin.js +9 -9
- package/dist/isin.js.map +1 -1
- package/dist/it/codicefiscale.d.ts +4 -3
- package/dist/it/codicefiscale.js +26 -2
- package/dist/it/codicefiscale.js.map +1 -1
- package/dist/it/iva.d.ts +0 -1
- package/dist/it/mod.d.ts +3 -2
- package/dist/jp/cn.d.ts +0 -1
- package/dist/jp/mod.d.ts +3 -2
- package/dist/jp/mynumber.d.ts +0 -1
- package/dist/kr/mod.d.ts +3 -2
- package/dist/kr/rrn.d.ts +4 -3
- package/dist/kr/rrn.js +13 -2
- package/dist/kr/rrn.js.map +1 -1
- package/dist/kw/civil.d.ts +6 -5
- package/dist/kw/civil.js +18 -3
- package/dist/kw/civil.js.map +1 -1
- package/dist/kw/mod.d.ts +3 -2
- package/dist/kz/iin.d.ts +1 -2
- package/dist/kz/iin.js +1 -0
- package/dist/kz/iin.js.map +1 -1
- package/dist/kz/mod.d.ts +3 -2
- package/dist/lei.d.ts +0 -1
- package/dist/li/mod.d.ts +3 -2
- package/dist/lk/mod.d.ts +3 -2
- package/dist/lk/nic.d.ts +4 -3
- package/dist/lk/nic.js +14 -2
- package/dist/lk/nic.js.map +1 -1
- package/dist/lt/asmens.d.ts +0 -1
- package/dist/lt/mod.d.ts +3 -2
- package/dist/lt/vat.d.ts +0 -1
- package/dist/lu/mod.d.ts +3 -2
- package/dist/lu/vat.d.ts +0 -1
- package/dist/luhn.d.ts +0 -1
- package/dist/luhn.js +7 -0
- package/dist/luhn.js.map +1 -1
- package/dist/lv/mod.d.ts +3 -2
- package/dist/lv/vat.d.ts +0 -1
- package/dist/lv/vat.js +39 -12
- package/dist/lv/vat.js.map +1 -1
- package/dist/ma/ice.d.ts +0 -1
- package/dist/ma/mod.d.ts +3 -2
- package/dist/mc/mod.d.ts +3 -2
- package/dist/mc/tva.d.ts +0 -1
- package/dist/md/idno.d.ts +0 -1
- package/dist/md/mod.d.ts +3 -2
- package/dist/me/mod.d.ts +3 -2
- package/dist/me/pib.d.ts +0 -1
- package/dist/mk/edb.d.ts +0 -1
- package/dist/mk/mod.d.ts +3 -2
- package/dist/mt/mod.d.ts +3 -2
- package/dist/mt/vat.d.ts +0 -1
- package/dist/mu/mod.d.ts +3 -2
- package/dist/mx/clabe.d.ts +0 -1
- package/dist/mx/curp.d.ts +4 -3
- package/dist/mx/curp.js +25 -3
- package/dist/mx/curp.js.map +1 -1
- package/dist/mx/mod.d.ts +3 -2
- package/dist/mx/rfc.d.ts +3 -2
- package/dist/mx/rfc.js +21 -2
- package/dist/mx/rfc.js.map +1 -1
- package/dist/my/mod.d.ts +3 -2
- package/dist/my/nric.d.ts +4 -3
- package/dist/my/nric.js +16 -2
- package/dist/my/nric.js.map +1 -1
- package/dist/ng/mod.d.ts +3 -2
- package/dist/ni/mod.d.ts +3 -2
- package/dist/ni/ruc.d.ts +0 -1
- package/dist/nl/bsn.d.ts +0 -1
- package/dist/nl/mod.d.ts +3 -2
- package/dist/nl/vat.d.ts +0 -1
- package/dist/nl/vat.js +9 -43
- package/dist/nl/vat.js.map +1 -1
- package/dist/no/fodselsnummer.d.ts +1 -2
- package/dist/no/fodselsnummer.js +1 -0
- package/dist/no/fodselsnummer.js.map +1 -1
- package/dist/no/mod.d.ts +3 -2
- package/dist/no/mva.d.ts +0 -1
- package/dist/no/orgnr.d.ts +0 -1
- package/dist/nz/ird.d.ts +0 -1
- package/dist/nz/ird.js +2 -2
- package/dist/nz/ird.js.map +1 -1
- package/dist/nz/mod.d.ts +3 -2
- package/dist/pa/mod.d.ts +3 -2
- package/dist/pa/ruc.d.ts +0 -1
- package/dist/pa/ruc.js +3 -1
- package/dist/pa/ruc.js.map +1 -1
- package/dist/patterns.d.ts +1 -4
- package/dist/patterns.js +80 -23
- package/dist/patterns.js.map +1 -1
- package/dist/pe/mod.d.ts +3 -2
- package/dist/pe/ruc.d.ts +0 -1
- package/dist/pe/ruc.js +9 -9
- package/dist/pe/ruc.js.map +1 -1
- package/dist/ph/mod.d.ts +3 -2
- package/dist/pk/cnic.js.map +1 -1
- package/dist/pk/mod.d.ts +3 -2
- package/dist/pl/mod.d.ts +3 -2
- package/dist/pl/nip.d.ts +0 -1
- package/dist/pl/pesel.d.ts +1 -2
- package/dist/pl/pesel.js +1 -0
- package/dist/pl/pesel.js.map +1 -1
- package/dist/pl/regon.d.ts +0 -1
- package/dist/pt/cc.d.ts +0 -1
- package/dist/pt/cc.js +6 -4
- package/dist/pt/cc.js.map +1 -1
- package/dist/pt/mod.d.ts +3 -2
- package/dist/pt/vat.d.ts +0 -1
- package/dist/ro/cnp.d.ts +1 -2
- package/dist/ro/cnp.js +1 -0
- package/dist/ro/cnp.js.map +1 -1
- package/dist/ro/mod.d.ts +3 -2
- package/dist/ro/vat.d.ts +0 -1
- package/dist/rs/mod.d.ts +3 -2
- package/dist/rs/pib.d.ts +0 -1
- package/dist/ru/inn.d.ts +0 -1
- package/dist/ru/inn.js +1 -1
- package/dist/ru/inn.js.map +1 -1
- package/dist/ru/mod.d.ts +3 -2
- package/dist/se/mod.d.ts +3 -2
- package/dist/se/orgnr.d.ts +0 -1
- package/dist/se/personnummer.d.ts +1 -2
- package/dist/se/personnummer.js +1 -0
- package/dist/se/personnummer.js.map +1 -1
- package/dist/se/vat.d.ts +0 -1
- package/dist/sg/mod.d.ts +3 -2
- package/dist/sg/uen.d.ts +0 -1
- package/dist/sg/uen.js +46 -55
- package/dist/sg/uen.js.map +1 -1
- package/dist/si/emso.d.ts +1 -2
- package/dist/si/emso.js +17 -4
- package/dist/si/emso.js.map +1 -1
- package/dist/si/mod.d.ts +3 -2
- package/dist/si/vat.d.ts +0 -1
- package/dist/sk/dic.d.ts +0 -1
- package/dist/sk/ico.d.ts +0 -1
- package/dist/sk/mod.d.ts +3 -2
- package/dist/sk/rc.d.ts +4 -5
- package/dist/sk/rc.js +5 -2
- package/dist/sk/rc.js.map +1 -1
- package/dist/th/mod.d.ts +3 -2
- package/dist/th/tin.d.ts +0 -1
- package/dist/tr/mod.d.ts +3 -2
- package/dist/tr/tckimlik.d.ts +0 -1
- package/dist/tr/vkn.d.ts +0 -1
- package/dist/tw/mod.d.ts +3 -2
- package/dist/tw/ubn.d.ts +0 -1
- package/dist/tw/ubn.js +1 -1
- package/dist/tw/ubn.js.map +1 -1
- package/dist/types.d.ts +35 -22
- package/dist/ua/edrpou.d.ts +0 -1
- package/dist/ua/edrpou.js +4 -1
- package/dist/ua/edrpou.js.map +1 -1
- package/dist/ua/mod.d.ts +3 -2
- package/dist/us/ein.js +87 -87
- package/dist/us/ein.js.map +1 -1
- package/dist/us/itin.js +3 -4
- package/dist/us/itin.js.map +1 -1
- package/dist/us/mod.d.ts +3 -2
- package/dist/us/rtn.d.ts +0 -1
- package/dist/us/rtn.js +8 -5
- package/dist/us/rtn.js.map +1 -1
- package/dist/uy/mod.d.ts +3 -2
- package/dist/uy/rut.d.ts +0 -1
- package/dist/uy/rut.js +1 -1
- package/dist/uy/rut.js.map +1 -1
- package/dist/ve/mod.d.ts +3 -2
- package/dist/ve/rif.d.ts +0 -1
- package/dist/ve/rif.js +11 -11
- package/dist/ve/rif.js.map +1 -1
- package/dist/vn/mod.d.ts +3 -2
- package/dist/vn/mst.d.ts +0 -1
- package/dist/za/idnr.d.ts +1 -2
- package/dist/za/idnr.js +1 -0
- package/dist/za/idnr.js.map +1 -1
- package/dist/za/mod.d.ts +3 -2
- package/package.json +18 -15
- package/src/_checksums/mod112.ts +7 -6
- package/src/_util/generate.ts +38 -0
- package/src/ad/nrt.ts +12 -4
- package/src/ar/cbu.ts +2 -2
- package/src/ar/cuit.ts +15 -7
- package/src/at/vnr.ts +26 -4
- package/src/az/voen.ts +2 -0
- package/src/ba/jmbg.ts +2 -1
- package/src/bd/nid.ts +4 -4
- package/src/bg/egn.ts +12 -4
- package/src/bh/cpr.ts +10 -1
- package/src/bic.ts +19 -17
- package/src/by/unp.ts +9 -4
- package/src/bz/tin.ts +12 -1
- package/src/cl/rut.ts +4 -2
- package/src/cn/ric.ts +4 -1
- package/src/cn/uscc.ts +20 -8
- package/src/co/nit.ts +6 -2
- package/src/cr/cpf.ts +4 -3
- package/src/cu/ni.ts +22 -2
- package/src/cz/rc.ts +54 -23
- package/src/de/handelsreg.ts +14 -3
- package/src/de/idnr.ts +3 -0
- package/src/de/stnr.ts +4 -0
- package/src/de/svnr.ts +7 -2
- package/src/dk/cpr.ts +16 -2
- package/src/do/rnc.ts +2 -2
- package/src/ec/ruc.ts +2 -2
- package/src/ee/ik.ts +14 -4
- package/src/ee/registrikood.ts +4 -3
- package/src/es/cif.ts +2 -3
- package/src/es/nie.ts +10 -5
- package/src/eu/vat.ts +46 -1
- package/src/fi/hetu.ts +19 -2
- package/src/fr/nir.ts +2 -1
- package/src/gb/nino.ts +11 -10
- package/src/gb/sedol.ts +14 -12
- package/src/gh/tin.ts +4 -3
- package/src/gt/nit.ts +6 -3
- package/src/hk/hkid.ts +2 -1
- package/src/in/gstin.ts +3 -1
- package/src/in/pan.ts +8 -3
- package/src/index.ts +3 -0
- package/src/isin.ts +10 -4
- package/src/it/codicefiscale.ts +40 -2
- package/src/kr/rrn.ts +20 -2
- package/src/kw/civil.ts +25 -9
- package/src/kz/iin.ts +2 -1
- package/src/lk/nic.ts +24 -2
- package/src/luhn.ts +3 -0
- package/src/lv/vat.ts +46 -20
- package/src/mx/curp.ts +41 -5
- package/src/mx/rfc.ts +35 -4
- package/src/my/nric.ts +26 -2
- package/src/nl/vat.ts +11 -66
- package/src/no/fodselsnummer.ts +2 -1
- package/src/nz/ird.ts +4 -4
- package/src/pa/ruc.ts +32 -8
- package/src/patterns.ts +135 -28
- package/src/pe/ruc.ts +6 -7
- package/src/pk/cnic.ts +2 -0
- package/src/pl/pesel.ts +2 -1
- package/src/pt/cc.ts +6 -4
- package/src/ro/cnp.ts +2 -1
- package/src/ru/inn.ts +2 -2
- package/src/se/personnummer.ts +2 -1
- package/src/sg/uen.ts +37 -20
- package/src/si/emso.ts +30 -5
- package/src/sk/rc.ts +13 -4
- package/src/tw/ubn.ts +2 -2
- package/src/types.ts +37 -6
- package/src/ua/edrpou.ts +3 -2
- package/src/us/ein.ts +88 -88
- package/src/us/itin.ts +7 -8
- package/src/us/rtn.ts +16 -11
- package/src/uy/rut.ts +2 -2
- package/src/ve/rif.ts +11 -6
- package/src/za/idnr.ts +2 -1
package/src/eu/vat.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { clean } from "#util/clean";
|
|
16
|
+
import { randomInt } from "#util/generate";
|
|
16
17
|
import { err } from "#util/result";
|
|
17
18
|
|
|
18
19
|
import atUid from "../at/uid";
|
|
@@ -152,6 +153,49 @@ const format = (value: string): string => {
|
|
|
152
153
|
return `${parts.cc}${validator.compact(parts.rest)}`;
|
|
153
154
|
};
|
|
154
155
|
|
|
156
|
+
const GENERATORS = [
|
|
157
|
+
["AT", atUid],
|
|
158
|
+
["BE", beVat],
|
|
159
|
+
["BG", bgVat],
|
|
160
|
+
["CY", cyVat],
|
|
161
|
+
["CZ", czDic],
|
|
162
|
+
["DE", deVat],
|
|
163
|
+
["DK", dkVat],
|
|
164
|
+
["EE", eeVat],
|
|
165
|
+
["ES", esVat],
|
|
166
|
+
["FI", fiVat],
|
|
167
|
+
["FR", frTva],
|
|
168
|
+
["GR", grVat],
|
|
169
|
+
["HR", hrVat],
|
|
170
|
+
["HU", huVat],
|
|
171
|
+
["IE", ieVat],
|
|
172
|
+
["IT", itIva],
|
|
173
|
+
["LT", ltVat],
|
|
174
|
+
["LU", luVat],
|
|
175
|
+
["LV", lvVat],
|
|
176
|
+
["MT", mtVat],
|
|
177
|
+
["NL", nlVat],
|
|
178
|
+
["PL", plNip],
|
|
179
|
+
["PT", ptVat],
|
|
180
|
+
["RO", roVat],
|
|
181
|
+
["SE", seVat],
|
|
182
|
+
["SI", siVat],
|
|
183
|
+
["SK", skDic],
|
|
184
|
+
] as const;
|
|
185
|
+
|
|
186
|
+
/** Generate a random EU VAT number from a member validator. */
|
|
187
|
+
const generate = (): string => {
|
|
188
|
+
for (;;) {
|
|
189
|
+
const candidate =
|
|
190
|
+
GENERATORS[randomInt(0, GENERATORS.length - 1)];
|
|
191
|
+
if (!candidate) continue;
|
|
192
|
+
|
|
193
|
+
const [prefix, validator] = candidate;
|
|
194
|
+
if (validator.generate === undefined) continue;
|
|
195
|
+
return `${prefix}${validator.generate()}`;
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
155
199
|
/** European Union VAT Number. */
|
|
156
200
|
const euVat: Validator = {
|
|
157
201
|
name: "EU VAT Number",
|
|
@@ -165,7 +209,8 @@ const euVat: Validator = {
|
|
|
165
209
|
compact,
|
|
166
210
|
format,
|
|
167
211
|
validate,
|
|
212
|
+
generate,
|
|
168
213
|
};
|
|
169
214
|
|
|
170
215
|
export default euVat;
|
|
171
|
-
export { compact, format, validate };
|
|
216
|
+
export { compact, format, generate, validate };
|
package/src/fi/hetu.ts
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import { clean } from "#util/clean";
|
|
12
12
|
import { isValidDate } from "#util/date";
|
|
13
|
+
import { randomInt } from "#util/generate";
|
|
13
14
|
import { err } from "#util/result";
|
|
14
15
|
import { isdigits } from "#util/strings";
|
|
15
16
|
|
|
@@ -158,8 +159,21 @@ const parse = (value: string): ParsedPersonId | null => {
|
|
|
158
159
|
};
|
|
159
160
|
};
|
|
160
161
|
|
|
162
|
+
/** Generate a random valid HETU. */
|
|
163
|
+
const generate = (): string => {
|
|
164
|
+
const year = randomInt(1900, 2024);
|
|
165
|
+
const month = String(randomInt(1, 12)).padStart(2, "0");
|
|
166
|
+
const day = String(randomInt(1, 28)).padStart(2, "0");
|
|
167
|
+
const yy = String(year % 100).padStart(2, "0");
|
|
168
|
+
const separator = year >= 2000 ? "A" : "-";
|
|
169
|
+
const serial = String(randomInt(2, 899)).padStart(3, "0");
|
|
170
|
+
const checkNum = Number(`${day}${month}${yy}${serial}`);
|
|
171
|
+
const checkChar = CHECK_CHARS.charAt(checkNum % 31);
|
|
172
|
+
return `${day}${month}${yy}${separator}${serial}${checkChar}`;
|
|
173
|
+
};
|
|
174
|
+
|
|
161
175
|
/** Finnish Personal Identity Code. */
|
|
162
|
-
const hetu: Validator = {
|
|
176
|
+
const hetu: Validator<ParsedPersonId> = {
|
|
163
177
|
name: "Finnish Personal ID",
|
|
164
178
|
localName: "Henkilötunnus",
|
|
165
179
|
abbreviation: "HETU",
|
|
@@ -172,11 +186,14 @@ const hetu: Validator = {
|
|
|
172
186
|
country: "FI",
|
|
173
187
|
entityType: "person",
|
|
174
188
|
sourceUrl: "https://dvv.fi/en/personal-identity-code",
|
|
189
|
+
lengths: [11] as const,
|
|
175
190
|
examples: ["131052-308T"] as const,
|
|
176
191
|
compact,
|
|
177
192
|
format,
|
|
193
|
+
parse,
|
|
178
194
|
validate,
|
|
195
|
+
generate,
|
|
179
196
|
};
|
|
180
197
|
|
|
181
198
|
export default hetu;
|
|
182
|
-
export { compact, format, parse, validate };
|
|
199
|
+
export { compact, format, generate, parse, validate };
|
package/src/fr/nir.ts
CHANGED
|
@@ -165,7 +165,7 @@ const generate = (): string => {
|
|
|
165
165
|
};
|
|
166
166
|
|
|
167
167
|
/** French Social Security Number. */
|
|
168
|
-
const nir: Validator = {
|
|
168
|
+
const nir: Validator<ParsedPersonId> = {
|
|
169
169
|
name: "French Social Security Number",
|
|
170
170
|
localName: "Numero d'Inscription au Repertoire",
|
|
171
171
|
abbreviation: "NIR",
|
|
@@ -187,6 +187,7 @@ const nir: Validator = {
|
|
|
187
187
|
examples: ["295117823456784"] as const,
|
|
188
188
|
compact,
|
|
189
189
|
format,
|
|
190
|
+
parse,
|
|
190
191
|
validate,
|
|
191
192
|
generate,
|
|
192
193
|
};
|
package/src/gb/nino.ts
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
|
+
const NINO_VALID_FIRST = "ABCEGHJKLMNOPRSTWXYZ";
|
|
2
|
+
const NINO_VALID_SECOND = "ABCEGHJKLMNPRSTWXYZ";
|
|
3
|
+
const NINO_SUFFIXES = "ABCD";
|
|
4
|
+
|
|
1
5
|
/** Generate a random valid UK NINO. */
|
|
2
6
|
const generate = (): string => {
|
|
3
|
-
const validFirst = "ABCEGHJKLMNOPRSTWXYZ";
|
|
4
|
-
const validSecond = "ABCEGHJKLMNPRSTWXYZ";
|
|
5
|
-
const suffixes = "ABCD";
|
|
6
7
|
let first: string;
|
|
7
8
|
let second: string;
|
|
8
9
|
let prefix: string;
|
|
9
10
|
do {
|
|
10
|
-
first =
|
|
11
|
-
|
|
12
|
-
second =
|
|
13
|
-
validSecond[randomInt(0, validSecond.length - 1)]!;
|
|
11
|
+
first = randomChar(NINO_VALID_FIRST);
|
|
12
|
+
second = randomChar(NINO_VALID_SECOND);
|
|
14
13
|
prefix = first + second;
|
|
15
14
|
} while (INVALID_PREFIX.has(prefix));
|
|
16
15
|
const digits = randomDigits(6);
|
|
17
|
-
const suffix =
|
|
18
|
-
suffixes[randomInt(0, suffixes.length - 1)]!;
|
|
16
|
+
const suffix = randomChar(NINO_SUFFIXES);
|
|
19
17
|
return `${prefix}${digits}${suffix}`;
|
|
20
18
|
};
|
|
21
19
|
|
|
@@ -31,7 +29,7 @@ const generate = (): string => {
|
|
|
31
29
|
*/
|
|
32
30
|
|
|
33
31
|
import { clean } from "#util/clean";
|
|
34
|
-
import {
|
|
32
|
+
import { randomChar, randomDigits } from "#util/generate";
|
|
35
33
|
import { err } from "#util/result";
|
|
36
34
|
|
|
37
35
|
import type { ValidateResult, Validator } from "../types";
|
|
@@ -85,7 +83,10 @@ const validate = (value: string): ValidateResult => {
|
|
|
85
83
|
);
|
|
86
84
|
}
|
|
87
85
|
|
|
86
|
+
// SAFETY: regex above guarantees v.length === 9.
|
|
87
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
88
88
|
const first = v[0]!;
|
|
89
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
89
90
|
const second = v[1]!;
|
|
90
91
|
const prefix = v.slice(0, 2);
|
|
91
92
|
|
package/src/gb/sedol.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { clean } from "#util/clean";
|
|
14
|
-
import {
|
|
14
|
+
import { randomChar } from "#util/generate";
|
|
15
15
|
import { err } from "#util/result";
|
|
16
16
|
import { isdigits } from "#util/strings";
|
|
17
17
|
|
|
@@ -36,14 +36,14 @@ const calcCheckDigit = (number: string): string => {
|
|
|
36
36
|
);
|
|
37
37
|
}
|
|
38
38
|
let sum = 0;
|
|
39
|
-
for (
|
|
40
|
-
const ch = number[i]
|
|
39
|
+
for (const [i, weight] of WEIGHTS.entries()) {
|
|
40
|
+
const ch = number[i];
|
|
41
|
+
if (ch === undefined) continue;
|
|
41
42
|
const val = ALPHABET.indexOf(ch);
|
|
42
43
|
if (val < 0) {
|
|
43
44
|
throw new Error(`Invalid SEDOL character: ${ch}`);
|
|
44
45
|
}
|
|
45
|
-
|
|
46
|
-
sum += WEIGHTS[i]! * val;
|
|
46
|
+
sum += weight * val;
|
|
47
47
|
}
|
|
48
48
|
return String((10 - (sum % 10)) % 10);
|
|
49
49
|
};
|
|
@@ -74,6 +74,8 @@ const validate = (value: string): ValidateResult => {
|
|
|
74
74
|
// Old-style SEDOLs are fully numeric; new-style
|
|
75
75
|
// SEDOLs start with a letter. A number that starts
|
|
76
76
|
// with a digit but contains letters is invalid.
|
|
77
|
+
// SAFETY: v.length === 7 here.
|
|
78
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
77
79
|
if (isdigits(v[0]!) && !isdigits(v)) {
|
|
78
80
|
return err(
|
|
79
81
|
"INVALID_FORMAT",
|
|
@@ -94,15 +96,15 @@ const validate = (value: string): ValidateResult => {
|
|
|
94
96
|
|
|
95
97
|
const format = (value: string): string => compact(value);
|
|
96
98
|
|
|
99
|
+
const SEDOL_CONSONANTS = "BCDFGHJKLMNPQRSTVWXYZ";
|
|
100
|
+
const SEDOL_CHARS = "0123456789BCDFGHJKLMNPQRSTVWXYZ";
|
|
101
|
+
|
|
97
102
|
/** Generate a random valid SEDOL. */
|
|
98
103
|
const generate = (): string => {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
let payload = first;
|
|
104
|
-
for (let i = 1; i < 6; i++)
|
|
105
|
-
payload += chars[randomInt(0, chars.length - 1)]!;
|
|
104
|
+
let payload = randomChar(SEDOL_CONSONANTS);
|
|
105
|
+
for (let i = 1; i < 6; i++) {
|
|
106
|
+
payload += randomChar(SEDOL_CHARS);
|
|
107
|
+
}
|
|
106
108
|
return payload + calcCheckDigit(payload);
|
|
107
109
|
};
|
|
108
110
|
|
package/src/gh/tin.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { clean } from "#util/clean";
|
|
18
|
-
import { randomDigits,
|
|
18
|
+
import { randomDigits, randomPick } from "#util/generate";
|
|
19
19
|
import { err } from "#util/result";
|
|
20
20
|
|
|
21
21
|
import type { ValidateResult, Validator } from "../types";
|
|
@@ -65,11 +65,12 @@ const validate = (value: string): ValidateResult => {
|
|
|
65
65
|
|
|
66
66
|
const format = (value: string): string => compact(value);
|
|
67
67
|
|
|
68
|
+
const TIN_PREFIXES = ["P", "C", "G", "Q", "V"] as const;
|
|
69
|
+
|
|
68
70
|
/** Generate a random valid Ghana TIN. */
|
|
69
71
|
const generate = (): string => {
|
|
70
|
-
const prefixes = ["P", "C", "G", "Q", "V"] as const;
|
|
71
72
|
for (;;) {
|
|
72
|
-
const p =
|
|
73
|
+
const p = randomPick(TIN_PREFIXES);
|
|
73
74
|
const d = randomDigits(9);
|
|
74
75
|
const partial = p + d;
|
|
75
76
|
const c = partial + calcCheckDigit(partial);
|
package/src/gt/nit.ts
CHANGED
|
@@ -88,9 +88,12 @@ const format = (value: string): string => {
|
|
|
88
88
|
|
|
89
89
|
/** Generate a random valid NIT (7 body digits). */
|
|
90
90
|
const generate = (): string => {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
for (;;) {
|
|
92
|
+
const body = randomDigits(7);
|
|
93
|
+
if (body.startsWith("0")) continue;
|
|
94
|
+
const check = calcCheckChar(body);
|
|
95
|
+
return `${body}${check}`;
|
|
96
|
+
}
|
|
94
97
|
};
|
|
95
98
|
|
|
96
99
|
/** Guatemala tax identification number. */
|
package/src/hk/hkid.ts
CHANGED
package/src/in/gstin.ts
CHANGED
|
@@ -70,7 +70,9 @@ const luhn36Checksum = (value: string): number => {
|
|
|
70
70
|
let sum = 0;
|
|
71
71
|
let double = false;
|
|
72
72
|
for (let i = value.length - 1; i >= 0; i--) {
|
|
73
|
-
|
|
73
|
+
const ch = value[i];
|
|
74
|
+
if (ch === undefined) continue;
|
|
75
|
+
let v = charValue(ch);
|
|
74
76
|
if (double) {
|
|
75
77
|
v *= 2;
|
|
76
78
|
sum += Math.floor(v / BASE) + (v % BASE);
|
package/src/in/pan.ts
CHANGED
|
@@ -4,8 +4,7 @@ const generate = (): string => {
|
|
|
4
4
|
String.fromCodePoint(65 + randomInt(0, 25));
|
|
5
5
|
const first3 =
|
|
6
6
|
randomLetter() + randomLetter() + randomLetter();
|
|
7
|
-
const holderType =
|
|
8
|
-
HOLDER_TYPES[randomInt(0, HOLDER_TYPES.length - 1)]!;
|
|
7
|
+
const holderType = randomChar(HOLDER_TYPES);
|
|
9
8
|
const fifth = randomLetter();
|
|
10
9
|
const digits = randomDigits(4);
|
|
11
10
|
const last = randomLetter();
|
|
@@ -27,7 +26,11 @@ const generate = (): string => {
|
|
|
27
26
|
*/
|
|
28
27
|
|
|
29
28
|
import { clean } from "#util/clean";
|
|
30
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
randomChar,
|
|
31
|
+
randomDigits,
|
|
32
|
+
randomInt,
|
|
33
|
+
} from "#util/generate";
|
|
31
34
|
import { err } from "#util/result";
|
|
32
35
|
|
|
33
36
|
import type { ValidateResult, Validator } from "../types";
|
|
@@ -53,6 +56,8 @@ const validate = (value: string): ValidateResult => {
|
|
|
53
56
|
"PAN must be 5 letters + 4 digits + 1 letter",
|
|
54
57
|
);
|
|
55
58
|
}
|
|
59
|
+
// SAFETY: regex above guarantees v.length === 10.
|
|
60
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
56
61
|
if (!HOLDER_TYPES.includes(v[3]!)) {
|
|
57
62
|
return err(
|
|
58
63
|
"INVALID_COMPONENT",
|
package/src/index.ts
CHANGED
package/src/isin.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import { luhnChecksum } from "#checksums/luhn";
|
|
14
14
|
import { clean } from "#util/clean";
|
|
15
|
-
import { randomInt } from "#util/generate";
|
|
15
|
+
import { randomInt, randomPick } from "#util/generate";
|
|
16
16
|
import { err } from "#util/result";
|
|
17
17
|
import { charValue, isalnum } from "#util/strings";
|
|
18
18
|
|
|
@@ -73,12 +73,18 @@ const format = (value: string): string => {
|
|
|
73
73
|
return `${v.slice(0, 2)} ${v.slice(2, 6)} ${v.slice(6, 10)} ${v.slice(10)}`;
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
+
const ISIN_COUNTRIES = [
|
|
77
|
+
"US",
|
|
78
|
+
"GB",
|
|
79
|
+
"DE",
|
|
80
|
+
"FR",
|
|
81
|
+
"JP",
|
|
82
|
+
] as const;
|
|
83
|
+
|
|
76
84
|
/** Generate a random valid ISIN. */
|
|
77
85
|
const generate = (): string => {
|
|
78
|
-
const countries = ["US", "GB", "DE", "FR", "JP"];
|
|
79
86
|
for (;;) {
|
|
80
|
-
const cc =
|
|
81
|
-
countries[randomInt(0, countries.length - 1)]!;
|
|
87
|
+
const cc = randomPick(ISIN_COUNTRIES);
|
|
82
88
|
let nsin = "";
|
|
83
89
|
for (let i = 0; i < 9; i++)
|
|
84
90
|
nsin += String(randomInt(0, 9));
|
package/src/it/codicefiscale.ts
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
import { clean } from "#util/clean";
|
|
24
|
+
import { randomInt } from "#util/generate";
|
|
24
25
|
import { err } from "#util/result";
|
|
25
26
|
import { isdigits } from "#util/strings";
|
|
26
27
|
|
|
@@ -260,8 +261,43 @@ const parse = (value: string): ParsedPersonId | null => {
|
|
|
260
261
|
};
|
|
261
262
|
};
|
|
262
263
|
|
|
264
|
+
const LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
265
|
+
const MONTH_CODES = Object.keys(MONTH_LETTERS);
|
|
266
|
+
|
|
267
|
+
const randomLetter = (): string =>
|
|
268
|
+
LETTERS.charAt(randomInt(0, LETTERS.length - 1));
|
|
269
|
+
|
|
270
|
+
/** Generate a random valid 16-character Codice Fiscale. */
|
|
271
|
+
const generate = (): string => {
|
|
272
|
+
let body = "";
|
|
273
|
+
|
|
274
|
+
for (let i = 0; i < 6; i++) {
|
|
275
|
+
body += randomLetter();
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
body += String(randomInt(0, 99)).padStart(2, "0");
|
|
279
|
+
body +=
|
|
280
|
+
MONTH_CODES[randomInt(0, MONTH_CODES.length - 1)] ??
|
|
281
|
+
"A";
|
|
282
|
+
|
|
283
|
+
const day =
|
|
284
|
+
randomInt(1, 28) + (randomInt(0, 1) === 0 ? 0 : 40);
|
|
285
|
+
body += String(day).padStart(2, "0");
|
|
286
|
+
body += randomLetter();
|
|
287
|
+
body += String(randomInt(0, 999)).padStart(3, "0");
|
|
288
|
+
|
|
289
|
+
let sum = 0;
|
|
290
|
+
for (let i = 0; i < body.length; i++) {
|
|
291
|
+
const ch = body[i];
|
|
292
|
+
if (ch === undefined) continue;
|
|
293
|
+
sum += i % 2 === 0 ? (ODD[ch] ?? 0) : (EVEN[ch] ?? 0);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return `${body}${CHECK_LETTERS.charAt(sum % 26)}`;
|
|
297
|
+
};
|
|
298
|
+
|
|
263
299
|
/** Italian Tax Code. */
|
|
264
|
-
const codiceFiscale: Validator = {
|
|
300
|
+
const codiceFiscale: Validator<ParsedPersonId> = {
|
|
265
301
|
name: "Italian Tax Code",
|
|
266
302
|
localName: "Codice Fiscale",
|
|
267
303
|
abbreviation: "CF",
|
|
@@ -283,8 +319,10 @@ const codiceFiscale: Validator = {
|
|
|
283
319
|
examples: ["RCCMNL83S18D969H"] as const,
|
|
284
320
|
compact,
|
|
285
321
|
format,
|
|
322
|
+
parse,
|
|
286
323
|
validate,
|
|
324
|
+
generate,
|
|
287
325
|
};
|
|
288
326
|
|
|
289
327
|
export default codiceFiscale;
|
|
290
|
-
export { compact, format, parse, validate };
|
|
328
|
+
export { compact, format, generate, parse, validate };
|
package/src/kr/rrn.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import { clean } from "#util/clean";
|
|
13
13
|
import { isValidDate } from "#util/date";
|
|
14
|
+
import { randomDigits, randomInt } from "#util/generate";
|
|
14
15
|
import { err } from "#util/result";
|
|
15
16
|
import { isdigits } from "#util/strings";
|
|
16
17
|
|
|
@@ -140,8 +141,23 @@ const parse = (value: string): ParsedPersonId | null => {
|
|
|
140
141
|
};
|
|
141
142
|
};
|
|
142
143
|
|
|
144
|
+
/** Generate a random valid Korean RRN. */
|
|
145
|
+
const generate = (): string => {
|
|
146
|
+
const year = randomInt(1900, 2024);
|
|
147
|
+
const month = String(randomInt(1, 12)).padStart(2, "0");
|
|
148
|
+
const day = String(randomInt(1, 28)).padStart(2, "0");
|
|
149
|
+
const yy = String(year % 100).padStart(2, "0");
|
|
150
|
+
const genderDigit =
|
|
151
|
+
year >= 2000
|
|
152
|
+
? String(randomInt(3, 4))
|
|
153
|
+
: String(randomInt(1, 2));
|
|
154
|
+
const place = String(randomInt(0, 96)).padStart(2, "0");
|
|
155
|
+
const body = `${yy}${month}${day}${genderDigit}${place}${randomDigits(3)}`;
|
|
156
|
+
return `${body}${String(checkDigit(body))}`;
|
|
157
|
+
};
|
|
158
|
+
|
|
143
159
|
/** Korean Resident Registration Number. */
|
|
144
|
-
const rrn: Validator = {
|
|
160
|
+
const rrn: Validator<ParsedPersonId> = {
|
|
145
161
|
name: "Korean Resident Registration Number",
|
|
146
162
|
localName: "주민등록번호",
|
|
147
163
|
abbreviation: "RRN",
|
|
@@ -163,8 +179,10 @@ const rrn: Validator = {
|
|
|
163
179
|
examples: ["9710139019902", "9501011000109"] as const,
|
|
164
180
|
compact,
|
|
165
181
|
format,
|
|
182
|
+
parse,
|
|
166
183
|
validate,
|
|
184
|
+
generate,
|
|
167
185
|
};
|
|
168
186
|
|
|
169
187
|
export default rrn;
|
|
170
|
-
export { compact, format, parse, validate };
|
|
188
|
+
export { compact, format, generate, parse, validate };
|
package/src/kw/civil.ts
CHANGED
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
|
|
15
15
|
import { clean } from "#util/clean";
|
|
16
16
|
import { isValidDate } from "#util/date";
|
|
17
|
+
import { randomDigits, randomInt } from "#util/generate";
|
|
17
18
|
import { err } from "#util/result";
|
|
18
19
|
import { isdigits } from "#util/strings";
|
|
19
20
|
|
|
20
21
|
import type {
|
|
21
|
-
|
|
22
|
+
ParsedBirthDate,
|
|
22
23
|
ValidateResult,
|
|
23
24
|
Validator,
|
|
24
25
|
} from "../types";
|
|
@@ -35,9 +36,8 @@ const compact = (value: string): string =>
|
|
|
35
36
|
|
|
36
37
|
const calcCheckDigit = (digits: string): number => {
|
|
37
38
|
let sum = 0;
|
|
38
|
-
for (
|
|
39
|
-
|
|
40
|
-
sum += Number(digits[i]) * WEIGHTS[i]!;
|
|
39
|
+
for (const [i, weight] of WEIGHTS.entries()) {
|
|
40
|
+
sum += Number(digits[i]) * weight;
|
|
41
41
|
}
|
|
42
42
|
return (11 - (sum % 11)) % 11;
|
|
43
43
|
};
|
|
@@ -101,9 +101,7 @@ const format = (value: string): string => {
|
|
|
101
101
|
* Gender is not encoded in the number.
|
|
102
102
|
* Returns null if the value is not valid.
|
|
103
103
|
*/
|
|
104
|
-
const parse = (
|
|
105
|
-
value: string,
|
|
106
|
-
): Omit<ParsedPersonId, "gender"> | null => {
|
|
104
|
+
const parse = (value: string): ParsedBirthDate | null => {
|
|
107
105
|
const result = validate(value);
|
|
108
106
|
if (!result.valid) return null;
|
|
109
107
|
|
|
@@ -120,8 +118,24 @@ const parse = (
|
|
|
120
118
|
};
|
|
121
119
|
};
|
|
122
120
|
|
|
121
|
+
/** Generate a random valid Kuwait civil number. */
|
|
122
|
+
const generate = (): string => {
|
|
123
|
+
for (;;) {
|
|
124
|
+
const year = randomInt(1950, 2024);
|
|
125
|
+
const month = String(randomInt(1, 12)).padStart(2, "0");
|
|
126
|
+
const day = String(randomInt(1, 28)).padStart(2, "0");
|
|
127
|
+
const body =
|
|
128
|
+
`${year >= 2000 ? "3" : "2"}` +
|
|
129
|
+
`${String(year % 100).padStart(2, "0")}` +
|
|
130
|
+
`${month}${day}${randomDigits(4)}`;
|
|
131
|
+
const check = calcCheckDigit(body);
|
|
132
|
+
if (check > 9) continue;
|
|
133
|
+
return `${body}${String(check)}`;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
123
137
|
/** Kuwait Civil Number (الرقم المدني). */
|
|
124
|
-
const civil: Validator = {
|
|
138
|
+
const civil: Validator<ParsedBirthDate> = {
|
|
125
139
|
name: "Civil Number",
|
|
126
140
|
localName: "الرقم المدني",
|
|
127
141
|
abbreviation: "Civil ID",
|
|
@@ -137,8 +151,10 @@ const civil: Validator = {
|
|
|
137
151
|
"https://kuwaitsexpat.com/kuwait-civil-id-format/",
|
|
138
152
|
compact,
|
|
139
153
|
format,
|
|
154
|
+
parse,
|
|
140
155
|
validate,
|
|
156
|
+
generate,
|
|
141
157
|
};
|
|
142
158
|
|
|
143
159
|
export default civil;
|
|
144
|
-
export { compact, format, parse, validate };
|
|
160
|
+
export { compact, format, generate, parse, validate };
|
package/src/kz/iin.ts
CHANGED
|
@@ -155,7 +155,7 @@ const generate = (): string => {
|
|
|
155
155
|
*
|
|
156
156
|
* Examples sourced from identique/idnumbers test suite.
|
|
157
157
|
*/
|
|
158
|
-
const iin: Validator = {
|
|
158
|
+
const iin: Validator<ParsedPersonId> = {
|
|
159
159
|
name: "Kazakhstan Individual ID",
|
|
160
160
|
localName: "Жеке сәйкестендіру нөмірі",
|
|
161
161
|
abbreviation: "IIN",
|
|
@@ -171,6 +171,7 @@ const iin: Validator = {
|
|
|
171
171
|
examples: ["880515300120", "950101400012"] as const,
|
|
172
172
|
compact,
|
|
173
173
|
format,
|
|
174
|
+
parse,
|
|
174
175
|
validate,
|
|
175
176
|
sourceUrl:
|
|
176
177
|
"https://www.oecd.org/tax/automatic-exchange/" +
|
package/src/lk/nic.ts
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import { clean } from "#util/clean";
|
|
16
16
|
import { isValidDate } from "#util/date";
|
|
17
|
+
import { randomDigits, randomInt } from "#util/generate";
|
|
17
18
|
import { err } from "#util/result";
|
|
18
19
|
import { isdigits } from "#util/strings";
|
|
19
20
|
|
|
@@ -184,8 +185,27 @@ const parse = (value: string): ParsedPersonId | null => {
|
|
|
184
185
|
};
|
|
185
186
|
};
|
|
186
187
|
|
|
188
|
+
/** Generate a random valid Sri Lankan NIC. */
|
|
189
|
+
const generate = (): string => {
|
|
190
|
+
const year = randomInt(1950, 2024);
|
|
191
|
+
const start = new Date(year, 0, 1);
|
|
192
|
+
const end = new Date(year, 11, 31);
|
|
193
|
+
const maxDay =
|
|
194
|
+
Math.round(
|
|
195
|
+
(end.getTime() - start.getTime()) / 86_400_000,
|
|
196
|
+
) + 1;
|
|
197
|
+
const dayOfYear = randomInt(1, maxDay);
|
|
198
|
+
const genderOffset = Math.random() < 0.5 ? 0 : 500;
|
|
199
|
+
const ddd = String(dayOfYear + genderOffset).padStart(
|
|
200
|
+
3,
|
|
201
|
+
"0",
|
|
202
|
+
);
|
|
203
|
+
const body = `${year}${ddd}0${randomDigits(3)}`;
|
|
204
|
+
return `${body}${String(checkDigit(body))}`;
|
|
205
|
+
};
|
|
206
|
+
|
|
187
207
|
/** Sri Lankan National Identity Card. */
|
|
188
|
-
const nic: Validator = {
|
|
208
|
+
const nic: Validator<ParsedPersonId> = {
|
|
189
209
|
name: "National Identity Card",
|
|
190
210
|
localName: "ජාතික හැඳුනුම්පත",
|
|
191
211
|
abbreviation: "NIC",
|
|
@@ -203,8 +223,10 @@ const nic: Validator = {
|
|
|
203
223
|
examples: ["197819202757", "862348753V"] as const,
|
|
204
224
|
compact,
|
|
205
225
|
format,
|
|
226
|
+
parse,
|
|
206
227
|
validate,
|
|
228
|
+
generate,
|
|
207
229
|
};
|
|
208
230
|
|
|
209
231
|
export default nic;
|
|
210
|
-
export { compact, format, parse, validate };
|
|
232
|
+
export { compact, format, generate, parse, validate };
|
package/src/luhn.ts
CHANGED
|
@@ -60,7 +60,10 @@ const luhn: Validator = {
|
|
|
60
60
|
name: "Luhn",
|
|
61
61
|
localName: "Luhn",
|
|
62
62
|
abbreviation: "Luhn",
|
|
63
|
+
aliases: ["Luhn", "Luhn algorithm", "mod 10"] as const,
|
|
64
|
+
candidatePattern: "\\d{2,}",
|
|
63
65
|
entityType: "any",
|
|
66
|
+
sourceUrl: "https://en.wikipedia.org/wiki/Luhn_algorithm",
|
|
64
67
|
examples: ["4111111111111111", "18"] as const,
|
|
65
68
|
compact,
|
|
66
69
|
format,
|