@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/dist/types.d.ts CHANGED
@@ -17,24 +17,25 @@ type ValidateResult = {
17
17
  error: StdnumError;
18
18
  };
19
19
  /**
20
- * Structured data extracted from a personal ID number.
21
- * Returned by `parse()` on validators that encode
22
- * birth date and gender.
20
+ * Structured data extracted from an identifier that
21
+ * encodes a birth date.
23
22
  */
24
- type ParsedPersonId = {
23
+ type ParsedBirthDate = {
25
24
  birthDate: Date;
25
+ };
26
+ /**
27
+ * Structured data extracted from a personal ID number
28
+ * that also encodes gender.
29
+ */
30
+ type ParsedPersonId = ParsedBirthDate & {
26
31
  gender: "male" | "female";
27
32
  };
28
- type Validator = {
29
- /** English name. */
30
- name: string;
31
- /** Name in the local language. */
32
- localName: string;
33
- /** Common abbreviation (e.g. "IČO"). */
34
- abbreviation: string;
35
- /** Country this identifier belongs to. */
36
- country?: CountryCode;
37
- /** What kind of entity this identifies. */
33
+ type ParsedIdentifier = ParsedBirthDate | ParsedPersonId;
34
+ type Validator<TParsed extends ParsedIdentifier | undefined = undefined> = {
35
+ /** English name. */name: string; /** Name in the local language. */
36
+ localName: string; /** Common abbreviation (e.g. "IČO"). */
37
+ abbreviation: string; /** Country this identifier belongs to. */
38
+ country?: CountryCode; /** What kind of entity this identifies. */
38
39
  entityType: "person" | "company" | "any";
39
40
  /**
40
41
  * Strip separators and normalize to a
@@ -51,12 +52,9 @@ type Validator = {
51
52
  * compact form on success, or an error
52
53
  * with a code and message on failure.
53
54
  */
54
- validate: (value: string) => ValidateResult;
55
- /** One-liner describing the identifier. */
56
- description?: string;
57
- /** URL to official authority or spec page. */
58
- sourceUrl?: string;
59
- /** Valid lengths of the compact form. */
55
+ validate: (value: string) => ValidateResult; /** One-liner describing the identifier. */
56
+ description?: string; /** URL to official authority or spec page. */
57
+ sourceUrl?: string; /** Valid lengths of the compact form. */
60
58
  lengths?: readonly number[];
61
59
  /**
62
60
  * Known-valid compact values. Useful as test
@@ -89,7 +87,22 @@ type Validator = {
89
87
  * passed to validate() for confirmation.
90
88
  */
91
89
  candidatePattern?: string;
92
- };
90
+ /**
91
+ * Extract structured data (e.g. birth date,
92
+ * gender) from a known-valid identifier.
93
+ * Available on personal IDs that encode such
94
+ * data. Returns null if the input cannot be
95
+ * parsed.
96
+ *
97
+ * On the base `Validator` type this is optional
98
+ * with a widened return; narrow it by typing the
99
+ * validator as `Validator<ParsedPersonId>` etc.
100
+ */
101
+ parse?: (value: string) => ParsedIdentifier | null;
102
+ } & ([TParsed] extends [undefined] ? unknown : {
103
+ parse: (value: string) => TParsed | null;
104
+ });
105
+ type ParsableValidator<TParsed extends ParsedIdentifier = ParsedIdentifier> = Validator<TParsed>;
93
106
  //#endregion
94
- export { CountryCode, ErrorCode, ParsedPersonId, StdnumError, ValidateResult, Validator };
107
+ export { CountryCode, ErrorCode, ParsableValidator, ParsedBirthDate, ParsedIdentifier, ParsedPersonId, StdnumError, ValidateResult, Validator };
95
108
  //# sourceMappingURL=types.d.ts.map
@@ -1,7 +1,6 @@
1
1
  import { ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/ua/edrpou.d.ts
4
-
5
4
  declare const compact: (value: string) => string;
6
5
  declare const validate: (value: string) => ValidateResult;
7
6
  declare const format: (value: string) => string;
package/dist/ua/edrpou.js CHANGED
@@ -52,7 +52,10 @@ const WEIGHTS_B2 = [
52
52
  ];
53
53
  const calcCheck = (value, weights) => {
54
54
  let sum = 0;
55
- for (let i = 0; i < 7; i++) sum += Number(value[i]) * weights[i];
55
+ for (const [i, weight] of weights.entries()) {
56
+ if (i >= 7) break;
57
+ sum += Number(value[i]) * weight;
58
+ }
56
59
  return sum % 11;
57
60
  };
58
61
  const compact = (value) => clean(value, " -");
@@ -1 +1 @@
1
- {"version":3,"file":"edrpou.js","names":[],"sources":["../../src/ua/edrpou.ts"],"sourcesContent":["/**\n * EDRPOU (ЄДРПОУ, Unified State Register of\n * Enterprises and Organizations of Ukraine).\n *\n * 8-digit company identification number with a\n * weighted checksum. Two sets of weights are used\n * depending on whether the first digit is 0-2/6-9 or 3-5.\n *\n * @see https://en.wikipedia.org/wiki/EDRPOU\n * @see https://usr.minjust.gov.ua/\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst WEIGHTS_A = [1, 2, 3, 4, 5, 6, 7] as const;\nconst WEIGHTS_B = [7, 1, 2, 3, 4, 5, 6] as const;\nconst WEIGHTS_A2 = [3, 4, 5, 6, 7, 8, 9] as const;\nconst WEIGHTS_B2 = [9, 3, 4, 5, 6, 7, 8] as const;\n\nconst calcCheck = (\n value: string,\n weights: readonly number[],\n): number => {\n let sum = 0;\n for (let i = 0; i < 7; i++) {\n sum += Number(value[i]) * weights[i]!;\n }\n return sum % 11;\n};\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 8) {\n return err(\n \"INVALID_LENGTH\",\n \"EDRPOU must be exactly 8 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"EDRPOU must contain only digits\",\n );\n }\n\n const firstDigit = Number(v[0]);\n const useA = firstDigit < 3 || firstDigit >= 6;\n const weightsFirst = useA ? WEIGHTS_A : WEIGHTS_B;\n const weightsSecond = useA ? WEIGHTS_A2 : WEIGHTS_B2;\n\n let check = calcCheck(v, weightsFirst);\n if (check >= 10) {\n check = calcCheck(v, weightsSecond) % 10;\n }\n\n if (check !== Number(v[7])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"EDRPOU check digit mismatch\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid Ukrainian EDRPOU. */\nconst generate = (): string => {\n for (;;) {\n const c = randomDigits(8);\n if (validate(c).valid) return c;\n }\n};\n\n/** Ukrainian Company Register Number. */\nconst edrpou: Validator = {\n name: \"Ukrainian Company Register Number\",\n localName: \"ЄДРПОУ\",\n abbreviation: \"ЄДРПОУ\",\n aliases: [\"ЄДРПОУ\", \"EDRPOU\"] as const,\n candidatePattern: \"\\\\d{8}\",\n country: \"UA\",\n entityType: \"company\",\n lengths: [8] as const,\n sourceUrl: \"https://usr.minjust.gov.ua/\",\n examples: [\"14360570\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default edrpou;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;AAmBA,MAAM,YAAY;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AACvC,MAAM,YAAY;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AACvC,MAAM,aAAa;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AACxC,MAAM,aAAa;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAExC,MAAM,aACJ,OACA,YACW;CACX,IAAI,MAAM;AACV,MAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IACrB,QAAO,OAAO,MAAM,GAAG,GAAG,QAAQ;AAEpC,QAAO,MAAM;;AAGf,MAAM,WAAW,UACf,MAAM,OAAO,KAAK;AAEpB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,IACL,kBACA,kCACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,kCACD;CAGH,MAAM,aAAa,OAAO,EAAE,GAAG;CAC/B,MAAM,OAAO,aAAa,KAAK,cAAc;CAC7C,MAAM,eAAe,OAAO,YAAY;CACxC,MAAM,gBAAgB,OAAO,aAAa;CAE1C,IAAI,QAAQ,UAAU,GAAG,aAAa;AACtC,KAAI,SAAS,GACX,SAAQ,UAAU,GAAG,cAAc,GAAG;AAGxC,KAAI,UAAU,OAAO,EAAE,GAAG,CACxB,QAAO,IACL,oBACA,8BACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B,QAAQ,MAAM;;AAGxD,MAAM,iBAAyB;AAC7B,UAAS;EACP,MAAM,IAAI,aAAa,EAAE;AACzB,MAAI,SAAS,EAAE,CAAC,MAAO,QAAO;;;;AAKlC,MAAM,SAAoB;CACxB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,UAAU,SAAS;CAC7B,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,EAAE;CACZ,WAAW;CACX,UAAU,CAAC,WAAW;CACtB;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"edrpou.js","names":[],"sources":["../../src/ua/edrpou.ts"],"sourcesContent":["/**\n * EDRPOU (ЄДРПОУ, Unified State Register of\n * Enterprises and Organizations of Ukraine).\n *\n * 8-digit company identification number with a\n * weighted checksum. Two sets of weights are used\n * depending on whether the first digit is 0-2/6-9 or 3-5.\n *\n * @see https://en.wikipedia.org/wiki/EDRPOU\n * @see https://usr.minjust.gov.ua/\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst WEIGHTS_A = [1, 2, 3, 4, 5, 6, 7] as const;\nconst WEIGHTS_B = [7, 1, 2, 3, 4, 5, 6] as const;\nconst WEIGHTS_A2 = [3, 4, 5, 6, 7, 8, 9] as const;\nconst WEIGHTS_B2 = [9, 3, 4, 5, 6, 7, 8] as const;\n\nconst calcCheck = (\n value: string,\n weights: readonly number[],\n): number => {\n let sum = 0;\n for (const [i, weight] of weights.entries()) {\n if (i >= 7) break;\n sum += Number(value[i]) * weight;\n }\n return sum % 11;\n};\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 8) {\n return err(\n \"INVALID_LENGTH\",\n \"EDRPOU must be exactly 8 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"EDRPOU must contain only digits\",\n );\n }\n\n const firstDigit = Number(v[0]);\n const useA = firstDigit < 3 || firstDigit >= 6;\n const weightsFirst = useA ? WEIGHTS_A : WEIGHTS_B;\n const weightsSecond = useA ? WEIGHTS_A2 : WEIGHTS_B2;\n\n let check = calcCheck(v, weightsFirst);\n if (check >= 10) {\n check = calcCheck(v, weightsSecond) % 10;\n }\n\n if (check !== Number(v[7])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"EDRPOU check digit mismatch\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid Ukrainian EDRPOU. */\nconst generate = (): string => {\n for (;;) {\n const c = randomDigits(8);\n if (validate(c).valid) return c;\n }\n};\n\n/** Ukrainian Company Register Number. */\nconst edrpou: Validator = {\n name: \"Ukrainian Company Register Number\",\n localName: \"ЄДРПОУ\",\n abbreviation: \"ЄДРПОУ\",\n aliases: [\"ЄДРПОУ\", \"EDRPOU\"] as const,\n candidatePattern: \"\\\\d{8}\",\n country: \"UA\",\n entityType: \"company\",\n lengths: [8] as const,\n sourceUrl: \"https://usr.minjust.gov.ua/\",\n examples: [\"14360570\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default edrpou;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;AAmBA,MAAM,YAAY;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AACvC,MAAM,YAAY;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AACvC,MAAM,aAAa;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AACxC,MAAM,aAAa;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAExC,MAAM,aACJ,OACA,YACW;CACX,IAAI,MAAM;AACV,MAAK,MAAM,CAAC,GAAG,WAAW,QAAQ,SAAS,EAAE;AAC3C,MAAI,KAAK,EAAG;AACZ,SAAO,OAAO,MAAM,GAAG,GAAG;;AAE5B,QAAO,MAAM;;AAGf,MAAM,WAAW,UACf,MAAM,OAAO,KAAK;AAEpB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,IACL,kBACA,kCACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,kCACD;CAGH,MAAM,aAAa,OAAO,EAAE,GAAG;CAC/B,MAAM,OAAO,aAAa,KAAK,cAAc;CAC7C,MAAM,eAAe,OAAO,YAAY;CACxC,MAAM,gBAAgB,OAAO,aAAa;CAE1C,IAAI,QAAQ,UAAU,GAAG,aAAa;AACtC,KAAI,SAAS,GACX,SAAQ,UAAU,GAAG,cAAc,GAAG;AAGxC,KAAI,UAAU,OAAO,EAAE,GAAG,CACxB,QAAO,IACL,oBACA,8BACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B,QAAQ,MAAM;;AAGxD,MAAM,iBAAyB;AAC7B,UAAS;EACP,MAAM,IAAI,aAAa,EAAE;AACzB,MAAI,SAAS,EAAE,CAAC,MAAO,QAAO;;;;AAKlC,MAAM,SAAoB;CACxB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,UAAU,SAAS;CAC7B,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,EAAE;CACZ,WAAW;CACX,UAAU,CAAC,WAAW;CACtB;CACA;CACA;CACA;CACD"}
package/dist/ua/mod.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
1
  import edrpou from "./edrpou.js";
3
2
 
4
3
  //#region src/ua/mod.d.ts
5
-
4
+ declare namespace mod_d_exports {
5
+ export { edrpou };
6
+ }
6
7
  //#endregion
7
8
  export { edrpou, mod_d_exports };
8
9
  //# sourceMappingURL=mod.d.ts.map
package/dist/us/ein.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { clean } from "../_util/clean.js";
2
- import { randomDigits, randomInt } from "../_util/generate.js";
2
+ import { randomDigits, randomPick } from "../_util/generate.js";
3
3
  import { err } from "../_util/result.js";
4
4
  import { isdigits } from "../_util/strings.js";
5
5
  //#region src/us/ein.ts
@@ -13,94 +13,94 @@ import { isdigits } from "../_util/strings.js";
13
13
  * @see https://en.wikipedia.org/wiki/Employer_Identification_Number
14
14
  * @see https://www.irs.gov/businesses/small-businesses-self-employed/how-eins-are-assigned-and-valid-ein-prefixes
15
15
  */
16
+ const EIN_PREFIXES = [
17
+ "01",
18
+ "02",
19
+ "03",
20
+ "04",
21
+ "05",
22
+ "06",
23
+ "10",
24
+ "11",
25
+ "12",
26
+ "13",
27
+ "14",
28
+ "15",
29
+ "16",
30
+ "20",
31
+ "21",
32
+ "22",
33
+ "23",
34
+ "24",
35
+ "25",
36
+ "26",
37
+ "27",
38
+ "30",
39
+ "31",
40
+ "32",
41
+ "33",
42
+ "34",
43
+ "35",
44
+ "36",
45
+ "37",
46
+ "38",
47
+ "39",
48
+ "40",
49
+ "41",
50
+ "42",
51
+ "43",
52
+ "44",
53
+ "45",
54
+ "46",
55
+ "47",
56
+ "48",
57
+ "50",
58
+ "51",
59
+ "52",
60
+ "53",
61
+ "54",
62
+ "55",
63
+ "56",
64
+ "57",
65
+ "58",
66
+ "59",
67
+ "60",
68
+ "61",
69
+ "62",
70
+ "63",
71
+ "64",
72
+ "65",
73
+ "66",
74
+ "67",
75
+ "68",
76
+ "71",
77
+ "72",
78
+ "73",
79
+ "74",
80
+ "75",
81
+ "76",
82
+ "77",
83
+ "80",
84
+ "81",
85
+ "82",
86
+ "83",
87
+ "84",
88
+ "85",
89
+ "86",
90
+ "87",
91
+ "88",
92
+ "90",
93
+ "91",
94
+ "92",
95
+ "93",
96
+ "94",
97
+ "95",
98
+ "98",
99
+ "99"
100
+ ];
16
101
  /** Generate a random valid U.S. EIN. */
17
102
  const generate = () => {
18
- const prefixes = [
19
- "01",
20
- "02",
21
- "03",
22
- "04",
23
- "05",
24
- "06",
25
- "10",
26
- "11",
27
- "12",
28
- "13",
29
- "14",
30
- "15",
31
- "16",
32
- "20",
33
- "21",
34
- "22",
35
- "23",
36
- "24",
37
- "25",
38
- "26",
39
- "27",
40
- "30",
41
- "31",
42
- "32",
43
- "33",
44
- "34",
45
- "35",
46
- "36",
47
- "37",
48
- "38",
49
- "39",
50
- "40",
51
- "41",
52
- "42",
53
- "43",
54
- "44",
55
- "45",
56
- "46",
57
- "47",
58
- "48",
59
- "50",
60
- "51",
61
- "52",
62
- "53",
63
- "54",
64
- "55",
65
- "56",
66
- "57",
67
- "58",
68
- "59",
69
- "60",
70
- "61",
71
- "62",
72
- "63",
73
- "64",
74
- "65",
75
- "66",
76
- "67",
77
- "68",
78
- "71",
79
- "72",
80
- "73",
81
- "74",
82
- "75",
83
- "76",
84
- "77",
85
- "80",
86
- "81",
87
- "82",
88
- "83",
89
- "84",
90
- "85",
91
- "86",
92
- "87",
93
- "88",
94
- "90",
95
- "91",
96
- "92",
97
- "93",
98
- "94",
99
- "95",
100
- "98",
101
- "99"
102
- ];
103
- return prefixes[randomInt(0, prefixes.length - 1)] + randomDigits(7);
103
+ return randomPick(EIN_PREFIXES) + randomDigits(7);
104
104
  };
105
105
  /**
106
106
  * Valid EIN campus prefixes. Sourced from IRS
@@ -1 +1 @@
1
- {"version":3,"file":"ein.js","names":[],"sources":["../../src/us/ein.ts"],"sourcesContent":["/** Generate a random valid U.S. EIN. */\nconst generate = (): string => {\n const prefixes = [\n \"01\",\n \"02\",\n \"03\",\n \"04\",\n \"05\",\n \"06\",\n \"10\",\n \"11\",\n \"12\",\n \"13\",\n \"14\",\n \"15\",\n \"16\",\n \"20\",\n \"21\",\n \"22\",\n \"23\",\n \"24\",\n \"25\",\n \"26\",\n \"27\",\n \"30\",\n \"31\",\n \"32\",\n \"33\",\n \"34\",\n \"35\",\n \"36\",\n \"37\",\n \"38\",\n \"39\",\n \"40\",\n \"41\",\n \"42\",\n \"43\",\n \"44\",\n \"45\",\n \"46\",\n \"47\",\n \"48\",\n \"50\",\n \"51\",\n \"52\",\n \"53\",\n \"54\",\n \"55\",\n \"56\",\n \"57\",\n \"58\",\n \"59\",\n \"60\",\n \"61\",\n \"62\",\n \"63\",\n \"64\",\n \"65\",\n \"66\",\n \"67\",\n \"68\",\n \"71\",\n \"72\",\n \"73\",\n \"74\",\n \"75\",\n \"76\",\n \"77\",\n \"80\",\n \"81\",\n \"82\",\n \"83\",\n \"84\",\n \"85\",\n \"86\",\n \"87\",\n \"88\",\n \"90\",\n \"91\",\n \"92\",\n \"93\",\n \"94\",\n \"95\",\n \"98\",\n \"99\",\n ];\n const prefix =\n prefixes[randomInt(0, prefixes.length - 1)]!;\n return prefix + randomDigits(7);\n};\n\n/**\n * EIN (U.S. Employer Identification Number).\n *\n * 9-digit identifier: 2-digit campus prefix +\n * 7-digit group. No checksum. The first 2 digits\n * must be a valid IRS campus code.\n *\n * @see https://en.wikipedia.org/wiki/Employer_Identification_Number\n * @see https://www.irs.gov/businesses/small-businesses-self-employed/how-eins-are-assigned-and-valid-ein-prefixes\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\n/**\n * Valid EIN campus prefixes. Sourced from IRS\n * documentation and python-stdnum's numdb.\n */\nconst VALID_PREFIXES = new Set([\n \"01\",\n \"02\",\n \"03\",\n \"04\",\n \"05\",\n \"06\",\n \"10\",\n \"11\",\n \"12\",\n \"13\",\n \"14\",\n \"15\",\n \"16\",\n \"20\",\n \"21\",\n \"22\",\n \"23\",\n \"24\",\n \"25\",\n \"26\",\n \"27\",\n \"30\",\n \"31\",\n \"32\",\n \"33\",\n \"34\",\n \"35\",\n \"36\",\n \"37\",\n \"38\",\n \"39\",\n \"40\",\n \"41\",\n \"42\",\n \"43\",\n \"44\",\n \"45\",\n \"46\",\n \"47\",\n \"48\",\n \"50\",\n \"51\",\n \"52\",\n \"53\",\n \"54\",\n \"55\",\n \"56\",\n \"57\",\n \"58\",\n \"59\",\n \"60\",\n \"61\",\n \"62\",\n \"63\",\n \"64\",\n \"65\",\n \"66\",\n \"67\",\n \"68\",\n \"71\",\n \"72\",\n \"73\",\n \"74\",\n \"75\",\n \"76\",\n \"77\",\n \"80\",\n \"81\",\n \"82\",\n \"83\",\n \"84\",\n \"85\",\n \"86\",\n \"87\",\n \"88\",\n \"90\",\n \"91\",\n \"92\",\n \"93\",\n \"94\",\n \"95\",\n \"98\",\n \"99\",\n]);\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"EIN must contain only digits\",\n );\n }\n if (v.length !== 9) {\n return err(\"INVALID_LENGTH\", \"EIN must be 9 digits\");\n }\n const prefix = v.slice(0, 2);\n if (!VALID_PREFIXES.has(prefix)) {\n return err(\n \"INVALID_COMPONENT\",\n \"EIN campus prefix is invalid\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n if (v.length === 9) {\n return `${v.slice(0, 2)}-${v.slice(2)}`;\n }\n return v;\n};\n\n/** U.S. Employer Identification Number. */\nconst ein: Validator = {\n name: \"Employer Identification Number\",\n localName: \"Employer Identification Number\",\n abbreviation: \"EIN\",\n aliases: [\n \"EIN\",\n \"Employer Identification Number\",\n \"Federal Tax ID\",\n ] as const,\n candidatePattern: \"\\\\d{2}-?\\\\d{7}\",\n country: \"US\",\n entityType: \"company\",\n sourceUrl:\n \"https://www.irs.gov/businesses/small-businesses-self-employed/how-eins-are-assigned-and-valid-ein-prefixes\",\n examples: [\"042103594\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default ein;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;AACA,MAAM,iBAAyB;CAC7B,MAAM,WAAW;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;AAGD,QADE,SAAS,UAAU,GAAG,SAAS,SAAS,EAAE,IAC5B,aAAa,EAAE;;;;;;AAyBjC,MAAM,iBAAiB,IAAI,IAAI;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAM,WAAW,UACf,MAAM,OAAO,KAAK;AAEpB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,+BACD;AAEH,KAAI,EAAE,WAAW,EACf,QAAO,IAAI,kBAAkB,uBAAuB;CAEtD,MAAM,SAAS,EAAE,MAAM,GAAG,EAAE;AAC5B,KAAI,CAAC,eAAe,IAAI,OAAO,CAC7B,QAAO,IACL,qBACA,+BACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE;AAEvC,QAAO;;;AAIT,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;EACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WACE;CACF,UAAU,CAAC,YAAY;CACvB;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"ein.js","names":[],"sources":["../../src/us/ein.ts"],"sourcesContent":["const EIN_PREFIXES = [\n \"01\",\n \"02\",\n \"03\",\n \"04\",\n \"05\",\n \"06\",\n \"10\",\n \"11\",\n \"12\",\n \"13\",\n \"14\",\n \"15\",\n \"16\",\n \"20\",\n \"21\",\n \"22\",\n \"23\",\n \"24\",\n \"25\",\n \"26\",\n \"27\",\n \"30\",\n \"31\",\n \"32\",\n \"33\",\n \"34\",\n \"35\",\n \"36\",\n \"37\",\n \"38\",\n \"39\",\n \"40\",\n \"41\",\n \"42\",\n \"43\",\n \"44\",\n \"45\",\n \"46\",\n \"47\",\n \"48\",\n \"50\",\n \"51\",\n \"52\",\n \"53\",\n \"54\",\n \"55\",\n \"56\",\n \"57\",\n \"58\",\n \"59\",\n \"60\",\n \"61\",\n \"62\",\n \"63\",\n \"64\",\n \"65\",\n \"66\",\n \"67\",\n \"68\",\n \"71\",\n \"72\",\n \"73\",\n \"74\",\n \"75\",\n \"76\",\n \"77\",\n \"80\",\n \"81\",\n \"82\",\n \"83\",\n \"84\",\n \"85\",\n \"86\",\n \"87\",\n \"88\",\n \"90\",\n \"91\",\n \"92\",\n \"93\",\n \"94\",\n \"95\",\n \"98\",\n \"99\",\n] as const;\n\n/** Generate a random valid U.S. EIN. */\nconst generate = (): string => {\n const prefix = randomPick(EIN_PREFIXES);\n return prefix + randomDigits(7);\n};\n\n/**\n * EIN (U.S. Employer Identification Number).\n *\n * 9-digit identifier: 2-digit campus prefix +\n * 7-digit group. No checksum. The first 2 digits\n * must be a valid IRS campus code.\n *\n * @see https://en.wikipedia.org/wiki/Employer_Identification_Number\n * @see https://www.irs.gov/businesses/small-businesses-self-employed/how-eins-are-assigned-and-valid-ein-prefixes\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomPick } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\n/**\n * Valid EIN campus prefixes. Sourced from IRS\n * documentation and python-stdnum's numdb.\n */\nconst VALID_PREFIXES = new Set([\n \"01\",\n \"02\",\n \"03\",\n \"04\",\n \"05\",\n \"06\",\n \"10\",\n \"11\",\n \"12\",\n \"13\",\n \"14\",\n \"15\",\n \"16\",\n \"20\",\n \"21\",\n \"22\",\n \"23\",\n \"24\",\n \"25\",\n \"26\",\n \"27\",\n \"30\",\n \"31\",\n \"32\",\n \"33\",\n \"34\",\n \"35\",\n \"36\",\n \"37\",\n \"38\",\n \"39\",\n \"40\",\n \"41\",\n \"42\",\n \"43\",\n \"44\",\n \"45\",\n \"46\",\n \"47\",\n \"48\",\n \"50\",\n \"51\",\n \"52\",\n \"53\",\n \"54\",\n \"55\",\n \"56\",\n \"57\",\n \"58\",\n \"59\",\n \"60\",\n \"61\",\n \"62\",\n \"63\",\n \"64\",\n \"65\",\n \"66\",\n \"67\",\n \"68\",\n \"71\",\n \"72\",\n \"73\",\n \"74\",\n \"75\",\n \"76\",\n \"77\",\n \"80\",\n \"81\",\n \"82\",\n \"83\",\n \"84\",\n \"85\",\n \"86\",\n \"87\",\n \"88\",\n \"90\",\n \"91\",\n \"92\",\n \"93\",\n \"94\",\n \"95\",\n \"98\",\n \"99\",\n]);\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"EIN must contain only digits\",\n );\n }\n if (v.length !== 9) {\n return err(\"INVALID_LENGTH\", \"EIN must be 9 digits\");\n }\n const prefix = v.slice(0, 2);\n if (!VALID_PREFIXES.has(prefix)) {\n return err(\n \"INVALID_COMPONENT\",\n \"EIN campus prefix is invalid\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n if (v.length === 9) {\n return `${v.slice(0, 2)}-${v.slice(2)}`;\n }\n return v;\n};\n\n/** U.S. Employer Identification Number. */\nconst ein: Validator = {\n name: \"Employer Identification Number\",\n localName: \"Employer Identification Number\",\n abbreviation: \"EIN\",\n aliases: [\n \"EIN\",\n \"Employer Identification Number\",\n \"Federal Tax ID\",\n ] as const,\n candidatePattern: \"\\\\d{2}-?\\\\d{7}\",\n country: \"US\",\n entityType: \"company\",\n sourceUrl:\n \"https://www.irs.gov/businesses/small-businesses-self-employed/how-eins-are-assigned-and-valid-ein-prefixes\",\n examples: [\"042103594\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default ein;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;AAAA,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAM,iBAAyB;AAE7B,QADe,WAAW,aAAa,GACvB,aAAa,EAAE;;;;;;AAyBjC,MAAM,iBAAiB,IAAI,IAAI;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAM,WAAW,UACf,MAAM,OAAO,KAAK;AAEpB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,+BACD;AAEH,KAAI,EAAE,WAAW,EACf,QAAO,IAAI,kBAAkB,uBAAuB;CAEtD,MAAM,SAAS,EAAE,MAAM,GAAG,EAAE;AAC5B,KAAI,CAAC,eAAe,IAAI,OAAO,CAC7B,QAAO,IACL,qBACA,+BACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE;AAEvC,QAAO;;;AAIT,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;EACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WACE;CACF,UAAU,CAAC,YAAY;CACvB;CACA;CACA;CACA;CACD"}
package/dist/us/itin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { clean } from "../_util/clean.js";
2
- import { randomDigits, randomInt } from "../_util/generate.js";
2
+ import { randomDigits, randomPick } from "../_util/generate.js";
3
3
  import { err } from "../_util/result.js";
4
4
  import { isdigits } from "../_util/strings.js";
5
5
  //#region src/us/itin.ts
@@ -14,11 +14,10 @@ import { isdigits } from "../_util/strings.js";
14
14
  *
15
15
  * @see https://www.irs.gov/individuals/individual-taxpayer-identification-number
16
16
  */
17
+ const ITIN_ALLOWED_GROUPS = Array.from({ length: 30 }, (_, i) => i + 70).filter((g) => g !== 89 && g !== 93);
17
18
  /** Generate a random valid U.S. ITIN. */
18
19
  const generate = () => {
19
- const area = "9" + randomDigits(2);
20
- const allowed = Array.from({ length: 30 }, (_, i) => i + 70).filter((g) => g !== 89 && g !== 93);
21
- return `${area}${String(allowed[randomInt(0, allowed.length - 1)])}${randomDigits(4)}`;
20
+ return `${"9" + randomDigits(2)}${String(randomPick(ITIN_ALLOWED_GROUPS))}${randomDigits(4)}`;
22
21
  };
23
22
  const ITIN_RE = /^(?<area>\d{3})-?(?<group>\d{2})-?\d{4}$/;
24
23
  /** Groups 70-99 excluding 89 and 93. */
@@ -1 +1 @@
1
- {"version":3,"file":"itin.js","names":[],"sources":["../../src/us/itin.ts"],"sourcesContent":["/** Generate a random valid U.S. ITIN. */\nconst generate = (): string => {\n const area = \"9\" + randomDigits(2);\n const allowed = Array.from(\n { length: 30 },\n (_, i) => i + 70,\n ).filter((g) => g !== 89 && g !== 93);\n const group = String(\n allowed[randomInt(0, allowed.length - 1)]!,\n );\n const serial = randomDigits(4);\n return `${area}${group}${serial}`;\n};\n\n/**\n * ITIN (U.S. Individual Taxpayer Identification\n * Number).\n *\n * 9-digit number issued by the IRS to individuals\n * who need a taxpayer ID but are not eligible for\n * an SSN. Starts with 9; digits 4-5 (the \"group\")\n * must be in the range 70-99 excluding 89 and 93.\n *\n * @see https://www.irs.gov/individuals/individual-taxpayer-identification-number\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst ITIN_RE = /^(?<area>\\d{3})-?(?<group>\\d{2})-?\\d{4}$/;\n\n/** Groups 70-99 excluding 89 and 93. */\nconst ALLOWED_GROUPS = new Set(\n Array.from({ length: 30 }, (_, i) => i + 70)\n .filter((g) => g !== 89 && g !== 93)\n .map(String),\n);\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"ITIN must contain only digits\",\n );\n }\n if (v.length !== 9) {\n return err(\"INVALID_LENGTH\", \"ITIN must be 9 digits\");\n }\n\n const match = ITIN_RE.exec(v);\n if (!match?.groups) {\n return err(\n \"INVALID_FORMAT\",\n \"ITIN must be 9 digits, optionally \" +\n \"formatted as NNN-NN-NNNN\",\n );\n }\n\n const { area, group } = match.groups;\n if (!area || !group) {\n return err(\"INVALID_FORMAT\", \"ITIN must be 9 digits\");\n }\n\n if (area[0] !== \"9\") {\n return err(\n \"INVALID_COMPONENT\",\n \"ITIN area must start with 9\",\n );\n }\n\n if (!ALLOWED_GROUPS.has(group)) {\n return err(\n \"INVALID_COMPONENT\",\n \"ITIN group digits are not in the \" +\n \"allowed range (70-99 excl. 89, 93)\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n if (v.length === 9) {\n return (\n `${v.slice(0, 3)}-${v.slice(3, 5)}` + `-${v.slice(5)}`\n );\n }\n return v;\n};\n\n/**\n * U.S. Individual Taxpayer Identification Number.\n */\nconst itin: Validator = {\n name: \"Individual Taxpayer Identification Number\",\n localName: \"Individual Taxpayer Identification Number\",\n abbreviation: \"ITIN\",\n aliases: [\n \"ITIN\",\n \"Individual Taxpayer Identification Number\",\n ] as const,\n candidatePattern: \"9\\\\d{2}[\\\\s-]?\\\\d{2}[\\\\s-]?\\\\d{4}\",\n country: \"US\",\n entityType: \"person\",\n sourceUrl:\n \"https://www.irs.gov/individuals/\" +\n \"individual-taxpayer-identification-number\",\n lengths: [9] as const,\n examples: [\"912-90-3456\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default itin;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;AACA,MAAM,iBAAyB;CAC7B,MAAM,OAAO,MAAM,aAAa,EAAE;CAClC,MAAM,UAAU,MAAM,KACpB,EAAE,QAAQ,IAAI,GACb,GAAG,MAAM,IAAI,GACf,CAAC,QAAQ,MAAM,MAAM,MAAM,MAAM,GAAG;AAKrC,QAAO,GAAG,OAJI,OACZ,QAAQ,UAAU,GAAG,QAAQ,SAAS,EAAE,EACzC,GACc,aAAa,EAAE;;AAuBhC,MAAM,UAAU;;AAGhB,MAAM,iBAAiB,IAAI,IACzB,MAAM,KAAK,EAAE,QAAQ,IAAI,GAAG,GAAG,MAAM,IAAI,GAAG,CACzC,QAAQ,MAAM,MAAM,MAAM,MAAM,GAAG,CACnC,IAAI,OAAO,CACf;AAED,MAAM,WAAW,UACf,MAAM,OAAO,KAAK;AAEpB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,gCACD;AAEH,KAAI,EAAE,WAAW,EACf,QAAO,IAAI,kBAAkB,wBAAwB;CAGvD,MAAM,QAAQ,QAAQ,KAAK,EAAE;AAC7B,KAAI,CAAC,OAAO,OACV,QAAO,IACL,kBACA,6DAED;CAGH,MAAM,EAAE,MAAM,UAAU,MAAM;AAC9B,KAAI,CAAC,QAAQ,CAAC,MACZ,QAAO,IAAI,kBAAkB,wBAAwB;AAGvD,KAAI,KAAK,OAAO,IACd,QAAO,IACL,qBACA,8BACD;AAGH,KAAI,CAAC,eAAe,IAAI,MAAM,CAC5B,QAAO,IACL,qBACA,sEAED;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QACE,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,CAAA,GAAS,EAAE,MAAM,EAAE;AAGxD,QAAO;;;;;AAMT,MAAM,OAAkB;CACtB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CACP,QACA,4CACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WACE;CAEF,SAAS,CAAC,EAAE;CACZ,UAAU,CAAC,cAAc;CACzB;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"itin.js","names":[],"sources":["../../src/us/itin.ts"],"sourcesContent":["const ITIN_ALLOWED_GROUPS = Array.from(\n { length: 30 },\n (_, i) => i + 70,\n).filter((g) => g !== 89 && g !== 93);\n\n/** Generate a random valid U.S. ITIN. */\nconst generate = (): string => {\n const area = \"9\" + randomDigits(2);\n const group = String(randomPick(ITIN_ALLOWED_GROUPS));\n const serial = randomDigits(4);\n return `${area}${group}${serial}`;\n};\n\n/**\n * ITIN (U.S. Individual Taxpayer Identification\n * Number).\n *\n * 9-digit number issued by the IRS to individuals\n * who need a taxpayer ID but are not eligible for\n * an SSN. Starts with 9; digits 4-5 (the \"group\")\n * must be in the range 70-99 excluding 89 and 93.\n *\n * @see https://www.irs.gov/individuals/individual-taxpayer-identification-number\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomPick } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst ITIN_RE = /^(?<area>\\d{3})-?(?<group>\\d{2})-?\\d{4}$/;\n\n/** Groups 70-99 excluding 89 and 93. */\nconst ALLOWED_GROUPS = new Set(\n Array.from({ length: 30 }, (_, i) => i + 70)\n .filter((g) => g !== 89 && g !== 93)\n .map(String),\n);\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"ITIN must contain only digits\",\n );\n }\n if (v.length !== 9) {\n return err(\"INVALID_LENGTH\", \"ITIN must be 9 digits\");\n }\n\n const match = ITIN_RE.exec(v);\n if (!match?.groups) {\n return err(\n \"INVALID_FORMAT\",\n \"ITIN must be 9 digits, optionally \" +\n \"formatted as NNN-NN-NNNN\",\n );\n }\n\n const { area, group } = match.groups;\n if (!area || !group) {\n return err(\"INVALID_FORMAT\", \"ITIN must be 9 digits\");\n }\n\n if (area[0] !== \"9\") {\n return err(\n \"INVALID_COMPONENT\",\n \"ITIN area must start with 9\",\n );\n }\n\n if (!ALLOWED_GROUPS.has(group)) {\n return err(\n \"INVALID_COMPONENT\",\n \"ITIN group digits are not in the \" +\n \"allowed range (70-99 excl. 89, 93)\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n if (v.length === 9) {\n return (\n `${v.slice(0, 3)}-${v.slice(3, 5)}` + `-${v.slice(5)}`\n );\n }\n return v;\n};\n\n/**\n * U.S. Individual Taxpayer Identification Number.\n */\nconst itin: Validator = {\n name: \"Individual Taxpayer Identification Number\",\n localName: \"Individual Taxpayer Identification Number\",\n abbreviation: \"ITIN\",\n aliases: [\n \"ITIN\",\n \"Individual Taxpayer Identification Number\",\n ] as const,\n candidatePattern: \"9\\\\d{2}[\\\\s-]?\\\\d{2}[\\\\s-]?\\\\d{4}\",\n country: \"US\",\n entityType: \"person\",\n sourceUrl:\n \"https://www.irs.gov/individuals/\" +\n \"individual-taxpayer-identification-number\",\n lengths: [9] as const,\n examples: [\"912-90-3456\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default itin;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;AAAA,MAAM,sBAAsB,MAAM,KAChC,EAAE,QAAQ,IAAI,GACb,GAAG,MAAM,IAAI,GACf,CAAC,QAAQ,MAAM,MAAM,MAAM,MAAM,GAAG;;AAGrC,MAAM,iBAAyB;AAI7B,QAAO,GAHM,MAAM,aAAa,EAAE,GACpB,OAAO,WAAW,oBAAoB,CAAC,GACtC,aAAa,EAAE;;AAuBhC,MAAM,UAAU;;AAGhB,MAAM,iBAAiB,IAAI,IACzB,MAAM,KAAK,EAAE,QAAQ,IAAI,GAAG,GAAG,MAAM,IAAI,GAAG,CACzC,QAAQ,MAAM,MAAM,MAAM,MAAM,GAAG,CACnC,IAAI,OAAO,CACf;AAED,MAAM,WAAW,UACf,MAAM,OAAO,KAAK;AAEpB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,gCACD;AAEH,KAAI,EAAE,WAAW,EACf,QAAO,IAAI,kBAAkB,wBAAwB;CAGvD,MAAM,QAAQ,QAAQ,KAAK,EAAE;AAC7B,KAAI,CAAC,OAAO,OACV,QAAO,IACL,kBACA,6DAED;CAGH,MAAM,EAAE,MAAM,UAAU,MAAM;AAC9B,KAAI,CAAC,QAAQ,CAAC,MACZ,QAAO,IAAI,kBAAkB,wBAAwB;AAGvD,KAAI,KAAK,OAAO,IACd,QAAO,IACL,qBACA,8BACD;AAGH,KAAI,CAAC,eAAe,IAAI,MAAM,CAC5B,QAAO,IACL,qBACA,sEAED;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QACE,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,CAAA,GAAS,EAAE,MAAM,EAAE;AAGxD,QAAO;;;;;AAMT,MAAM,OAAkB;CACtB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CACP,QACA,4CACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WACE;CAEF,SAAS,CAAC,EAAE;CACZ,UAAU,CAAC,cAAc;CACzB;CACA;CACA;CACA;CACD"}
package/dist/us/mod.d.ts CHANGED
@@ -1,11 +1,12 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
1
  import ein from "./ein.js";
3
2
  import itin from "./itin.js";
4
3
  import rtn from "./rtn.js";
5
4
  import ssn from "./ssn.js";
6
5
 
7
6
  //#region src/us/mod.d.ts
8
-
7
+ declare namespace mod_d_exports {
8
+ export { ein, itin, rtn, ssn };
9
+ }
9
10
  //#endregion
10
11
  export { ein, itin, mod_d_exports, rtn, ssn };
11
12
  //# sourceMappingURL=mod.d.ts.map
package/dist/us/rtn.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/us/rtn.d.ts
4
-
5
4
  declare const compact: (value: string) => string;
6
5
  declare const validate: (value: string) => ValidateResult;
7
6
  declare const format: (value: string) => string;
package/dist/us/rtn.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { clean } from "../_util/clean.js";
2
- import { randomDigits, randomInt } from "../_util/generate.js";
2
+ import { randomDigits, randomInt, randomPick } from "../_util/generate.js";
3
3
  import { err } from "../_util/result.js";
4
4
  import { isdigits } from "../_util/strings.js";
5
5
  //#region src/us/rtn.ts
@@ -38,7 +38,7 @@ const validate = (value) => {
38
38
  const prefix = Number(v.slice(0, 2));
39
39
  if (!(prefix >= 1 && prefix <= 12 || prefix >= 21 && prefix <= 32 || prefix >= 61 && prefix <= 72 || prefix === 80)) return err("INVALID_COMPONENT", "RTN has an invalid Federal Reserve district");
40
40
  let sum = 0;
41
- for (let i = 0; i < 9; i++) sum += Number(v[i]) * WEIGHTS[i];
41
+ for (const [i, weight] of WEIGHTS.entries()) sum += Number(v[i]) * weight;
42
42
  if (sum % 10 !== 0) return err("INVALID_CHECKSUM", "RTN checksum is invalid");
43
43
  return {
44
44
  valid: true,
@@ -55,10 +55,13 @@ const PREFIX_RANGES = [
55
55
  ];
56
56
  /** Generate a random valid U.S. RTN. */
57
57
  const generate = () => {
58
- const range = PREFIX_RANGES[randomInt(0, PREFIX_RANGES.length - 1)];
59
- const body = String(randomInt(range[0], range[1])).padStart(2, "0") + randomDigits(6);
58
+ const [low, high] = randomPick(PREFIX_RANGES);
59
+ const body = String(randomInt(low, high)).padStart(2, "0") + randomDigits(6);
60
60
  let sum = 0;
61
- for (let i = 0; i < 8; i++) sum += Number(body[i]) * WEIGHTS[i];
61
+ for (const [i, weight] of WEIGHTS.entries()) {
62
+ if (i >= 8) break;
63
+ sum += Number(body[i]) * weight;
64
+ }
62
65
  const check = (10 - sum % 10) % 10;
63
66
  return body + String(check);
64
67
  };
@@ -1 +1 @@
1
- {"version":3,"file":"rtn.js","names":[],"sources":["../../src/us/rtn.ts"],"sourcesContent":["/**\n * RTN (Routing Transit Number / ABA Number).\n *\n * 9-digit number used by U.S. financial institutions\n * for routing wire transfers, ACH, and check\n * processing. Uses a weighted checksum with weights\n * [3, 7, 1] repeated three times.\n *\n * The first two digits identify the Federal Reserve\n * district (01-12) or special ranges (21-32 for\n * thrifts, 61-72 for electronic, 80 for traveler's\n * cheques).\n *\n * @see https://en.wikipedia.org/wiki/ABA_routing_transit_number\n * @see https://www.frbservices.org/\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst WEIGHTS = [3, 7, 1, 3, 7, 1, 3, 7, 1];\n\nconst compact = (value: string): string =>\n clean(value, \" -\").trim();\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 9) {\n return err(\"INVALID_LENGTH\", \"RTN must be 9 digits\");\n }\n\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"RTN must contain only digits\",\n );\n }\n\n // Validate Federal Reserve prefix (first 2 digits)\n const prefix = Number(v.slice(0, 2));\n const validPrefixRanges =\n (prefix >= 1 && prefix <= 12) ||\n (prefix >= 21 && prefix <= 32) ||\n (prefix >= 61 && prefix <= 72) ||\n prefix === 80;\n if (!validPrefixRanges) {\n return err(\n \"INVALID_COMPONENT\",\n \"RTN has an invalid Federal Reserve district\",\n );\n }\n\n // Weighted checksum must be divisible by 10\n let sum = 0;\n for (let i = 0; i < 9; i++) {\n sum += Number(v[i]) * WEIGHTS[i]!;\n }\n if (sum % 10 !== 0) {\n return err(\n \"INVALID_CHECKSUM\",\n \"RTN checksum is invalid\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** All valid Federal Reserve prefix ranges. */\nconst PREFIX_RANGES: readonly [number, number][] = [\n [1, 12],\n [21, 32],\n [61, 72],\n [80, 80],\n];\n\n/** Generate a random valid U.S. RTN. */\nconst generate = (): string => {\n const range =\n PREFIX_RANGES[randomInt(0, PREFIX_RANGES.length - 1)]!;\n const prefix = String(\n randomInt(range[0], range[1]),\n ).padStart(2, \"0\");\n const mid = randomDigits(6);\n const body = prefix + mid;\n let sum = 0;\n for (let i = 0; i < 8; i++) {\n sum += Number(body[i]) * WEIGHTS[i]!;\n }\n const check = (10 - (sum % 10)) % 10;\n return body + String(check);\n};\n\n/** U.S. Routing Transit Number. */\nconst rtn: Validator = {\n name: \"Routing Transit Number\",\n localName: \"Routing Transit Number\",\n abbreviation: \"RTN\",\n aliases: [\n \"RTN\",\n \"ABA\",\n \"Routing Number\",\n \"ABA Routing Number\",\n \"Routing Transit Number\",\n ] as const,\n candidatePattern: \"\\\\d{9}\",\n country: \"US\",\n entityType: \"company\",\n sourceUrl:\n \"https://en.wikipedia.org/wiki/ABA_routing_transit_number\",\n lengths: [9] as const,\n examples: [\"111000025\", \"021000021\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default rtn;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAwBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAE3C,MAAM,WAAW,UACf,MAAM,OAAO,KAAK,CAAC,MAAM;AAE3B,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,EACf,QAAO,IAAI,kBAAkB,uBAAuB;AAGtD,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,+BACD;CAIH,MAAM,SAAS,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;AAMpC,KAAI,EAJD,UAAU,KAAK,UAAU,MACzB,UAAU,MAAM,UAAU,MAC1B,UAAU,MAAM,UAAU,MAC3B,WAAW,IAEX,QAAO,IACL,qBACA,8CACD;CAIH,IAAI,MAAM;AACV,MAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IACrB,QAAO,OAAO,EAAE,GAAG,GAAG,QAAQ;AAEhC,KAAI,MAAM,OAAO,EACf,QAAO,IACL,oBACA,0BACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B,QAAQ,MAAM;;AAGxD,MAAM,gBAA6C;CACjD,CAAC,GAAG,GAAG;CACP,CAAC,IAAI,GAAG;CACR,CAAC,IAAI,GAAG;CACR,CAAC,IAAI,GAAG;CACT;;AAGD,MAAM,iBAAyB;CAC7B,MAAM,QACJ,cAAc,UAAU,GAAG,cAAc,SAAS,EAAE;CAKtD,MAAM,OAJS,OACb,UAAU,MAAM,IAAI,MAAM,GAAG,CAC9B,CAAC,SAAS,GAAG,IAAI,GACN,aAAa,EAAE;CAE3B,IAAI,MAAM;AACV,MAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IACrB,QAAO,OAAO,KAAK,GAAG,GAAG,QAAQ;CAEnC,MAAM,SAAS,KAAM,MAAM,MAAO;AAClC,QAAO,OAAO,OAAO,MAAM;;;AAI7B,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;EACA;EACA;EACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WACE;CACF,SAAS,CAAC,EAAE;CACZ,UAAU,CAAC,aAAa,YAAY;CACpC;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"rtn.js","names":[],"sources":["../../src/us/rtn.ts"],"sourcesContent":["/**\n * RTN (Routing Transit Number / ABA Number).\n *\n * 9-digit number used by U.S. financial institutions\n * for routing wire transfers, ACH, and check\n * processing. Uses a weighted checksum with weights\n * [3, 7, 1] repeated three times.\n *\n * The first two digits identify the Federal Reserve\n * district (01-12) or special ranges (21-32 for\n * thrifts, 61-72 for electronic, 80 for traveler's\n * cheques).\n *\n * @see https://en.wikipedia.org/wiki/ABA_routing_transit_number\n * @see https://www.frbservices.org/\n */\n\nimport { clean } from \"#util/clean\";\nimport {\n randomDigits,\n randomInt,\n randomPick,\n} from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst WEIGHTS = [3, 7, 1, 3, 7, 1, 3, 7, 1] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -\").trim();\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 9) {\n return err(\"INVALID_LENGTH\", \"RTN must be 9 digits\");\n }\n\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"RTN must contain only digits\",\n );\n }\n\n // Validate Federal Reserve prefix (first 2 digits)\n const prefix = Number(v.slice(0, 2));\n const validPrefixRanges =\n (prefix >= 1 && prefix <= 12) ||\n (prefix >= 21 && prefix <= 32) ||\n (prefix >= 61 && prefix <= 72) ||\n prefix === 80;\n if (!validPrefixRanges) {\n return err(\n \"INVALID_COMPONENT\",\n \"RTN has an invalid Federal Reserve district\",\n );\n }\n\n // Weighted checksum must be divisible by 10\n let sum = 0;\n for (const [i, weight] of WEIGHTS.entries()) {\n sum += Number(v[i]) * weight;\n }\n if (sum % 10 !== 0) {\n return err(\n \"INVALID_CHECKSUM\",\n \"RTN checksum is invalid\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** All valid Federal Reserve prefix ranges. */\nconst PREFIX_RANGES: readonly [number, number][] = [\n [1, 12],\n [21, 32],\n [61, 72],\n [80, 80],\n];\n\n/** Generate a random valid U.S. RTN. */\nconst generate = (): string => {\n const [low, high] = randomPick(PREFIX_RANGES);\n const prefix = String(randomInt(low, high)).padStart(\n 2,\n \"0\",\n );\n const mid = randomDigits(6);\n const body = prefix + mid;\n let sum = 0;\n for (const [i, weight] of WEIGHTS.entries()) {\n if (i >= 8) break;\n sum += Number(body[i]) * weight;\n }\n const check = (10 - (sum % 10)) % 10;\n return body + String(check);\n};\n\n/** U.S. Routing Transit Number. */\nconst rtn: Validator = {\n name: \"Routing Transit Number\",\n localName: \"Routing Transit Number\",\n abbreviation: \"RTN\",\n aliases: [\n \"RTN\",\n \"ABA\",\n \"Routing Number\",\n \"ABA Routing Number\",\n \"Routing Transit Number\",\n ] as const,\n candidatePattern: \"\\\\d{9}\",\n country: \"US\",\n entityType: \"company\",\n sourceUrl:\n \"https://en.wikipedia.org/wiki/ABA_routing_transit_number\",\n lengths: [9] as const,\n examples: [\"111000025\", \"021000021\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default rtn;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA4BA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAE3C,MAAM,WAAW,UACf,MAAM,OAAO,KAAK,CAAC,MAAM;AAE3B,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,EACf,QAAO,IAAI,kBAAkB,uBAAuB;AAGtD,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,+BACD;CAIH,MAAM,SAAS,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;AAMpC,KAAI,EAJD,UAAU,KAAK,UAAU,MACzB,UAAU,MAAM,UAAU,MAC1B,UAAU,MAAM,UAAU,MAC3B,WAAW,IAEX,QAAO,IACL,qBACA,8CACD;CAIH,IAAI,MAAM;AACV,MAAK,MAAM,CAAC,GAAG,WAAW,QAAQ,SAAS,CACzC,QAAO,OAAO,EAAE,GAAG,GAAG;AAExB,KAAI,MAAM,OAAO,EACf,QAAO,IACL,oBACA,0BACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B,QAAQ,MAAM;;AAGxD,MAAM,gBAA6C;CACjD,CAAC,GAAG,GAAG;CACP,CAAC,IAAI,GAAG;CACR,CAAC,IAAI,GAAG;CACR,CAAC,IAAI,GAAG;CACT;;AAGD,MAAM,iBAAyB;CAC7B,MAAM,CAAC,KAAK,QAAQ,WAAW,cAAc;CAM7C,MAAM,OALS,OAAO,UAAU,KAAK,KAAK,CAAC,CAAC,SAC1C,GACA,IACD,GACW,aAAa,EAAE;CAE3B,IAAI,MAAM;AACV,MAAK,MAAM,CAAC,GAAG,WAAW,QAAQ,SAAS,EAAE;AAC3C,MAAI,KAAK,EAAG;AACZ,SAAO,OAAO,KAAK,GAAG,GAAG;;CAE3B,MAAM,SAAS,KAAM,MAAM,MAAO;AAClC,QAAO,OAAO,OAAO,MAAM;;;AAI7B,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;EACA;EACA;EACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WACE;CACF,SAAS,CAAC,EAAE;CACZ,UAAU,CAAC,aAAa,YAAY;CACpC;CACA;CACA;CACA;CACD"}
package/dist/uy/mod.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
1
  import rut from "./rut.js";
3
2
 
4
3
  //#region src/uy/mod.d.ts
5
-
4
+ declare namespace mod_d_exports {
5
+ export { rut };
6
+ }
6
7
  //#endregion
7
8
  export { mod_d_exports, rut };
8
9
  //# sourceMappingURL=mod.d.ts.map
package/dist/uy/rut.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/uy/rut.d.ts
4
-
5
4
  declare const compact: (value: string) => string;
6
5
  declare const validate: (value: string) => ValidateResult;
7
6
  declare const format: (value: string) => string;
package/dist/uy/rut.js CHANGED
@@ -42,7 +42,7 @@ const compact = (value) => {
42
42
  const pymod = (a, b) => (a % b + b) % b;
43
43
  const calcCheckDigit = (value) => {
44
44
  let sum = 0;
45
- for (let i = 0; i < 11; i++) sum += Number(value[i]) * WEIGHTS[i];
45
+ for (const [i, weight] of WEIGHTS.entries()) sum += Number(value[i]) * weight;
46
46
  const result = pymod(-sum, 11);
47
47
  if (result === 10) return null;
48
48
  return String(result);
@@ -1 +1 @@
1
- {"version":3,"file":"rut.js","names":[],"sources":["../../src/uy/rut.ts"],"sourcesContent":["/**\n * RUT (Registro Único Tributario).\n *\n * Uruguayan tax identification number issued by the\n * DGI (Dirección General Impositiva). The number is\n * 12 digits: 2-digit document type (01-22), 6-digit\n * sequence, fixed \"001\" suffix, and a check digit\n * computed via weighted sum mod 11 (Python-style\n * modulo of the negated sum).\n *\n * Format: ############ (12 digits compact)\n *\n * @see https://www.agesic.gub.uy/\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst WEIGHTS = [4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2] as const;\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -\").trim();\n if (v.toUpperCase().startsWith(\"UY\")) {\n v = v.slice(2);\n }\n return v;\n};\n\n/**\n * Python-style modulo: always returns a non-negative\n * result for a positive divisor.\n */\nconst pymod = (a: number, b: number): number =>\n ((a % b) + b) % b;\n\nconst calcCheckDigit = (value: string): string | null => {\n let sum = 0;\n for (let i = 0; i < 11; i++) {\n sum += Number(value[i]) * WEIGHTS[i]!;\n }\n const result = pymod(-sum, 11);\n // A result of 10 means no valid single-digit check\n // digit exists; the DGI does not issue such numbers.\n if (result === 10) return null;\n return String(result);\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 12) {\n return err(\"INVALID_LENGTH\", \"RUT must be 12 digits\");\n }\n\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"RUT must contain only digits\",\n );\n }\n\n // First 2 digits: document type (01-22)\n const docType = Number.parseInt(v.slice(0, 2), 10);\n if (docType < 1 || docType > 22) {\n return err(\n \"INVALID_COMPONENT\",\n \"RUT document type must be between 01 and 22\",\n );\n }\n\n // Digits 2-8: sequence (must not be all zeros)\n if (v.slice(2, 8) === \"000000\") {\n return err(\n \"INVALID_COMPONENT\",\n \"RUT sequence must not be all zeros\",\n );\n }\n\n // Digits 8-11: must be \"001\"\n if (v.slice(8, 11) !== \"001\") {\n return err(\n \"INVALID_COMPONENT\",\n \"RUT branch code must be 001\",\n );\n }\n\n const expected = calcCheckDigit(v);\n if (expected === null || v.at(-1) !== expected) {\n return err(\n \"INVALID_CHECKSUM\",\n \"RUT check digit does not match\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n return `${v.slice(0, 2)}-${v.slice(2, 8)}-${v.slice(8, 11)}-${v.slice(11)}`;\n};\n\n/** Generate a random valid Uruguayan RUT. */\nconst generate = (): string => {\n for (;;) {\n const docType = String(randomInt(1, 22)).padStart(\n 2,\n \"0\",\n );\n const seq = randomDigits(6);\n if (seq === \"000000\") continue;\n const partial = `${docType}${seq}001`;\n const check = calcCheckDigit(partial);\n if (check === null) continue;\n return `${partial}${check}`;\n }\n};\n\n/**\n * Uruguayan RUT (tax identification number).\n *\n * Examples sourced from python-stdnum test suite.\n */\nconst rut: Validator = {\n name: \"Uruguayan Tax ID\",\n localName: \"Registro Único Tributario\",\n abbreviation: \"RUT\",\n aliases: [\"RUT\", \"Registro Único Tributario\"] as const,\n candidatePattern: \"\\\\d{12}\",\n country: \"UY\",\n entityType: \"any\",\n lengths: [12] as const,\n examples: [\"010100010013\", \"102000010017\"] as const,\n compact,\n format,\n validate,\n sourceUrl: \"https://www.agesic.gub.uy/\",\n generate,\n};\n\nexport default rut;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAsBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAEjD,MAAM,WAAW,UAA0B;CACzC,IAAI,IAAI,MAAM,OAAO,KAAK,CAAC,MAAM;AACjC,KAAI,EAAE,aAAa,CAAC,WAAW,KAAK,CAClC,KAAI,EAAE,MAAM,EAAE;AAEhB,QAAO;;;;;;AAOT,MAAM,SAAS,GAAW,OACtB,IAAI,IAAK,KAAK;AAElB,MAAM,kBAAkB,UAAiC;CACvD,IAAI,MAAM;AACV,MAAK,IAAI,IAAI,GAAG,IAAI,IAAI,IACtB,QAAO,OAAO,MAAM,GAAG,GAAG,QAAQ;CAEpC,MAAM,SAAS,MAAM,CAAC,KAAK,GAAG;AAG9B,KAAI,WAAW,GAAI,QAAO;AAC1B,QAAO,OAAO,OAAO;;AAGvB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,GACf,QAAO,IAAI,kBAAkB,wBAAwB;AAGvD,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,+BACD;CAIH,MAAM,UAAU,OAAO,SAAS,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG;AAClD,KAAI,UAAU,KAAK,UAAU,GAC3B,QAAO,IACL,qBACA,8CACD;AAIH,KAAI,EAAE,MAAM,GAAG,EAAE,KAAK,SACpB,QAAO,IACL,qBACA,qCACD;AAIH,KAAI,EAAE,MAAM,GAAG,GAAG,KAAK,MACrB,QAAO,IACL,qBACA,8BACD;CAGH,MAAM,WAAW,eAAe,EAAE;AAClC,KAAI,aAAa,QAAQ,EAAE,GAAG,GAAG,KAAK,SACpC,QAAO,IACL,oBACA,iCACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;AACxB,QAAO,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG;;;AAI3E,MAAM,iBAAyB;AAC7B,UAAS;EACP,MAAM,UAAU,OAAO,UAAU,GAAG,GAAG,CAAC,CAAC,SACvC,GACA,IACD;EACD,MAAM,MAAM,aAAa,EAAE;AAC3B,MAAI,QAAQ,SAAU;EACtB,MAAM,UAAU,GAAG,UAAU,IAAI;EACjC,MAAM,QAAQ,eAAe,QAAQ;AACrC,MAAI,UAAU,KAAM;AACpB,SAAO,GAAG,UAAU;;;;;;;;AASxB,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,OAAO,4BAA4B;CAC7C,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,GAAG;CACb,UAAU,CAAC,gBAAgB,eAAe;CAC1C;CACA;CACA;CACA,WAAW;CACX;CACD"}
1
+ {"version":3,"file":"rut.js","names":[],"sources":["../../src/uy/rut.ts"],"sourcesContent":["/**\n * RUT (Registro Único Tributario).\n *\n * Uruguayan tax identification number issued by the\n * DGI (Dirección General Impositiva). The number is\n * 12 digits: 2-digit document type (01-22), 6-digit\n * sequence, fixed \"001\" suffix, and a check digit\n * computed via weighted sum mod 11 (Python-style\n * modulo of the negated sum).\n *\n * Format: ############ (12 digits compact)\n *\n * @see https://www.agesic.gub.uy/\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst WEIGHTS = [4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2] as const;\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -\").trim();\n if (v.toUpperCase().startsWith(\"UY\")) {\n v = v.slice(2);\n }\n return v;\n};\n\n/**\n * Python-style modulo: always returns a non-negative\n * result for a positive divisor.\n */\nconst pymod = (a: number, b: number): number =>\n ((a % b) + b) % b;\n\nconst calcCheckDigit = (value: string): string | null => {\n let sum = 0;\n for (const [i, weight] of WEIGHTS.entries()) {\n sum += Number(value[i]) * weight;\n }\n const result = pymod(-sum, 11);\n // A result of 10 means no valid single-digit check\n // digit exists; the DGI does not issue such numbers.\n if (result === 10) return null;\n return String(result);\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 12) {\n return err(\"INVALID_LENGTH\", \"RUT must be 12 digits\");\n }\n\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"RUT must contain only digits\",\n );\n }\n\n // First 2 digits: document type (01-22)\n const docType = Number.parseInt(v.slice(0, 2), 10);\n if (docType < 1 || docType > 22) {\n return err(\n \"INVALID_COMPONENT\",\n \"RUT document type must be between 01 and 22\",\n );\n }\n\n // Digits 2-8: sequence (must not be all zeros)\n if (v.slice(2, 8) === \"000000\") {\n return err(\n \"INVALID_COMPONENT\",\n \"RUT sequence must not be all zeros\",\n );\n }\n\n // Digits 8-11: must be \"001\"\n if (v.slice(8, 11) !== \"001\") {\n return err(\n \"INVALID_COMPONENT\",\n \"RUT branch code must be 001\",\n );\n }\n\n const expected = calcCheckDigit(v);\n if (expected === null || v.at(-1) !== expected) {\n return err(\n \"INVALID_CHECKSUM\",\n \"RUT check digit does not match\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n return `${v.slice(0, 2)}-${v.slice(2, 8)}-${v.slice(8, 11)}-${v.slice(11)}`;\n};\n\n/** Generate a random valid Uruguayan RUT. */\nconst generate = (): string => {\n for (;;) {\n const docType = String(randomInt(1, 22)).padStart(\n 2,\n \"0\",\n );\n const seq = randomDigits(6);\n if (seq === \"000000\") continue;\n const partial = `${docType}${seq}001`;\n const check = calcCheckDigit(partial);\n if (check === null) continue;\n return `${partial}${check}`;\n }\n};\n\n/**\n * Uruguayan RUT (tax identification number).\n *\n * Examples sourced from python-stdnum test suite.\n */\nconst rut: Validator = {\n name: \"Uruguayan Tax ID\",\n localName: \"Registro Único Tributario\",\n abbreviation: \"RUT\",\n aliases: [\"RUT\", \"Registro Único Tributario\"] as const,\n candidatePattern: \"\\\\d{12}\",\n country: \"UY\",\n entityType: \"any\",\n lengths: [12] as const,\n examples: [\"010100010013\", \"102000010017\"] as const,\n compact,\n format,\n validate,\n sourceUrl: \"https://www.agesic.gub.uy/\",\n generate,\n};\n\nexport default rut;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAsBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAEjD,MAAM,WAAW,UAA0B;CACzC,IAAI,IAAI,MAAM,OAAO,KAAK,CAAC,MAAM;AACjC,KAAI,EAAE,aAAa,CAAC,WAAW,KAAK,CAClC,KAAI,EAAE,MAAM,EAAE;AAEhB,QAAO;;;;;;AAOT,MAAM,SAAS,GAAW,OACtB,IAAI,IAAK,KAAK;AAElB,MAAM,kBAAkB,UAAiC;CACvD,IAAI,MAAM;AACV,MAAK,MAAM,CAAC,GAAG,WAAW,QAAQ,SAAS,CACzC,QAAO,OAAO,MAAM,GAAG,GAAG;CAE5B,MAAM,SAAS,MAAM,CAAC,KAAK,GAAG;AAG9B,KAAI,WAAW,GAAI,QAAO;AAC1B,QAAO,OAAO,OAAO;;AAGvB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,GACf,QAAO,IAAI,kBAAkB,wBAAwB;AAGvD,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,+BACD;CAIH,MAAM,UAAU,OAAO,SAAS,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG;AAClD,KAAI,UAAU,KAAK,UAAU,GAC3B,QAAO,IACL,qBACA,8CACD;AAIH,KAAI,EAAE,MAAM,GAAG,EAAE,KAAK,SACpB,QAAO,IACL,qBACA,qCACD;AAIH,KAAI,EAAE,MAAM,GAAG,GAAG,KAAK,MACrB,QAAO,IACL,qBACA,8BACD;CAGH,MAAM,WAAW,eAAe,EAAE;AAClC,KAAI,aAAa,QAAQ,EAAE,GAAG,GAAG,KAAK,SACpC,QAAO,IACL,oBACA,iCACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;AACxB,QAAO,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG;;;AAI3E,MAAM,iBAAyB;AAC7B,UAAS;EACP,MAAM,UAAU,OAAO,UAAU,GAAG,GAAG,CAAC,CAAC,SACvC,GACA,IACD;EACD,MAAM,MAAM,aAAa,EAAE;AAC3B,MAAI,QAAQ,SAAU;EACtB,MAAM,UAAU,GAAG,UAAU,IAAI;EACjC,MAAM,QAAQ,eAAe,QAAQ;AACrC,MAAI,UAAU,KAAM;AACpB,SAAO,GAAG,UAAU;;;;;;;;AASxB,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,OAAO,4BAA4B;CAC7C,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,GAAG;CACb,UAAU,CAAC,gBAAgB,eAAe;CAC1C;CACA;CACA;CACA,WAAW;CACX;CACD"}
package/dist/ve/mod.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
1
  import rif from "./rif.js";
3
2
 
4
3
  //#region src/ve/mod.d.ts
5
-
4
+ declare namespace mod_d_exports {
5
+ export { rif };
6
+ }
6
7
  //#endregion
7
8
  export { mod_d_exports, rif };
8
9
  //# sourceMappingURL=mod.d.ts.map
package/dist/ve/rif.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/ve/rif.d.ts
4
-
5
4
  declare const compact: (value: string) => string;
6
5
  declare const validate: (value: string) => ValidateResult;
7
6
  declare const format: (value: string) => string;
package/dist/ve/rif.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { clean } from "../_util/clean.js";
2
- import { randomDigits, randomInt } from "../_util/generate.js";
2
+ import { randomDigits, randomPick } from "../_util/generate.js";
3
3
  import { err } from "../_util/result.js";
4
4
  import { isdigits } from "../_util/strings.js";
5
5
  //#region src/ve/rif.ts
@@ -46,9 +46,9 @@ const WEIGHTS = [
46
46
  const CHECK_LOOKUP = "00987654321";
47
47
  const compact = (value) => clean(value, " -.").trim().toUpperCase();
48
48
  const calcCheckDigit = (prefix, body) => {
49
- const pv = PREFIX_VALUES[prefix];
49
+ const pv = PREFIX_VALUES[prefix] ?? 0;
50
50
  let sum = 0;
51
- for (let i = 0; i < 8; i++) sum += Number(body[i]) * WEIGHTS[i];
51
+ for (const [i, weight] of WEIGHTS.entries()) sum += Number(body[i]) * weight;
52
52
  return CHECK_LOOKUP[(pv + sum % 11) % 11];
53
53
  };
54
54
  const validate = (value) => {
@@ -69,16 +69,16 @@ const format = (value) => {
69
69
  const v = compact(value);
70
70
  return `${v[0]}-${v.slice(1, 9)}-${v.slice(9)}`;
71
71
  };
72
+ const GENERATE_TYPES = [
73
+ "V",
74
+ "E",
75
+ "J",
76
+ "P",
77
+ "G"
78
+ ];
72
79
  /** Generate a random valid Venezuelan RIF. */
73
80
  const generate = () => {
74
- const types = [
75
- "V",
76
- "E",
77
- "J",
78
- "P",
79
- "G"
80
- ];
81
- const prefix = types[randomInt(0, types.length - 1)];
81
+ const prefix = randomPick(GENERATE_TYPES);
82
82
  const body = randomDigits(8);
83
83
  return prefix + body + String(calcCheckDigit(prefix, body));
84
84
  };