@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/bz/tin.ts
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
28
|
import { clean } from "#util/clean";
|
|
29
|
+
import { randomDigits, randomInt } from "#util/generate";
|
|
29
30
|
import { err } from "#util/result";
|
|
30
31
|
|
|
31
32
|
import type { ValidateResult, Validator } from "../types";
|
|
@@ -79,6 +80,15 @@ const format = (value: string): string => {
|
|
|
79
80
|
return `${v.slice(0, 6)}-${v.slice(6)}`;
|
|
80
81
|
};
|
|
81
82
|
|
|
83
|
+
/** Generate a random valid Belize TIN. */
|
|
84
|
+
const generate = (): string => {
|
|
85
|
+
const base = randomDigits(6);
|
|
86
|
+
const suffixes = ["", ...SUFFIX_CODES] as const;
|
|
87
|
+
const suffix =
|
|
88
|
+
suffixes[randomInt(0, suffixes.length - 1)] ?? "";
|
|
89
|
+
return `${base}${suffix}`;
|
|
90
|
+
};
|
|
91
|
+
|
|
82
92
|
/**
|
|
83
93
|
* Belize Tax Identification Number.
|
|
84
94
|
*
|
|
@@ -97,6 +107,7 @@ const tin: Validator = {
|
|
|
97
107
|
compact,
|
|
98
108
|
format,
|
|
99
109
|
validate,
|
|
110
|
+
generate,
|
|
100
111
|
description:
|
|
101
112
|
"Belize tax number issued by the Belize Tax Service Department",
|
|
102
113
|
sourceUrl:
|
|
@@ -104,4 +115,4 @@ const tin: Validator = {
|
|
|
104
115
|
};
|
|
105
116
|
|
|
106
117
|
export default tin;
|
|
107
|
-
export { compact, format, validate };
|
|
118
|
+
export { compact, format, generate, validate };
|
package/src/cl/rut.ts
CHANGED
|
@@ -35,10 +35,12 @@ const compact = (value: string): string => {
|
|
|
35
35
|
* 11 -> "0", 10 -> "K", else the digit as string.
|
|
36
36
|
*/
|
|
37
37
|
const calcCheckDigit = (body: string): string => {
|
|
38
|
-
const weights = [2, 3, 4, 5, 6, 7];
|
|
38
|
+
const weights = [2, 3, 4, 5, 6, 7] as const;
|
|
39
39
|
let sum = 0;
|
|
40
40
|
for (let i = body.length - 1, w = 0; i >= 0; i--, w++) {
|
|
41
|
-
|
|
41
|
+
// SAFETY: w % weights.length is a valid index.
|
|
42
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
43
|
+
sum += Number(body[i]) * weights[w % weights.length]!;
|
|
42
44
|
}
|
|
43
45
|
const remainder = 11 - (sum % 11);
|
|
44
46
|
if (remainder === 11) return "0";
|
package/src/cn/ric.ts
CHANGED
|
@@ -67,6 +67,8 @@ const validate = (value: string): ValidateResult => {
|
|
|
67
67
|
"RIC must contain only digits (plus check char)",
|
|
68
68
|
);
|
|
69
69
|
}
|
|
70
|
+
// SAFETY: 18-character branch guarantees v[17] exists.
|
|
71
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
70
72
|
const lastChar = v[17]!;
|
|
71
73
|
if (!isdigits(lastChar) && lastChar !== "X") {
|
|
72
74
|
return err(
|
|
@@ -153,7 +155,7 @@ const generate = (): string => {
|
|
|
153
155
|
};
|
|
154
156
|
|
|
155
157
|
/** Chinese Resident Identity Card number. */
|
|
156
|
-
const ric: Validator = {
|
|
158
|
+
const ric: Validator<ParsedPersonId> = {
|
|
157
159
|
name: "Chinese Resident Identity Card",
|
|
158
160
|
localName: "居民身份证号码",
|
|
159
161
|
abbreviation: "RIC",
|
|
@@ -172,6 +174,7 @@ const ric: Validator = {
|
|
|
172
174
|
] as const,
|
|
173
175
|
compact,
|
|
174
176
|
format,
|
|
177
|
+
parse,
|
|
175
178
|
validate,
|
|
176
179
|
generate,
|
|
177
180
|
};
|
package/src/cn/uscc.ts
CHANGED
|
@@ -10,7 +10,11 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { clean } from "#util/clean";
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
randomChar,
|
|
15
|
+
randomDigits,
|
|
16
|
+
randomInt,
|
|
17
|
+
} from "#util/generate";
|
|
14
18
|
import { err } from "#util/result";
|
|
15
19
|
import { isdigits } from "#util/strings";
|
|
16
20
|
|
|
@@ -28,10 +32,14 @@ const compact = (value: string): string =>
|
|
|
28
32
|
|
|
29
33
|
const calcCheckChar = (value: string): string => {
|
|
30
34
|
let total = 0;
|
|
31
|
-
for (
|
|
32
|
-
const
|
|
33
|
-
|
|
35
|
+
for (const [i, weight] of WEIGHTS.entries()) {
|
|
36
|
+
const ch = value[i];
|
|
37
|
+
if (ch === undefined) continue;
|
|
38
|
+
total += ALPHABET.indexOf(ch) * weight;
|
|
34
39
|
}
|
|
40
|
+
// SAFETY: (31 - total % 31) % 31 is in 0..30 and
|
|
41
|
+
// ALPHABET has 31 characters.
|
|
42
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
35
43
|
return ALPHABET[(31 - (total % 31)) % 31]!;
|
|
36
44
|
};
|
|
37
45
|
|
|
@@ -45,8 +53,8 @@ const validate = (value: string): ValidateResult => {
|
|
|
45
53
|
);
|
|
46
54
|
}
|
|
47
55
|
|
|
48
|
-
for (
|
|
49
|
-
if (!ALPHABET.includes(
|
|
56
|
+
for (const ch of v) {
|
|
57
|
+
if (!ALPHABET.includes(ch)) {
|
|
50
58
|
return err(
|
|
51
59
|
"INVALID_FORMAT",
|
|
52
60
|
"USCC contains invalid character",
|
|
@@ -75,12 +83,16 @@ const format = (value: string): string => compact(value);
|
|
|
75
83
|
|
|
76
84
|
/** Generate a random valid USCC. */
|
|
77
85
|
const generate = (): string => {
|
|
86
|
+
// SAFETY: indices 1..9 are within ALPHABET (31 chars).
|
|
87
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
78
88
|
const reg = ALPHABET[randomInt(1, 9)]!;
|
|
89
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
79
90
|
const etype = ALPHABET[randomInt(1, 9)]!;
|
|
80
91
|
const region = randomDigits(6);
|
|
81
92
|
let org = "";
|
|
82
|
-
for (let i = 0; i < 9; i++)
|
|
83
|
-
org +=
|
|
93
|
+
for (let i = 0; i < 9; i++) {
|
|
94
|
+
org += randomChar(ALPHABET);
|
|
95
|
+
}
|
|
84
96
|
const payload = reg + etype + region + org;
|
|
85
97
|
return payload + calcCheckChar(payload);
|
|
86
98
|
};
|
package/src/co/nit.ts
CHANGED
|
@@ -30,9 +30,13 @@ const compact = (value: string): string =>
|
|
|
30
30
|
const calcCheckDigit = (body: string): number => {
|
|
31
31
|
let sum = 0;
|
|
32
32
|
const len = body.length;
|
|
33
|
-
for (
|
|
34
|
-
|
|
33
|
+
for (const [i, weight] of WEIGHTS.entries()) {
|
|
34
|
+
if (i >= len) break;
|
|
35
|
+
sum += Number(body[len - 1 - i]) * weight;
|
|
35
36
|
}
|
|
37
|
+
// SAFETY: sum % 11 is in 0..10 and CHECK_DIGITS has
|
|
38
|
+
// 11 entries.
|
|
39
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
36
40
|
return CHECK_DIGITS[sum % 11]!;
|
|
37
41
|
};
|
|
38
42
|
|
package/src/cr/cpf.ts
CHANGED
|
@@ -38,9 +38,10 @@ const compact = (value: string): string => {
|
|
|
38
38
|
|
|
39
39
|
const parts = number.split("-");
|
|
40
40
|
if (parts.length === 3) {
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const
|
|
41
|
+
const [raw0, raw1, raw2] = parts;
|
|
42
|
+
const p0 = (raw0 ?? "").padStart(2, "0");
|
|
43
|
+
const p1 = (raw1 ?? "").padStart(4, "0");
|
|
44
|
+
const p2 = (raw2 ?? "").padStart(4, "0");
|
|
44
45
|
number = p0 + p1 + p2;
|
|
45
46
|
} else {
|
|
46
47
|
number = number.replaceAll("-", "");
|
package/src/cu/ni.ts
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import { clean } from "#util/clean";
|
|
19
19
|
import { isValidDate } from "#util/date";
|
|
20
|
+
import { randomDigits, randomInt } from "#util/generate";
|
|
20
21
|
import { err } from "#util/result";
|
|
21
22
|
|
|
22
23
|
import type {
|
|
@@ -58,6 +59,8 @@ const validate = (value: string): ValidateResult => {
|
|
|
58
59
|
const yy = Number(v.slice(0, 2));
|
|
59
60
|
const mm = Number(v.slice(2, 4));
|
|
60
61
|
const dd = Number(v.slice(4, 6));
|
|
62
|
+
// SAFETY: regex check above guarantees v.length === 11.
|
|
63
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
61
64
|
const year = centuryOffset(v[6]!) + yy;
|
|
62
65
|
|
|
63
66
|
if (!isValidDate(year, mm, dd)) {
|
|
@@ -84,6 +87,8 @@ const parse = (value: string): ParsedPersonId | null => {
|
|
|
84
87
|
const yy = Number(v.slice(0, 2));
|
|
85
88
|
const mm = Number(v.slice(2, 4));
|
|
86
89
|
const dd = Number(v.slice(4, 6));
|
|
90
|
+
// SAFETY: regex check above guarantees v.length === 11.
|
|
91
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
87
92
|
const year = centuryOffset(v[6]!) + yy;
|
|
88
93
|
|
|
89
94
|
const genderDigit = Number(v[9]);
|
|
@@ -96,12 +101,25 @@ const parse = (value: string): ParsedPersonId | null => {
|
|
|
96
101
|
};
|
|
97
102
|
};
|
|
98
103
|
|
|
104
|
+
/** Generate a random valid Cuban NI. */
|
|
105
|
+
const generate = (): string => {
|
|
106
|
+
const year = randomInt(1950, 2024);
|
|
107
|
+
const month = String(randomInt(1, 12)).padStart(2, "0");
|
|
108
|
+
const day = String(randomInt(1, 28)).padStart(2, "0");
|
|
109
|
+
const yy = String(year % 100).padStart(2, "0");
|
|
110
|
+
const century =
|
|
111
|
+
year >= 2000
|
|
112
|
+
? String(randomInt(6, 8))
|
|
113
|
+
: String(randomInt(0, 5));
|
|
114
|
+
return `${yy}${month}${day}${century}${randomDigits(4)}`;
|
|
115
|
+
};
|
|
116
|
+
|
|
99
117
|
/**
|
|
100
118
|
* Cuban identity card number (NI).
|
|
101
119
|
*
|
|
102
120
|
* Examples sourced from python-stdnum test suite.
|
|
103
121
|
*/
|
|
104
|
-
const ni: Validator = {
|
|
122
|
+
const ni: Validator<ParsedPersonId> = {
|
|
105
123
|
name: "Cuban Identity Card Number",
|
|
106
124
|
localName: "Número de Identidad",
|
|
107
125
|
abbreviation: "NI",
|
|
@@ -117,9 +135,11 @@ const ni: Validator = {
|
|
|
117
135
|
examples: ["91021027775", "72062506561"] as const,
|
|
118
136
|
compact,
|
|
119
137
|
format,
|
|
138
|
+
parse,
|
|
120
139
|
validate,
|
|
140
|
+
generate,
|
|
121
141
|
sourceUrl: "https://www.ecured.cu/Carnet_de_Identidad",
|
|
122
142
|
};
|
|
123
143
|
|
|
124
144
|
export default ni;
|
|
125
|
-
export { compact, format, parse, validate };
|
|
145
|
+
export { compact, format, generate, parse, validate };
|
package/src/cz/rc.ts
CHANGED
|
@@ -6,9 +6,19 @@
|
|
|
6
6
|
* and gender. 10-digit numbers (post-1954) must
|
|
7
7
|
* be divisible by 11.
|
|
8
8
|
*
|
|
9
|
-
* Women have 50 added to the month.
|
|
10
|
-
* an
|
|
11
|
-
* range is exhausted
|
|
9
|
+
* Women have 50 added to the month. For modern
|
|
10
|
+
* 10-digit numbers, an additional +20 offset may
|
|
11
|
+
* be used when the daily serial range is exhausted
|
|
12
|
+
* (+70 for women).
|
|
13
|
+
*
|
|
14
|
+
* Canonical source:
|
|
15
|
+
* - Czech Ministry of the Interior guidance on rodne
|
|
16
|
+
* cislo, with the modern overflow-month rules
|
|
17
|
+
*
|
|
18
|
+
* We use this to keep the 9-digit historical form
|
|
19
|
+
* valid while rejecting modern +20/+70 month offsets
|
|
20
|
+
* on 9-digit numbers. Those overflow offsets are a
|
|
21
|
+
* modern rule for 10-digit values.
|
|
12
22
|
*
|
|
13
23
|
* @see https://www.mvcr.cz/mvcren/docDetail.aspx?docid=21975362&doctype=ART
|
|
14
24
|
* @see Law 133/2000 Sb.
|
|
@@ -29,6 +39,24 @@ import type {
|
|
|
29
39
|
const compact = (value: string): string =>
|
|
30
40
|
clean(value, " /");
|
|
31
41
|
|
|
42
|
+
const decodeMonth = (
|
|
43
|
+
rawMonth: number,
|
|
44
|
+
year: number,
|
|
45
|
+
length: number,
|
|
46
|
+
): number | null => {
|
|
47
|
+
const candidates =
|
|
48
|
+
length === 10 && year >= 2004
|
|
49
|
+
? [0, 50, 20, 70]
|
|
50
|
+
: [0, 50];
|
|
51
|
+
for (const offset of candidates) {
|
|
52
|
+
const month = rawMonth - offset;
|
|
53
|
+
if (month >= 1 && month <= 12) {
|
|
54
|
+
return month;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
};
|
|
59
|
+
|
|
32
60
|
const validate = (value: string): ValidateResult => {
|
|
33
61
|
const v = compact(value);
|
|
34
62
|
if (v.length !== 9 && v.length !== 10) {
|
|
@@ -48,22 +76,6 @@ const validate = (value: string): ValidateResult => {
|
|
|
48
76
|
const mm = Number(v.slice(2, 4));
|
|
49
77
|
const dd = Number(v.slice(4, 6));
|
|
50
78
|
|
|
51
|
-
// Strip gender (+50) and overflow (+20) offsets
|
|
52
|
-
const month = (mm % 50) % 20 || mm % 50;
|
|
53
|
-
if (month < 1 || month > 12) {
|
|
54
|
-
return err(
|
|
55
|
-
"INVALID_COMPONENT",
|
|
56
|
-
"Birth number contains an invalid month",
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (dd < 1 || dd > 31) {
|
|
61
|
-
return err(
|
|
62
|
-
"INVALID_COMPONENT",
|
|
63
|
-
"Birth number contains an invalid day",
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
79
|
// Resolve full year
|
|
68
80
|
let year = yy + 1900;
|
|
69
81
|
if (v.length === 9) {
|
|
@@ -80,6 +92,21 @@ const validate = (value: string): ValidateResult => {
|
|
|
80
92
|
if (year < 1954) year += 100;
|
|
81
93
|
}
|
|
82
94
|
|
|
95
|
+
const month = decodeMonth(mm, year, v.length);
|
|
96
|
+
if (month === null) {
|
|
97
|
+
return err(
|
|
98
|
+
"INVALID_COMPONENT",
|
|
99
|
+
"Birth number contains an invalid month",
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (dd < 1 || dd > 31) {
|
|
104
|
+
return err(
|
|
105
|
+
"INVALID_COMPONENT",
|
|
106
|
+
"Birth number contains an invalid day",
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
83
110
|
// Validate the actual date
|
|
84
111
|
if (!isValidDate(year, month, dd)) {
|
|
85
112
|
return err(
|
|
@@ -122,13 +149,16 @@ const parse = (value: string): ParsedPersonId | null => {
|
|
|
122
149
|
const mm = Number(v.slice(2, 4));
|
|
123
150
|
const dd = Number(v.slice(4, 6));
|
|
124
151
|
|
|
125
|
-
const gender = mm
|
|
126
|
-
const month = (mm % 50) % 20 || mm % 50;
|
|
127
|
-
|
|
152
|
+
const gender = mm >= 50 ? "female" : "male";
|
|
128
153
|
let year = yy + 1900;
|
|
129
154
|
if (v.length === 10 && year < 1954) year += 100;
|
|
130
155
|
if (v.length === 9 && year >= 1980) year -= 100;
|
|
131
156
|
|
|
157
|
+
const month = decodeMonth(mm, year, v.length);
|
|
158
|
+
if (month === null) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
|
|
132
162
|
return {
|
|
133
163
|
birthDate: new Date(year, month - 1, dd),
|
|
134
164
|
gender,
|
|
@@ -166,7 +196,7 @@ const generate = (): string => {
|
|
|
166
196
|
};
|
|
167
197
|
|
|
168
198
|
/** Czech/Slovak Birth Number. */
|
|
169
|
-
const rc: Validator = {
|
|
199
|
+
const rc: Validator<ParsedPersonId> = {
|
|
170
200
|
name: "Czech Birth Number",
|
|
171
201
|
localName: "Rodné číslo",
|
|
172
202
|
abbreviation: "RČ",
|
|
@@ -182,6 +212,7 @@ const rc: Validator = {
|
|
|
182
212
|
examples: ["7103192745"] as const,
|
|
183
213
|
compact,
|
|
184
214
|
format,
|
|
215
|
+
parse,
|
|
185
216
|
validate,
|
|
186
217
|
generate,
|
|
187
218
|
};
|
package/src/de/handelsreg.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
const GENERATE_TYPES = [
|
|
2
|
+
"HRA",
|
|
3
|
+
"HRB",
|
|
4
|
+
"GNR",
|
|
5
|
+
"PR",
|
|
6
|
+
"VR",
|
|
7
|
+
] as const;
|
|
8
|
+
|
|
1
9
|
/** Generate a random valid Handelsregisternummer. */
|
|
2
10
|
const generate = (): string => {
|
|
3
|
-
const
|
|
4
|
-
const type = types[randomInt(0, types.length - 1)]!;
|
|
11
|
+
const type = randomPick(GENERATE_TYPES);
|
|
5
12
|
const number = randomDigits(5);
|
|
6
13
|
return `${type} ${number}`;
|
|
7
14
|
};
|
|
@@ -25,7 +32,7 @@ const generate = (): string => {
|
|
|
25
32
|
*/
|
|
26
33
|
|
|
27
34
|
import { clean } from "#util/clean";
|
|
28
|
-
import { randomDigits,
|
|
35
|
+
import { randomDigits, randomPick } from "#util/generate";
|
|
29
36
|
import { err } from "#util/result";
|
|
30
37
|
|
|
31
38
|
import type { ValidateResult, Validator } from "../types";
|
|
@@ -62,7 +69,11 @@ const validate = (value: string): ValidateResult => {
|
|
|
62
69
|
);
|
|
63
70
|
}
|
|
64
71
|
|
|
72
|
+
// SAFETY: both capture groups are required, so a
|
|
73
|
+
// successful match always populates [1] and [2].
|
|
74
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
65
75
|
const type = match[1]!;
|
|
76
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
66
77
|
const number = match[2]!;
|
|
67
78
|
|
|
68
79
|
if (!REGISTER_TYPES.has(type)) {
|
package/src/de/idnr.ts
CHANGED
|
@@ -103,6 +103,9 @@ const generate = (): string => {
|
|
|
103
103
|
while (pool.length < 10) pool.push(randomInt(0, 9));
|
|
104
104
|
for (let i = pool.length - 1; i > 0; i--) {
|
|
105
105
|
const j = randomInt(0, i);
|
|
106
|
+
// SAFETY: i and j are valid indices of `pool`
|
|
107
|
+
// (i > 0, j ∈ [0, i]).
|
|
108
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
106
109
|
[pool[i], pool[j]] = [pool[j]!, pool[i]!];
|
|
107
110
|
}
|
|
108
111
|
if (pool[0] === 0) continue;
|
package/src/de/stnr.ts
CHANGED
|
@@ -166,9 +166,13 @@ const format = (value: string): string => {
|
|
|
166
166
|
// category: literal digits, F, B, U, P
|
|
167
167
|
const segments: string[] = [];
|
|
168
168
|
let segStart = 0;
|
|
169
|
+
// SAFETY: fmt is a non-empty literal from COMPILED.
|
|
170
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
169
171
|
let prevCat = charCat(fmt[0]!);
|
|
170
172
|
|
|
171
173
|
for (let i = 1; i < fmt.length; i++) {
|
|
174
|
+
// SAFETY: i < fmt.length.
|
|
175
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
172
176
|
const cat = charCat(fmt[i]!);
|
|
173
177
|
if (cat !== prevCat) {
|
|
174
178
|
segments.push(v.slice(segStart, i));
|
package/src/de/svnr.ts
CHANGED
|
@@ -39,6 +39,8 @@ const computeCheck = (v: string): number => {
|
|
|
39
39
|
digits.push(Number(v[i]));
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
// SAFETY: caller guarantees v.length === 12.
|
|
43
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
42
44
|
const lv = letterValue(v[8]!);
|
|
43
45
|
digits.push(Math.floor(lv / 10));
|
|
44
46
|
digits.push(lv % 10);
|
|
@@ -47,8 +49,11 @@ const computeCheck = (v: string): number => {
|
|
|
47
49
|
digits.push(Number(v[10]));
|
|
48
50
|
|
|
49
51
|
let sum = 0;
|
|
50
|
-
for (
|
|
51
|
-
|
|
52
|
+
for (const [i, weight] of WEIGHTS.entries()) {
|
|
53
|
+
// SAFETY: WEIGHTS.length === 12 and we just pushed
|
|
54
|
+
// 12 entries onto `digits`.
|
|
55
|
+
// eslint-disable-next-line no-non-null-assertion
|
|
56
|
+
const product = digits[i]! * weight;
|
|
52
57
|
if (product >= 10) {
|
|
53
58
|
sum += Math.floor(product / 10) + (product % 10);
|
|
54
59
|
} else {
|
package/src/dk/cpr.ts
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import { clean } from "#util/clean";
|
|
12
12
|
import { isValidDate } from "#util/date";
|
|
13
|
+
import { randomDigits, randomInt } from "#util/generate";
|
|
13
14
|
import { err } from "#util/result";
|
|
14
15
|
import { isdigits } from "#util/strings";
|
|
15
16
|
|
|
@@ -102,8 +103,18 @@ const parse = (value: string): ParsedPersonId | null => {
|
|
|
102
103
|
};
|
|
103
104
|
};
|
|
104
105
|
|
|
106
|
+
/** Generate a random valid Danish CPR. */
|
|
107
|
+
const generate = (): string => {
|
|
108
|
+
const year = randomInt(1900, 2024);
|
|
109
|
+
const month = String(randomInt(1, 12)).padStart(2, "0");
|
|
110
|
+
const day = String(randomInt(1, 28)).padStart(2, "0");
|
|
111
|
+
const yy = String(year % 100).padStart(2, "0");
|
|
112
|
+
const serialPrefix = String(randomInt(0, 3));
|
|
113
|
+
return `${day}${month}${yy}${serialPrefix}${randomDigits(3)}`;
|
|
114
|
+
};
|
|
115
|
+
|
|
105
116
|
/** Danish Personal Identification Number. */
|
|
106
|
-
const cpr: Validator = {
|
|
117
|
+
const cpr: Validator<ParsedPersonId> = {
|
|
107
118
|
name: "Danish Personal ID",
|
|
108
119
|
localName: "Det Centrale Personregister",
|
|
109
120
|
abbreviation: "CPR",
|
|
@@ -112,11 +123,14 @@ const cpr: Validator = {
|
|
|
112
123
|
country: "DK",
|
|
113
124
|
entityType: "person",
|
|
114
125
|
sourceUrl: "https://cpr.dk/",
|
|
126
|
+
lengths: [10] as const,
|
|
115
127
|
examples: ["2110625629"] as const,
|
|
116
128
|
compact,
|
|
117
129
|
format,
|
|
130
|
+
parse,
|
|
118
131
|
validate,
|
|
132
|
+
generate,
|
|
119
133
|
};
|
|
120
134
|
|
|
121
135
|
export default cpr;
|
|
122
|
-
export { compact, format, parse, validate };
|
|
136
|
+
export { compact, format, generate, parse, validate };
|
package/src/do/rnc.ts
CHANGED
|
@@ -38,8 +38,8 @@ const compact = (value: string): string =>
|
|
|
38
38
|
*/
|
|
39
39
|
const calcRncCheckDigit = (value: string): string => {
|
|
40
40
|
let sum = 0;
|
|
41
|
-
for (
|
|
42
|
-
sum += Number(value[i]) *
|
|
41
|
+
for (const [i, weight] of RNC_WEIGHTS.entries()) {
|
|
42
|
+
sum += Number(value[i]) * weight;
|
|
43
43
|
}
|
|
44
44
|
const remainder = sum % 11;
|
|
45
45
|
return String(((10 - remainder) % 9) + 1);
|
package/src/ec/ruc.ts
CHANGED
|
@@ -46,8 +46,8 @@ const mod11Checksum = (
|
|
|
46
46
|
weights: readonly number[],
|
|
47
47
|
): number => {
|
|
48
48
|
let sum = 0;
|
|
49
|
-
for (
|
|
50
|
-
sum += Number(digits[i]) *
|
|
49
|
+
for (const [i, weight] of weights.entries()) {
|
|
50
|
+
sum += Number(digits[i]) * weight;
|
|
51
51
|
}
|
|
52
52
|
return sum % 11;
|
|
53
53
|
};
|
package/src/ee/ik.ts
CHANGED
|
@@ -5,7 +5,16 @@
|
|
|
5
5
|
* gender/century digit, YYMMDD, 3-digit serial, and
|
|
6
6
|
* a check digit computed with two-pass weighted sums.
|
|
7
7
|
*
|
|
8
|
+
* Canonical sources:
|
|
9
|
+
* - Estonian legislation for the personal code format
|
|
10
|
+
* - OECD Estonia TIN sheet summarising the same
|
|
11
|
+
* first-digit ranges for cross-border tax use
|
|
12
|
+
*
|
|
13
|
+
* These sources are why we restrict the first digit
|
|
14
|
+
* to 1-6 rather than accepting speculative 7/8 forms.
|
|
15
|
+
*
|
|
8
16
|
* @see https://www.riigiteataja.ee/en/eli/512012015003/consolide
|
|
17
|
+
* @see https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Estonia-TIN.pdf
|
|
9
18
|
*/
|
|
10
19
|
|
|
11
20
|
import { weightedSum } from "#checksums/weighted-sum";
|
|
@@ -31,8 +40,6 @@ const centuryMap: Record<number, number> = {
|
|
|
31
40
|
4: 1900,
|
|
32
41
|
5: 2000,
|
|
33
42
|
6: 2000,
|
|
34
|
-
7: 2100,
|
|
35
|
-
8: 2100,
|
|
36
43
|
};
|
|
37
44
|
|
|
38
45
|
const compact = (value: string): string =>
|
|
@@ -65,7 +72,9 @@ const validate = (value: string): ValidateResult => {
|
|
|
65
72
|
}
|
|
66
73
|
|
|
67
74
|
const g = Number(v[0]);
|
|
68
|
-
|
|
75
|
+
// Official Estonian structure uses 1-6:
|
|
76
|
+
// 1-2 = 1800s, 3-4 = 1900s, 5-6 = 2000s.
|
|
77
|
+
if (g < 1 || g > 6) {
|
|
69
78
|
return err(
|
|
70
79
|
"INVALID_COMPONENT",
|
|
71
80
|
"Isikukood gender/century digit is invalid",
|
|
@@ -135,7 +144,7 @@ const generate = (): string => {
|
|
|
135
144
|
};
|
|
136
145
|
|
|
137
146
|
/** Estonian Personal Identification Code. */
|
|
138
|
-
const ik: Validator = {
|
|
147
|
+
const ik: Validator<ParsedPersonId> = {
|
|
139
148
|
name: "Estonian Personal ID",
|
|
140
149
|
localName: "Isikukood",
|
|
141
150
|
abbreviation: "IK",
|
|
@@ -148,6 +157,7 @@ const ik: Validator = {
|
|
|
148
157
|
examples: ["36805280109"] as const,
|
|
149
158
|
compact,
|
|
150
159
|
format,
|
|
160
|
+
parse,
|
|
151
161
|
validate,
|
|
152
162
|
generate,
|
|
153
163
|
};
|
package/src/ee/registrikood.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { clean } from "#util/clean";
|
|
11
|
-
import { randomDigits,
|
|
11
|
+
import { randomDigits, randomPick } from "#util/generate";
|
|
12
12
|
import { err } from "#util/result";
|
|
13
13
|
import { isdigits } from "#util/strings";
|
|
14
14
|
|
|
@@ -52,10 +52,11 @@ const validate = (value: string): ValidateResult => {
|
|
|
52
52
|
|
|
53
53
|
const format = (value: string): string => compact(value);
|
|
54
54
|
|
|
55
|
+
const REGISTRIKOOD_FIRSTS = [1, 7, 8, 9] as const;
|
|
56
|
+
|
|
55
57
|
/** Generate a random valid Estonian Registrikood. */
|
|
56
58
|
const generate = (): string => {
|
|
57
|
-
const
|
|
58
|
-
const first = String(firsts[randomInt(0, 3)]!);
|
|
59
|
+
const first = String(randomPick(REGISTRIKOOD_FIRSTS));
|
|
59
60
|
const payload = first + randomDigits(6);
|
|
60
61
|
return payload + String(twoPassCheck(payload));
|
|
61
62
|
};
|
package/src/es/cif.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { clean } from "#util/clean";
|
|
13
|
-
import {
|
|
13
|
+
import { randomChar, randomDigits } from "#util/generate";
|
|
14
14
|
import { err } from "#util/result";
|
|
15
15
|
import { isdigits } from "#util/strings";
|
|
16
16
|
|
|
@@ -72,8 +72,7 @@ const format = (value: string): string => compact(value);
|
|
|
72
72
|
|
|
73
73
|
/** Generate a random valid Spanish CIF. */
|
|
74
74
|
const generate = (): string => {
|
|
75
|
-
const letter =
|
|
76
|
-
CIF_PREFIXES[randomInt(0, CIF_PREFIXES.length - 1)]!;
|
|
75
|
+
const letter = randomChar(CIF_PREFIXES);
|
|
77
76
|
const payload = randomDigits(7);
|
|
78
77
|
const check = cifChecksum(payload);
|
|
79
78
|
if ("KPQS".includes(letter))
|
package/src/es/nie.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { clean } from "#util/clean";
|
|
12
|
-
import { randomDigits,
|
|
12
|
+
import { randomDigits, randomPick } from "#util/generate";
|
|
13
13
|
import { err } from "#util/result";
|
|
14
14
|
import { isdigits } from "#util/strings";
|
|
15
15
|
|
|
@@ -66,13 +66,18 @@ const validate = (value: string): ValidateResult => {
|
|
|
66
66
|
|
|
67
67
|
const format = (value: string): string => compact(value);
|
|
68
68
|
|
|
69
|
+
const NIE_PREFIXES = ["X", "Y", "Z"] as const;
|
|
70
|
+
const NIE_PREFIX_VALUES: Record<
|
|
71
|
+
(typeof NIE_PREFIXES)[number],
|
|
72
|
+
number
|
|
73
|
+
> = { X: 0, Y: 1, Z: 2 };
|
|
74
|
+
|
|
69
75
|
/** Generate a random valid Spanish NIE. */
|
|
70
76
|
const generate = (): string => {
|
|
71
|
-
const
|
|
72
|
-
const vals: Record<string, number> = { X: 0, Y: 1, Z: 2 };
|
|
73
|
-
const prefix = prefixes[randomInt(0, 2)]!;
|
|
77
|
+
const prefix = randomPick(NIE_PREFIXES);
|
|
74
78
|
const digits = randomDigits(7);
|
|
75
|
-
const num =
|
|
79
|
+
const num =
|
|
80
|
+
NIE_PREFIX_VALUES[prefix] * 10000000 + Number(digits);
|
|
76
81
|
return prefix + digits + CHECK_LETTERS.charAt(num % 23);
|
|
77
82
|
};
|
|
78
83
|
|