@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.
Files changed (474) hide show
  1. package/LICENSE +1 -5
  2. package/README.md +28 -4
  3. package/dist/_checksums/mod112.js +5 -5
  4. package/dist/_checksums/mod112.js.map +1 -1
  5. package/dist/_util/generate.d.ts +13 -1
  6. package/dist/_util/generate.js +23 -1
  7. package/dist/_util/generate.js.map +1 -1
  8. package/dist/ad/mod.d.ts +3 -2
  9. package/dist/ad/nrt.js +3 -2
  10. package/dist/ad/nrt.js.map +1 -1
  11. package/dist/ae/eid.d.ts +0 -1
  12. package/dist/ae/mod.d.ts +3 -2
  13. package/dist/ai/mod.d.ts +3 -2
  14. package/dist/al/mod.d.ts +3 -2
  15. package/dist/am/mod.d.ts +3 -2
  16. package/dist/ar/cbu.d.ts +0 -1
  17. package/dist/ar/cbu.js +1 -1
  18. package/dist/ar/cbu.js.map +1 -1
  19. package/dist/ar/cuit.d.ts +0 -1
  20. package/dist/ar/cuit.js +12 -12
  21. package/dist/ar/cuit.js.map +1 -1
  22. package/dist/ar/mod.d.ts +3 -2
  23. package/dist/at/mod.d.ts +3 -2
  24. package/dist/at/tin.d.ts +0 -1
  25. package/dist/at/uid.d.ts +0 -1
  26. package/dist/at/vnr.d.ts +3 -2
  27. package/dist/at/vnr.js +20 -3
  28. package/dist/at/vnr.js.map +1 -1
  29. package/dist/au/abn.d.ts +0 -1
  30. package/dist/au/acn.d.ts +0 -1
  31. package/dist/au/mod.d.ts +3 -2
  32. package/dist/au/tfn.d.ts +0 -1
  33. package/dist/az/mod.d.ts +3 -2
  34. package/dist/az/voen.d.ts +0 -1
  35. package/dist/az/voen.js.map +1 -1
  36. package/dist/ba/jmbg.d.ts +1 -2
  37. package/dist/ba/jmbg.js +1 -0
  38. package/dist/ba/jmbg.js.map +1 -1
  39. package/dist/ba/mod.d.ts +3 -2
  40. package/dist/bd/mod.d.ts +3 -2
  41. package/dist/bd/nid.js +10 -11
  42. package/dist/bd/nid.js.map +1 -1
  43. package/dist/be/bis.d.ts +0 -1
  44. package/dist/be/mod.d.ts +3 -2
  45. package/dist/be/nn.d.ts +0 -1
  46. package/dist/be/vat.d.ts +0 -1
  47. package/dist/bg/egn.d.ts +1 -2
  48. package/dist/bg/egn.js +10 -3
  49. package/dist/bg/egn.js.map +1 -1
  50. package/dist/bg/mod.d.ts +3 -2
  51. package/dist/bg/pnf.d.ts +0 -1
  52. package/dist/bg/vat.d.ts +0 -1
  53. package/dist/bh/cpr.d.ts +3 -2
  54. package/dist/bh/cpr.js +8 -2
  55. package/dist/bh/cpr.js.map +1 -1
  56. package/dist/bh/mod.d.ts +3 -2
  57. package/dist/bic.js +13 -15
  58. package/dist/bic.js.map +1 -1
  59. package/dist/br/cnpj.d.ts +0 -1
  60. package/dist/br/cpf.d.ts +0 -1
  61. package/dist/br/mod.d.ts +3 -2
  62. package/dist/by/mod.d.ts +3 -2
  63. package/dist/by/unp.d.ts +0 -1
  64. package/dist/by/unp.js +6 -3
  65. package/dist/by/unp.js.map +1 -1
  66. package/dist/bz/mod.d.ts +3 -2
  67. package/dist/bz/tin.d.ts +3 -2
  68. package/dist/bz/tin.js +9 -1
  69. package/dist/bz/tin.js.map +1 -1
  70. package/dist/ca/bn.d.ts +0 -1
  71. package/dist/ca/mod.d.ts +3 -2
  72. package/dist/ca/sin.d.ts +0 -1
  73. package/dist/ch/mod.d.ts +3 -2
  74. package/dist/ch/ssn.d.ts +0 -1
  75. package/dist/ch/uid.d.ts +0 -1
  76. package/dist/ch/vat.d.ts +0 -1
  77. package/dist/cl/mod.d.ts +3 -2
  78. package/dist/cl/rut.d.ts +0 -1
  79. package/dist/cl/rut.js +1 -1
  80. package/dist/cl/rut.js.map +1 -1
  81. package/dist/cn/mod.d.ts +3 -2
  82. package/dist/cn/ric.d.ts +1 -2
  83. package/dist/cn/ric.js +1 -0
  84. package/dist/cn/ric.js.map +1 -1
  85. package/dist/cn/uscc.d.ts +0 -1
  86. package/dist/cn/uscc.js +7 -6
  87. package/dist/cn/uscc.js.map +1 -1
  88. package/dist/co/mod.d.ts +3 -2
  89. package/dist/co/nit.d.ts +0 -1
  90. package/dist/co/nit.js +4 -1
  91. package/dist/co/nit.js.map +1 -1
  92. package/dist/cr/cpf.js +4 -3
  93. package/dist/cr/cpf.js.map +1 -1
  94. package/dist/cr/mod.d.ts +3 -2
  95. package/dist/creditcard.d.ts +0 -1
  96. package/dist/cu/mod.d.ts +3 -2
  97. package/dist/cu/ni.d.ts +4 -3
  98. package/dist/cu/ni.js +11 -1
  99. package/dist/cu/ni.js.map +1 -1
  100. package/dist/cy/mod.d.ts +3 -2
  101. package/dist/cy/vat.d.ts +0 -1
  102. package/dist/cz/dic.d.ts +0 -1
  103. package/dist/cz/ico.d.ts +0 -1
  104. package/dist/cz/mod.d.ts +3 -2
  105. package/dist/cz/rc.d.ts +1 -2
  106. package/dist/cz/rc.js +33 -8
  107. package/dist/cz/rc.js.map +1 -1
  108. package/dist/de/handelsreg.js +9 -9
  109. package/dist/de/handelsreg.js.map +1 -1
  110. package/dist/de/idnr.d.ts +0 -1
  111. package/dist/de/idnr.js.map +1 -1
  112. package/dist/de/mod.d.ts +3 -2
  113. package/dist/de/stnr.d.ts +0 -1
  114. package/dist/de/stnr.js.map +1 -1
  115. package/dist/de/svnr.d.ts +0 -1
  116. package/dist/de/svnr.js +2 -2
  117. package/dist/de/svnr.js.map +1 -1
  118. package/dist/de/vat.d.ts +0 -1
  119. package/dist/dk/cpr.d.ts +4 -3
  120. package/dist/dk/cpr.js +12 -2
  121. package/dist/dk/cpr.js.map +1 -1
  122. package/dist/dk/cvr.d.ts +0 -1
  123. package/dist/dk/mod.d.ts +3 -2
  124. package/dist/dk/vat.d.ts +0 -1
  125. package/dist/do/mod.d.ts +3 -2
  126. package/dist/do/rnc.d.ts +0 -1
  127. package/dist/do/rnc.js +1 -1
  128. package/dist/do/rnc.js.map +1 -1
  129. package/dist/ec/mod.d.ts +3 -2
  130. package/dist/ec/ruc.d.ts +0 -1
  131. package/dist/ec/ruc.js +1 -1
  132. package/dist/ec/ruc.js.map +1 -1
  133. package/dist/ee/ik.d.ts +1 -2
  134. package/dist/ee/ik.js +12 -4
  135. package/dist/ee/ik.js.map +1 -1
  136. package/dist/ee/mod.d.ts +3 -2
  137. package/dist/ee/registrikood.d.ts +0 -1
  138. package/dist/ee/registrikood.js +8 -7
  139. package/dist/ee/registrikood.js.map +1 -1
  140. package/dist/ee/vat.d.ts +0 -1
  141. package/dist/eg/mod.d.ts +3 -2
  142. package/dist/es/cif.d.ts +0 -1
  143. package/dist/es/cif.js +2 -2
  144. package/dist/es/cif.js.map +1 -1
  145. package/dist/es/dni.d.ts +0 -1
  146. package/dist/es/mod.d.ts +3 -2
  147. package/dist/es/nie.d.ts +0 -1
  148. package/dist/es/nie.js +13 -13
  149. package/dist/es/nie.js.map +1 -1
  150. package/dist/es/nss.d.ts +0 -1
  151. package/dist/es/vat.d.ts +0 -1
  152. package/dist/eu/mod.d.ts +3 -2
  153. package/dist/eu/vat.d.ts +3 -2
  154. package/dist/eu/vat.js +43 -2
  155. package/dist/eu/vat.js.map +1 -1
  156. package/dist/fi/hetu.d.ts +4 -3
  157. package/dist/fi/hetu.js +17 -2
  158. package/dist/fi/hetu.js.map +1 -1
  159. package/dist/fi/mod.d.ts +3 -2
  160. package/dist/fi/vat.d.ts +0 -1
  161. package/dist/fi/ytunnus.d.ts +0 -1
  162. package/dist/fr/mod.d.ts +3 -2
  163. package/dist/fr/nif.d.ts +0 -1
  164. package/dist/fr/nir.d.ts +1 -2
  165. package/dist/fr/nir.js +1 -0
  166. package/dist/fr/nir.js.map +1 -1
  167. package/dist/fr/siren.d.ts +0 -1
  168. package/dist/fr/siret.d.ts +0 -1
  169. package/dist/fr/tva.d.ts +0 -1
  170. package/dist/gb/mod.d.ts +3 -2
  171. package/dist/gb/nino.js +7 -7
  172. package/dist/gb/nino.js.map +1 -1
  173. package/dist/gb/sedol.d.ts +0 -1
  174. package/dist/gb/sedol.js +8 -7
  175. package/dist/gb/sedol.js.map +1 -1
  176. package/dist/gb/utr.d.ts +0 -1
  177. package/dist/gb/vat.d.ts +0 -1
  178. package/dist/ge/mod.d.ts +3 -2
  179. package/dist/gh/mod.d.ts +3 -2
  180. package/dist/gh/tin.d.ts +0 -1
  181. package/dist/gh/tin.js +9 -9
  182. package/dist/gh/tin.js.map +1 -1
  183. package/dist/gr/amka.d.ts +0 -1
  184. package/dist/gr/mod.d.ts +3 -2
  185. package/dist/gr/vat.d.ts +0 -1
  186. package/dist/gt/mod.d.ts +3 -2
  187. package/dist/gt/nit.d.ts +0 -1
  188. package/dist/gt/nit.js +5 -2
  189. package/dist/gt/nit.js.map +1 -1
  190. package/dist/hk/hkid.d.ts +0 -1
  191. package/dist/hk/hkid.js +1 -0
  192. package/dist/hk/hkid.js.map +1 -1
  193. package/dist/hk/mod.d.ts +3 -2
  194. package/dist/hr/mod.d.ts +3 -2
  195. package/dist/hr/vat.d.ts +0 -1
  196. package/dist/hu/mod.d.ts +3 -2
  197. package/dist/hu/vat.d.ts +0 -1
  198. package/dist/iban.d.ts +0 -1
  199. package/dist/id/mod.d.ts +3 -2
  200. package/dist/id/npwp.d.ts +0 -1
  201. package/dist/ie/mod.d.ts +3 -2
  202. package/dist/ie/pps.d.ts +0 -1
  203. package/dist/ie/vat.d.ts +0 -1
  204. package/dist/il/idnr.d.ts +0 -1
  205. package/dist/il/mod.d.ts +3 -2
  206. package/dist/in/aadhaar.d.ts +0 -1
  207. package/dist/in/gstin.d.ts +0 -1
  208. package/dist/in/gstin.js +3 -1
  209. package/dist/in/gstin.js.map +1 -1
  210. package/dist/in/mod.d.ts +3 -2
  211. package/dist/in/pan.js +2 -2
  212. package/dist/in/pan.js.map +1 -1
  213. package/dist/index.d.ts +2 -2
  214. package/dist/iq/mod.d.ts +3 -2
  215. package/dist/ir/mod.d.ts +3 -2
  216. package/dist/ir/nid.d.ts +0 -1
  217. package/dist/is/kennitala.d.ts +0 -1
  218. package/dist/is/mod.d.ts +3 -2
  219. package/dist/isin.d.ts +0 -1
  220. package/dist/isin.js +9 -9
  221. package/dist/isin.js.map +1 -1
  222. package/dist/it/codicefiscale.d.ts +4 -3
  223. package/dist/it/codicefiscale.js +26 -2
  224. package/dist/it/codicefiscale.js.map +1 -1
  225. package/dist/it/iva.d.ts +0 -1
  226. package/dist/it/mod.d.ts +3 -2
  227. package/dist/jp/cn.d.ts +0 -1
  228. package/dist/jp/mod.d.ts +3 -2
  229. package/dist/jp/mynumber.d.ts +0 -1
  230. package/dist/kr/mod.d.ts +3 -2
  231. package/dist/kr/rrn.d.ts +4 -3
  232. package/dist/kr/rrn.js +13 -2
  233. package/dist/kr/rrn.js.map +1 -1
  234. package/dist/kw/civil.d.ts +6 -5
  235. package/dist/kw/civil.js +18 -3
  236. package/dist/kw/civil.js.map +1 -1
  237. package/dist/kw/mod.d.ts +3 -2
  238. package/dist/kz/iin.d.ts +1 -2
  239. package/dist/kz/iin.js +1 -0
  240. package/dist/kz/iin.js.map +1 -1
  241. package/dist/kz/mod.d.ts +3 -2
  242. package/dist/lei.d.ts +0 -1
  243. package/dist/li/mod.d.ts +3 -2
  244. package/dist/lk/mod.d.ts +3 -2
  245. package/dist/lk/nic.d.ts +4 -3
  246. package/dist/lk/nic.js +14 -2
  247. package/dist/lk/nic.js.map +1 -1
  248. package/dist/lt/asmens.d.ts +0 -1
  249. package/dist/lt/mod.d.ts +3 -2
  250. package/dist/lt/vat.d.ts +0 -1
  251. package/dist/lu/mod.d.ts +3 -2
  252. package/dist/lu/vat.d.ts +0 -1
  253. package/dist/luhn.d.ts +0 -1
  254. package/dist/luhn.js +7 -0
  255. package/dist/luhn.js.map +1 -1
  256. package/dist/lv/mod.d.ts +3 -2
  257. package/dist/lv/vat.d.ts +0 -1
  258. package/dist/lv/vat.js +39 -12
  259. package/dist/lv/vat.js.map +1 -1
  260. package/dist/ma/ice.d.ts +0 -1
  261. package/dist/ma/mod.d.ts +3 -2
  262. package/dist/mc/mod.d.ts +3 -2
  263. package/dist/mc/tva.d.ts +0 -1
  264. package/dist/md/idno.d.ts +0 -1
  265. package/dist/md/mod.d.ts +3 -2
  266. package/dist/me/mod.d.ts +3 -2
  267. package/dist/me/pib.d.ts +0 -1
  268. package/dist/mk/edb.d.ts +0 -1
  269. package/dist/mk/mod.d.ts +3 -2
  270. package/dist/mt/mod.d.ts +3 -2
  271. package/dist/mt/vat.d.ts +0 -1
  272. package/dist/mu/mod.d.ts +3 -2
  273. package/dist/mx/clabe.d.ts +0 -1
  274. package/dist/mx/curp.d.ts +4 -3
  275. package/dist/mx/curp.js +25 -3
  276. package/dist/mx/curp.js.map +1 -1
  277. package/dist/mx/mod.d.ts +3 -2
  278. package/dist/mx/rfc.d.ts +3 -2
  279. package/dist/mx/rfc.js +21 -2
  280. package/dist/mx/rfc.js.map +1 -1
  281. package/dist/my/mod.d.ts +3 -2
  282. package/dist/my/nric.d.ts +4 -3
  283. package/dist/my/nric.js +16 -2
  284. package/dist/my/nric.js.map +1 -1
  285. package/dist/ng/mod.d.ts +3 -2
  286. package/dist/ni/mod.d.ts +3 -2
  287. package/dist/ni/ruc.d.ts +0 -1
  288. package/dist/nl/bsn.d.ts +0 -1
  289. package/dist/nl/mod.d.ts +3 -2
  290. package/dist/nl/vat.d.ts +0 -1
  291. package/dist/nl/vat.js +9 -43
  292. package/dist/nl/vat.js.map +1 -1
  293. package/dist/no/fodselsnummer.d.ts +1 -2
  294. package/dist/no/fodselsnummer.js +1 -0
  295. package/dist/no/fodselsnummer.js.map +1 -1
  296. package/dist/no/mod.d.ts +3 -2
  297. package/dist/no/mva.d.ts +0 -1
  298. package/dist/no/orgnr.d.ts +0 -1
  299. package/dist/nz/ird.d.ts +0 -1
  300. package/dist/nz/ird.js +2 -2
  301. package/dist/nz/ird.js.map +1 -1
  302. package/dist/nz/mod.d.ts +3 -2
  303. package/dist/pa/mod.d.ts +3 -2
  304. package/dist/pa/ruc.d.ts +0 -1
  305. package/dist/pa/ruc.js +3 -1
  306. package/dist/pa/ruc.js.map +1 -1
  307. package/dist/patterns.d.ts +1 -4
  308. package/dist/patterns.js +80 -23
  309. package/dist/patterns.js.map +1 -1
  310. package/dist/pe/mod.d.ts +3 -2
  311. package/dist/pe/ruc.d.ts +0 -1
  312. package/dist/pe/ruc.js +9 -9
  313. package/dist/pe/ruc.js.map +1 -1
  314. package/dist/ph/mod.d.ts +3 -2
  315. package/dist/pk/cnic.js.map +1 -1
  316. package/dist/pk/mod.d.ts +3 -2
  317. package/dist/pl/mod.d.ts +3 -2
  318. package/dist/pl/nip.d.ts +0 -1
  319. package/dist/pl/pesel.d.ts +1 -2
  320. package/dist/pl/pesel.js +1 -0
  321. package/dist/pl/pesel.js.map +1 -1
  322. package/dist/pl/regon.d.ts +0 -1
  323. package/dist/pt/cc.d.ts +0 -1
  324. package/dist/pt/cc.js +6 -4
  325. package/dist/pt/cc.js.map +1 -1
  326. package/dist/pt/mod.d.ts +3 -2
  327. package/dist/pt/vat.d.ts +0 -1
  328. package/dist/ro/cnp.d.ts +1 -2
  329. package/dist/ro/cnp.js +1 -0
  330. package/dist/ro/cnp.js.map +1 -1
  331. package/dist/ro/mod.d.ts +3 -2
  332. package/dist/ro/vat.d.ts +0 -1
  333. package/dist/rs/mod.d.ts +3 -2
  334. package/dist/rs/pib.d.ts +0 -1
  335. package/dist/ru/inn.d.ts +0 -1
  336. package/dist/ru/inn.js +1 -1
  337. package/dist/ru/inn.js.map +1 -1
  338. package/dist/ru/mod.d.ts +3 -2
  339. package/dist/se/mod.d.ts +3 -2
  340. package/dist/se/orgnr.d.ts +0 -1
  341. package/dist/se/personnummer.d.ts +1 -2
  342. package/dist/se/personnummer.js +1 -0
  343. package/dist/se/personnummer.js.map +1 -1
  344. package/dist/se/vat.d.ts +0 -1
  345. package/dist/sg/mod.d.ts +3 -2
  346. package/dist/sg/uen.d.ts +0 -1
  347. package/dist/sg/uen.js +46 -55
  348. package/dist/sg/uen.js.map +1 -1
  349. package/dist/si/emso.d.ts +1 -2
  350. package/dist/si/emso.js +17 -4
  351. package/dist/si/emso.js.map +1 -1
  352. package/dist/si/mod.d.ts +3 -2
  353. package/dist/si/vat.d.ts +0 -1
  354. package/dist/sk/dic.d.ts +0 -1
  355. package/dist/sk/ico.d.ts +0 -1
  356. package/dist/sk/mod.d.ts +3 -2
  357. package/dist/sk/rc.d.ts +4 -5
  358. package/dist/sk/rc.js +5 -2
  359. package/dist/sk/rc.js.map +1 -1
  360. package/dist/th/mod.d.ts +3 -2
  361. package/dist/th/tin.d.ts +0 -1
  362. package/dist/tr/mod.d.ts +3 -2
  363. package/dist/tr/tckimlik.d.ts +0 -1
  364. package/dist/tr/vkn.d.ts +0 -1
  365. package/dist/tw/mod.d.ts +3 -2
  366. package/dist/tw/ubn.d.ts +0 -1
  367. package/dist/tw/ubn.js +1 -1
  368. package/dist/tw/ubn.js.map +1 -1
  369. package/dist/types.d.ts +35 -22
  370. package/dist/ua/edrpou.d.ts +0 -1
  371. package/dist/ua/edrpou.js +4 -1
  372. package/dist/ua/edrpou.js.map +1 -1
  373. package/dist/ua/mod.d.ts +3 -2
  374. package/dist/us/ein.js +87 -87
  375. package/dist/us/ein.js.map +1 -1
  376. package/dist/us/itin.js +3 -4
  377. package/dist/us/itin.js.map +1 -1
  378. package/dist/us/mod.d.ts +3 -2
  379. package/dist/us/rtn.d.ts +0 -1
  380. package/dist/us/rtn.js +8 -5
  381. package/dist/us/rtn.js.map +1 -1
  382. package/dist/uy/mod.d.ts +3 -2
  383. package/dist/uy/rut.d.ts +0 -1
  384. package/dist/uy/rut.js +1 -1
  385. package/dist/uy/rut.js.map +1 -1
  386. package/dist/ve/mod.d.ts +3 -2
  387. package/dist/ve/rif.d.ts +0 -1
  388. package/dist/ve/rif.js +11 -11
  389. package/dist/ve/rif.js.map +1 -1
  390. package/dist/vn/mod.d.ts +3 -2
  391. package/dist/vn/mst.d.ts +0 -1
  392. package/dist/za/idnr.d.ts +1 -2
  393. package/dist/za/idnr.js +1 -0
  394. package/dist/za/idnr.js.map +1 -1
  395. package/dist/za/mod.d.ts +3 -2
  396. package/package.json +18 -15
  397. package/src/_checksums/mod112.ts +7 -6
  398. package/src/_util/generate.ts +38 -0
  399. package/src/ad/nrt.ts +12 -4
  400. package/src/ar/cbu.ts +2 -2
  401. package/src/ar/cuit.ts +15 -7
  402. package/src/at/vnr.ts +26 -4
  403. package/src/az/voen.ts +2 -0
  404. package/src/ba/jmbg.ts +2 -1
  405. package/src/bd/nid.ts +4 -4
  406. package/src/bg/egn.ts +12 -4
  407. package/src/bh/cpr.ts +10 -1
  408. package/src/bic.ts +19 -17
  409. package/src/by/unp.ts +9 -4
  410. package/src/bz/tin.ts +12 -1
  411. package/src/cl/rut.ts +4 -2
  412. package/src/cn/ric.ts +4 -1
  413. package/src/cn/uscc.ts +20 -8
  414. package/src/co/nit.ts +6 -2
  415. package/src/cr/cpf.ts +4 -3
  416. package/src/cu/ni.ts +22 -2
  417. package/src/cz/rc.ts +54 -23
  418. package/src/de/handelsreg.ts +14 -3
  419. package/src/de/idnr.ts +3 -0
  420. package/src/de/stnr.ts +4 -0
  421. package/src/de/svnr.ts +7 -2
  422. package/src/dk/cpr.ts +16 -2
  423. package/src/do/rnc.ts +2 -2
  424. package/src/ec/ruc.ts +2 -2
  425. package/src/ee/ik.ts +14 -4
  426. package/src/ee/registrikood.ts +4 -3
  427. package/src/es/cif.ts +2 -3
  428. package/src/es/nie.ts +10 -5
  429. package/src/eu/vat.ts +46 -1
  430. package/src/fi/hetu.ts +19 -2
  431. package/src/fr/nir.ts +2 -1
  432. package/src/gb/nino.ts +11 -10
  433. package/src/gb/sedol.ts +14 -12
  434. package/src/gh/tin.ts +4 -3
  435. package/src/gt/nit.ts +6 -3
  436. package/src/hk/hkid.ts +2 -1
  437. package/src/in/gstin.ts +3 -1
  438. package/src/in/pan.ts +8 -3
  439. package/src/index.ts +3 -0
  440. package/src/isin.ts +10 -4
  441. package/src/it/codicefiscale.ts +40 -2
  442. package/src/kr/rrn.ts +20 -2
  443. package/src/kw/civil.ts +25 -9
  444. package/src/kz/iin.ts +2 -1
  445. package/src/lk/nic.ts +24 -2
  446. package/src/luhn.ts +3 -0
  447. package/src/lv/vat.ts +46 -20
  448. package/src/mx/curp.ts +41 -5
  449. package/src/mx/rfc.ts +35 -4
  450. package/src/my/nric.ts +26 -2
  451. package/src/nl/vat.ts +11 -66
  452. package/src/no/fodselsnummer.ts +2 -1
  453. package/src/nz/ird.ts +4 -4
  454. package/src/pa/ruc.ts +32 -8
  455. package/src/patterns.ts +135 -28
  456. package/src/pe/ruc.ts +6 -7
  457. package/src/pk/cnic.ts +2 -0
  458. package/src/pl/pesel.ts +2 -1
  459. package/src/pt/cc.ts +6 -4
  460. package/src/ro/cnp.ts +2 -1
  461. package/src/ru/inn.ts +2 -2
  462. package/src/se/personnummer.ts +2 -1
  463. package/src/sg/uen.ts +37 -20
  464. package/src/si/emso.ts +30 -5
  465. package/src/sk/rc.ts +13 -4
  466. package/src/tw/ubn.ts +2 -2
  467. package/src/types.ts +37 -6
  468. package/src/ua/edrpou.ts +3 -2
  469. package/src/us/ein.ts +88 -88
  470. package/src/us/itin.ts +7 -8
  471. package/src/us/rtn.ts +16 -11
  472. package/src/uy/rut.ts +2 -2
  473. package/src/ve/rif.ts +11 -6
  474. 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
- validFirst[randomInt(0, validFirst.length - 1)]!;
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 { randomDigits, randomInt } from "#util/generate";
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 { randomInt } from "#util/generate";
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 (let i = 0; i < 6; i++) {
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
- // SAFETY: weights length matches loop bound
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
- const consonants = "BCDFGHJKLMNPQRSTVWXYZ";
100
- const chars = "0123456789BCDFGHJKLMNPQRSTVWXYZ";
101
- const first =
102
- consonants[randomInt(0, consonants.length - 1)]!;
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, randomInt } from "#util/generate";
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 = prefixes[randomInt(0, 4)]!;
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
- const body = randomDigits(7);
92
- const check = calcCheckChar(body);
93
- return `${body}${check}`;
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
@@ -32,7 +32,8 @@ const computeCheck = (body: string): string => {
32
32
 
33
33
  let sum = 0;
34
34
  for (let i = 0; i < 8; i++) {
35
- const ch = padded[i]!;
35
+ const ch = padded[i];
36
+ if (ch === undefined) continue;
36
37
  let val: number;
37
38
  if (ch === " ") {
38
39
  val = 36;
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
- let v = charValue(value[i]!);
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 { randomDigits, randomInt } from "#util/generate";
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
@@ -1,7 +1,10 @@
1
1
  export type {
2
2
  CountryCode,
3
3
  ErrorCode,
4
+ ParsedBirthDate,
5
+ ParsedIdentifier,
4
6
  ParsedPersonId,
7
+ ParsableValidator,
5
8
  StdnumError,
6
9
  ValidateResult,
7
10
  Validator,
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));
@@ -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
- ParsedPersonId,
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 (let i = 0; i < 11; i++) {
39
- // SAFETY: loop bound guarantees valid index
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,