@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/bz/tin.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/bz/tin.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;
7
+ /** Generate a random valid Belize TIN. */
8
+ declare const generate: () => string;
8
9
  /**
9
10
  * Belize Tax Identification Number.
10
11
  *
@@ -12,5 +13,5 @@ declare const format: (value: string) => string;
12
13
  */
13
14
  declare const tin: Validator;
14
15
  //#endregion
15
- export { compact, tin as default, format, validate };
16
+ export { compact, tin as default, format, generate, validate };
16
17
  //# sourceMappingURL=tin.d.ts.map
package/dist/bz/tin.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { clean } from "../_util/clean.js";
2
+ import { randomDigits, randomInt } from "../_util/generate.js";
2
3
  import { err } from "../_util/result.js";
3
4
  //#region src/bz/tin.ts
4
5
  /**
@@ -54,6 +55,12 @@ const format = (value) => {
54
55
  if (v.length <= 6) return v;
55
56
  return `${v.slice(0, 6)}-${v.slice(6)}`;
56
57
  };
58
+ /** Generate a random valid Belize TIN. */
59
+ const generate = () => {
60
+ const base = randomDigits(6);
61
+ const suffixes = ["", ...SUFFIX_CODES];
62
+ return `${base}${suffixes[randomInt(0, suffixes.length - 1)] ?? ""}`;
63
+ };
57
64
  /**
58
65
  * Belize Tax Identification Number.
59
66
  *
@@ -76,10 +83,11 @@ const tin = {
76
83
  compact,
77
84
  format,
78
85
  validate,
86
+ generate,
79
87
  description: "Belize tax number issued by the Belize Tax Service Department",
80
88
  sourceUrl: "https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Belize-TIN.pdf"
81
89
  };
82
90
  //#endregion
83
- export { compact, tin as default, format, validate };
91
+ export { compact, tin as default, format, generate, validate };
84
92
 
85
93
  //# sourceMappingURL=tin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tin.js","names":[],"sources":["../../src/bz/tin.ts"],"sourcesContent":["/**\n * TIN (Belize Tax Identification Number).\n *\n * Issued by the Belize Tax Service Department to\n * individuals, sole proprietors, partnerships, and\n * companies. The base number is 6 digits generated\n * by the Revenue Management System. A 2-digit\n * suffix code may be appended to indicate entity\n * type:\n * - 10: individual\n * - 13: company\n * - 66: company (alternate)\n *\n * The OECD spec mentions a 7th check digit that is\n * not visible to the taxpayer; in practice the\n * number circulates as 6 or 8 digits (6 + suffix).\n *\n * Formatted as NNNNNN-SS (when suffix is present).\n *\n * Source: OECD CRS TIN information sheet; Belize\n * Tax Service (https://bts.gov.bz/).\n *\n * PERSON/ENTITY\n *\n * @see https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Belize-TIN.pdf\n */\n\nimport { clean } from \"#util/clean\";\nimport { err } from \"#util/result\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\n/** Valid 2-digit suffix codes. */\nconst SUFFIX_CODES = [\"10\", \"13\", \"66\"] as const;\n\nconst compact = (value: string): string => {\n return clean(value, \" -\").trim();\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 6 && v.length !== 8) {\n return err(\n \"INVALID_LENGTH\",\n \"Belize TIN must be 6 or 8 digits\",\n );\n }\n\n if (!/^\\d+$/.test(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Belize TIN must contain only digits\",\n );\n }\n\n if (v.length === 8) {\n const suffix = v.slice(6);\n if (\n !SUFFIX_CODES.includes(\n suffix as (typeof SUFFIX_CODES)[number],\n )\n ) {\n return err(\n \"INVALID_COMPONENT\",\n \"Belize TIN suffix must be 10, 13, or 66\",\n );\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 <= 6) {\n return v;\n }\n return `${v.slice(0, 6)}-${v.slice(6)}`;\n};\n\n/**\n * Belize Tax Identification Number.\n *\n * Examples derived from stdnum-js test suite.\n */\nconst tin: Validator = {\n name: \"Belize Tax Identification Number\",\n localName: \"Tax Identification Number\",\n abbreviation: \"TIN\",\n aliases: [\"TIN\"] as const,\n candidatePattern: \"\\\\d{6}\",\n country: \"BZ\",\n entityType: \"any\",\n lengths: [6, 8] as const,\n examples: [\"000005\", \"00000510\", \"00000513\"] as const,\n compact,\n format,\n validate,\n description:\n \"Belize tax number issued by the Belize Tax Service Department\",\n sourceUrl:\n \"https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Belize-TIN.pdf\",\n};\n\nexport default tin;\nexport { compact, format, validate };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,MAAM,eAAe;CAAC;CAAM;CAAM;CAAK;AAEvC,MAAM,WAAW,UAA0B;AACzC,QAAO,MAAM,OAAO,KAAK,CAAC,MAAM;;AAGlC,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,KAAK,EAAE,WAAW,EACjC,QAAO,IACL,kBACA,mCACD;AAGH,KAAI,CAAC,QAAQ,KAAK,EAAE,CAClB,QAAO,IACL,kBACA,sCACD;AAGH,KAAI,EAAE,WAAW,GAAG;EAClB,MAAM,SAAS,EAAE,MAAM,EAAE;AACzB,MACE,CAAC,aAAa,SACZ,OACD,CAED,QAAO,IACL,qBACA,0CACD;;AAIL,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,UAAU,EACd,QAAO;AAET,QAAO,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE;;;;;;;AAQvC,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,MAAM;CAChB,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,GAAG,EAAE;CACf,UAAU;EAAC;EAAU;EAAY;EAAW;CAC5C;CACA;CACA;CACA,aACE;CACF,WACE;CACH"}
1
+ {"version":3,"file":"tin.js","names":[],"sources":["../../src/bz/tin.ts"],"sourcesContent":["/**\n * TIN (Belize Tax Identification Number).\n *\n * Issued by the Belize Tax Service Department to\n * individuals, sole proprietors, partnerships, and\n * companies. The base number is 6 digits generated\n * by the Revenue Management System. A 2-digit\n * suffix code may be appended to indicate entity\n * type:\n * - 10: individual\n * - 13: company\n * - 66: company (alternate)\n *\n * The OECD spec mentions a 7th check digit that is\n * not visible to the taxpayer; in practice the\n * number circulates as 6 or 8 digits (6 + suffix).\n *\n * Formatted as NNNNNN-SS (when suffix is present).\n *\n * Source: OECD CRS TIN information sheet; Belize\n * Tax Service (https://bts.gov.bz/).\n *\n * PERSON/ENTITY\n *\n * @see https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Belize-TIN.pdf\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\n/** Valid 2-digit suffix codes. */\nconst SUFFIX_CODES = [\"10\", \"13\", \"66\"] as const;\n\nconst compact = (value: string): string => {\n return clean(value, \" -\").trim();\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 6 && v.length !== 8) {\n return err(\n \"INVALID_LENGTH\",\n \"Belize TIN must be 6 or 8 digits\",\n );\n }\n\n if (!/^\\d+$/.test(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Belize TIN must contain only digits\",\n );\n }\n\n if (v.length === 8) {\n const suffix = v.slice(6);\n if (\n !SUFFIX_CODES.includes(\n suffix as (typeof SUFFIX_CODES)[number],\n )\n ) {\n return err(\n \"INVALID_COMPONENT\",\n \"Belize TIN suffix must be 10, 13, or 66\",\n );\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 <= 6) {\n return v;\n }\n return `${v.slice(0, 6)}-${v.slice(6)}`;\n};\n\n/** Generate a random valid Belize TIN. */\nconst generate = (): string => {\n const base = randomDigits(6);\n const suffixes = [\"\", ...SUFFIX_CODES] as const;\n const suffix =\n suffixes[randomInt(0, suffixes.length - 1)] ?? \"\";\n return `${base}${suffix}`;\n};\n\n/**\n * Belize Tax Identification Number.\n *\n * Examples derived from stdnum-js test suite.\n */\nconst tin: Validator = {\n name: \"Belize Tax Identification Number\",\n localName: \"Tax Identification Number\",\n abbreviation: \"TIN\",\n aliases: [\"TIN\"] as const,\n candidatePattern: \"\\\\d{6}\",\n country: \"BZ\",\n entityType: \"any\",\n lengths: [6, 8] as const,\n examples: [\"000005\", \"00000510\", \"00000513\"] as const,\n compact,\n format,\n validate,\n generate,\n description:\n \"Belize tax number issued by the Belize Tax Service Department\",\n sourceUrl:\n \"https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Belize-TIN.pdf\",\n};\n\nexport default tin;\nexport { compact, format, generate, validate };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,MAAM,eAAe;CAAC;CAAM;CAAM;CAAK;AAEvC,MAAM,WAAW,UAA0B;AACzC,QAAO,MAAM,OAAO,KAAK,CAAC,MAAM;;AAGlC,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,KAAK,EAAE,WAAW,EACjC,QAAO,IACL,kBACA,mCACD;AAGH,KAAI,CAAC,QAAQ,KAAK,EAAE,CAClB,QAAO,IACL,kBACA,sCACD;AAGH,KAAI,EAAE,WAAW,GAAG;EAClB,MAAM,SAAS,EAAE,MAAM,EAAE;AACzB,MACE,CAAC,aAAa,SACZ,OACD,CAED,QAAO,IACL,qBACA,0CACD;;AAIL,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,UAAU,EACd,QAAO;AAET,QAAO,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE;;;AAIvC,MAAM,iBAAyB;CAC7B,MAAM,OAAO,aAAa,EAAE;CAC5B,MAAM,WAAW,CAAC,IAAI,GAAG,aAAa;AAGtC,QAAO,GAAG,OADR,SAAS,UAAU,GAAG,SAAS,SAAS,EAAE,KAAK;;;;;;;AASnD,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,MAAM;CAChB,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,GAAG,EAAE;CACf,UAAU;EAAC;EAAU;EAAY;EAAW;CAC5C;CACA;CACA;CACA;CACA,aACE;CACF,WACE;CACH"}
package/dist/ca/bn.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/ca/bn.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/ca/mod.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
1
  import bn from "./bn.js";
3
2
  import sin from "./sin.js";
4
3
 
5
4
  //#region src/ca/mod.d.ts
6
-
5
+ declare namespace mod_d_exports {
6
+ export { bn, sin };
7
+ }
7
8
  //#endregion
8
9
  export { bn, mod_d_exports, sin };
9
10
  //# sourceMappingURL=mod.d.ts.map
package/dist/ca/sin.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/ca/sin.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/ch/mod.d.ts CHANGED
@@ -1,10 +1,11 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
1
  import uid from "./uid.js";
3
2
  import vat from "./vat.js";
4
3
  import ssn from "./ssn.js";
5
4
 
6
5
  //#region src/ch/mod.d.ts
7
-
6
+ declare namespace mod_d_exports {
7
+ export { ssn, uid, vat };
8
+ }
8
9
  //#endregion
9
10
  export { mod_d_exports, ssn, uid, vat };
10
11
  //# sourceMappingURL=mod.d.ts.map
package/dist/ch/ssn.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/ch/ssn.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/ch/uid.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/ch/uid.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/ch/vat.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/ch/vat.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/cl/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/cl/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/cl/rut.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/cl/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/cl/rut.js CHANGED
@@ -39,7 +39,7 @@ const calcCheckDigit = (body) => {
39
39
  7
40
40
  ];
41
41
  let sum = 0;
42
- for (let i = body.length - 1, w = 0; i >= 0; i--, w++) sum += Number(body[i]) * weights[w % 6];
42
+ for (let i = body.length - 1, w = 0; i >= 0; i--, w++) sum += Number(body[i]) * weights[w % weights.length];
43
43
  const remainder = 11 - sum % 11;
44
44
  if (remainder === 11) return "0";
45
45
  if (remainder === 10) return "K";
@@ -1 +1 @@
1
- {"version":3,"file":"rut.js","names":[],"sources":["../../src/cl/rut.ts"],"sourcesContent":["/**\n * RUT (Rol Único Tributario).\n *\n * Chilean tax identification number assigned by the SII\n * (Servicio de Impuestos Internos). The number consists\n * of 7 or 8 digits followed by a check digit (0-9 or K),\n * computed using a modulo 11 algorithm with weights\n * [2, 3, 4, 5, 6, 7] cycling right-to-left.\n *\n * Format: XX.XXX.XXX-C (7-8 digits + check digit).\n *\n * @see https://www.sii.cl/\n * @see https://en.wikipedia.org/wiki/Rol_%C3%9Anico_Tributario\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst RUT_RE = /^\\d{7,8}[\\dK]$/;\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -.\").trim().toUpperCase();\n if (v.startsWith(\"CL\")) v = v.slice(2);\n return v;\n};\n\n/**\n * Compute the RUT check digit using mod 11 with\n * weights [2, 3, 4, 5, 6, 7] cycling right-to-left.\n *\n * remainder = 11 - (weighted sum % 11)\n * 11 -> \"0\", 10 -> \"K\", else the digit as string.\n */\nconst calcCheckDigit = (body: string): string => {\n const weights = [2, 3, 4, 5, 6, 7];\n let sum = 0;\n for (let i = body.length - 1, w = 0; i >= 0; i--, w++) {\n sum += Number(body[i]) * weights[w % 6]!;\n }\n const remainder = 11 - (sum % 11);\n if (remainder === 11) return \"0\";\n if (remainder === 10) return \"K\";\n return String(remainder);\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 8 && v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"RUT must be 8 or 9 characters\",\n );\n }\n\n if (!RUT_RE.test(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"RUT must contain only digits and optionally K\",\n );\n }\n\n const body = v.slice(0, -1);\n const expected = calcCheckDigit(body);\n if (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 const check = v.at(-1);\n const body = v.slice(0, -1);\n return (\n `${body.slice(0, -6)}.${body.slice(-6, -3)}` +\n `.${body.slice(-3)}-${check}`\n );\n};\n\n/** Generate a random valid Chilean RUT. */\nconst generate = (): string => {\n const body = randomDigits(8);\n return body + calcCheckDigit(body);\n};\n\n/**\n * Chilean RUT (tax identification number).\n *\n * Examples sourced from python-stdnum test suite\n * (cl.rut module).\n */\nconst rut: Validator = {\n name: \"Chilean Tax ID\",\n localName: \"Rol Único Tributario\",\n abbreviation: \"RUT\",\n aliases: [\"RUT\", \"Rol Único Tributario\"] as const,\n candidatePattern: \"\\\\d{1,2}\\\\.?\\\\d{3}\\\\.?\\\\d{3}-?[\\\\dkK]\",\n country: \"CL\",\n entityType: \"any\",\n compact,\n format,\n validate,\n sourceUrl: \"https://www.sii.cl/\",\n lengths: [8, 9] as const,\n examples: [\"760864285\", \"125319092\"] as const,\n generate,\n};\n\nexport default rut;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,MAAM,SAAS;AAEf,MAAM,WAAW,UAA0B;CACzC,IAAI,IAAI,MAAM,OAAO,MAAM,CAAC,MAAM,CAAC,aAAa;AAChD,KAAI,EAAE,WAAW,KAAK,CAAE,KAAI,EAAE,MAAM,EAAE;AACtC,QAAO;;;;;;;;;AAUT,MAAM,kBAAkB,SAAyB;CAC/C,MAAM,UAAU;EAAC;EAAG;EAAG;EAAG;EAAG;EAAG;EAAE;CAClC,IAAI,MAAM;AACV,MAAK,IAAI,IAAI,KAAK,SAAS,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,IAChD,QAAO,OAAO,KAAK,GAAG,GAAG,QAAQ,IAAI;CAEvC,MAAM,YAAY,KAAM,MAAM;AAC9B,KAAI,cAAc,GAAI,QAAO;AAC7B,KAAI,cAAc,GAAI,QAAO;AAC7B,QAAO,OAAO,UAAU;;AAG1B,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,KAAK,EAAE,WAAW,EACjC,QAAO,IACL,kBACA,gCACD;AAGH,KAAI,CAAC,OAAO,KAAK,EAAE,CACjB,QAAO,IACL,kBACA,gDACD;CAIH,MAAM,WAAW,eADJ,EAAE,MAAM,GAAG,GAAG,CACU;AACrC,KAAI,EAAE,GAAG,GAAG,KAAK,SACf,QAAO,IACL,oBACA,iCACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;CACxB,MAAM,QAAQ,EAAE,GAAG,GAAG;CACtB,MAAM,OAAO,EAAE,MAAM,GAAG,GAAG;AAC3B,QACE,GAAG,KAAK,MAAM,GAAG,GAAG,CAAC,GAAG,KAAK,MAAM,IAAI,GAAG,CAAA,GACtC,KAAK,MAAM,GAAG,CAAC,GAAG;;;AAK1B,MAAM,iBAAyB;CAC7B,MAAM,OAAO,aAAa,EAAE;AAC5B,QAAO,OAAO,eAAe,KAAK;;;;;;;;AASpC,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,OAAO,uBAAuB;CACxC,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ;CACA;CACA;CACA,WAAW;CACX,SAAS,CAAC,GAAG,EAAE;CACf,UAAU,CAAC,aAAa,YAAY;CACpC;CACD"}
1
+ {"version":3,"file":"rut.js","names":[],"sources":["../../src/cl/rut.ts"],"sourcesContent":["/**\n * RUT (Rol Único Tributario).\n *\n * Chilean tax identification number assigned by the SII\n * (Servicio de Impuestos Internos). The number consists\n * of 7 or 8 digits followed by a check digit (0-9 or K),\n * computed using a modulo 11 algorithm with weights\n * [2, 3, 4, 5, 6, 7] cycling right-to-left.\n *\n * Format: XX.XXX.XXX-C (7-8 digits + check digit).\n *\n * @see https://www.sii.cl/\n * @see https://en.wikipedia.org/wiki/Rol_%C3%9Anico_Tributario\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst RUT_RE = /^\\d{7,8}[\\dK]$/;\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -.\").trim().toUpperCase();\n if (v.startsWith(\"CL\")) v = v.slice(2);\n return v;\n};\n\n/**\n * Compute the RUT check digit using mod 11 with\n * weights [2, 3, 4, 5, 6, 7] cycling right-to-left.\n *\n * remainder = 11 - (weighted sum % 11)\n * 11 -> \"0\", 10 -> \"K\", else the digit as string.\n */\nconst calcCheckDigit = (body: string): string => {\n const weights = [2, 3, 4, 5, 6, 7] as const;\n let sum = 0;\n for (let i = body.length - 1, w = 0; i >= 0; i--, w++) {\n // SAFETY: w % weights.length is a valid index.\n // eslint-disable-next-line no-non-null-assertion\n sum += Number(body[i]) * weights[w % weights.length]!;\n }\n const remainder = 11 - (sum % 11);\n if (remainder === 11) return \"0\";\n if (remainder === 10) return \"K\";\n return String(remainder);\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 8 && v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"RUT must be 8 or 9 characters\",\n );\n }\n\n if (!RUT_RE.test(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"RUT must contain only digits and optionally K\",\n );\n }\n\n const body = v.slice(0, -1);\n const expected = calcCheckDigit(body);\n if (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 const check = v.at(-1);\n const body = v.slice(0, -1);\n return (\n `${body.slice(0, -6)}.${body.slice(-6, -3)}` +\n `.${body.slice(-3)}-${check}`\n );\n};\n\n/** Generate a random valid Chilean RUT. */\nconst generate = (): string => {\n const body = randomDigits(8);\n return body + calcCheckDigit(body);\n};\n\n/**\n * Chilean RUT (tax identification number).\n *\n * Examples sourced from python-stdnum test suite\n * (cl.rut module).\n */\nconst rut: Validator = {\n name: \"Chilean Tax ID\",\n localName: \"Rol Único Tributario\",\n abbreviation: \"RUT\",\n aliases: [\"RUT\", \"Rol Único Tributario\"] as const,\n candidatePattern: \"\\\\d{1,2}\\\\.?\\\\d{3}\\\\.?\\\\d{3}-?[\\\\dkK]\",\n country: \"CL\",\n entityType: \"any\",\n compact,\n format,\n validate,\n sourceUrl: \"https://www.sii.cl/\",\n lengths: [8, 9] as const,\n examples: [\"760864285\", \"125319092\"] as const,\n generate,\n};\n\nexport default rut;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,MAAM,SAAS;AAEf,MAAM,WAAW,UAA0B;CACzC,IAAI,IAAI,MAAM,OAAO,MAAM,CAAC,MAAM,CAAC,aAAa;AAChD,KAAI,EAAE,WAAW,KAAK,CAAE,KAAI,EAAE,MAAM,EAAE;AACtC,QAAO;;;;;;;;;AAUT,MAAM,kBAAkB,SAAyB;CAC/C,MAAM,UAAU;EAAC;EAAG;EAAG;EAAG;EAAG;EAAG;EAAE;CAClC,IAAI,MAAM;AACV,MAAK,IAAI,IAAI,KAAK,SAAS,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,IAGhD,QAAO,OAAO,KAAK,GAAG,GAAG,QAAQ,IAAI,QAAQ;CAE/C,MAAM,YAAY,KAAM,MAAM;AAC9B,KAAI,cAAc,GAAI,QAAO;AAC7B,KAAI,cAAc,GAAI,QAAO;AAC7B,QAAO,OAAO,UAAU;;AAG1B,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,KAAK,EAAE,WAAW,EACjC,QAAO,IACL,kBACA,gCACD;AAGH,KAAI,CAAC,OAAO,KAAK,EAAE,CACjB,QAAO,IACL,kBACA,gDACD;CAIH,MAAM,WAAW,eADJ,EAAE,MAAM,GAAG,GAAG,CACU;AACrC,KAAI,EAAE,GAAG,GAAG,KAAK,SACf,QAAO,IACL,oBACA,iCACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;CACxB,MAAM,QAAQ,EAAE,GAAG,GAAG;CACtB,MAAM,OAAO,EAAE,MAAM,GAAG,GAAG;AAC3B,QACE,GAAG,KAAK,MAAM,GAAG,GAAG,CAAC,GAAG,KAAK,MAAM,IAAI,GAAG,CAAA,GACtC,KAAK,MAAM,GAAG,CAAC,GAAG;;;AAK1B,MAAM,iBAAyB;CAC7B,MAAM,OAAO,aAAa,EAAE;AAC5B,QAAO,OAAO,eAAe,KAAK;;;;;;;;AASpC,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,OAAO,uBAAuB;CACxC,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ;CACA;CACA;CACA,WAAW;CACX,SAAS,CAAC,GAAG,EAAE;CACf,UAAU,CAAC,aAAa,YAAY;CACpC;CACD"}
package/dist/cn/mod.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
1
  import ric from "./ric.js";
3
2
  import uscc from "./uscc.js";
4
3
 
5
4
  //#region src/cn/mod.d.ts
6
-
5
+ declare namespace mod_d_exports {
6
+ export { ric, uscc };
7
+ }
7
8
  //#endregion
8
9
  export { mod_d_exports, ric, uscc };
9
10
  //# sourceMappingURL=mod.d.ts.map
package/dist/cn/ric.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ParsedPersonId, ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/cn/ric.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;
@@ -13,7 +12,7 @@ declare const parse: (value: string) => ParsedPersonId | null;
13
12
  /** Generate a random valid 18-digit RIC. */
14
13
  declare const generate: () => string;
15
14
  /** Chinese Resident Identity Card number. */
16
- declare const ric: Validator;
15
+ declare const ric: Validator<ParsedPersonId>;
17
16
  //#endregion
18
17
  export { compact, ric as default, format, generate, parse, validate };
19
18
  //# sourceMappingURL=ric.d.ts.map
package/dist/cn/ric.js CHANGED
@@ -99,6 +99,7 @@ const ric = {
99
99
  examples: ["11010519491231002X", "440524188001010014"],
100
100
  compact,
101
101
  format,
102
+ parse,
102
103
  validate,
103
104
  generate
104
105
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ric.js","names":[],"sources":["../../src/cn/ric.ts"],"sourcesContent":["/**\n * RIC (Resident Identity Card number, 居民身份证号码).\n *\n * Chinese national identifier. 18 characters:\n * 6 (area code) + 8 (YYYYMMDD birth) + 3 (sequence,\n * odd = male) + 1 (check, 0-9 or X).\n *\n * Also accepts the legacy 15-digit format (no check\n * digit, 2-digit year).\n *\n * @see https://en.wikipedia.org/wiki/Resident_Identity_Card\n */\n\nimport {\n mod112checkChar,\n mod112validate,\n} from \"#checksums/mod112\";\nimport { clean } from \"#util/clean\";\nimport { isValidDate } from \"#util/date\";\nimport { randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type {\n ParsedPersonId,\n ValidateResult,\n Validator,\n} from \"../types\";\n\nconst compact = (value: string): string =>\n clean(value, \" -\").toUpperCase();\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 15 && v.length !== 18) {\n return err(\n \"INVALID_LENGTH\",\n \"RIC must be 15 or 18 characters\",\n );\n }\n\n if (v.length === 15) {\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"15-digit RIC must contain only digits\",\n );\n }\n // Validate date: digits 6-11 are YYMMDD\n const year = 1900 + Number(v.slice(6, 8));\n const month = Number(v.slice(8, 10));\n const day = Number(v.slice(10, 12));\n if (!isValidDate(year, month, day)) {\n return err(\n \"INVALID_COMPONENT\",\n \"RIC contains an invalid birth date\",\n );\n }\n return { valid: true, compact: v };\n }\n\n // 18-character format\n if (!isdigits(v.slice(0, 17))) {\n return err(\n \"INVALID_FORMAT\",\n \"RIC must contain only digits (plus check char)\",\n );\n }\n const lastChar = v[17]!;\n if (!isdigits(lastChar) && lastChar !== \"X\") {\n return err(\n \"INVALID_FORMAT\",\n \"RIC check character must be 0-9 or X\",\n );\n }\n\n // Validate date: digits 6-13 are YYYYMMDD\n const year = Number(v.slice(6, 10));\n const month = Number(v.slice(10, 12));\n const day = Number(v.slice(12, 14));\n if (!isValidDate(year, month, day)) {\n return err(\n \"INVALID_COMPONENT\",\n \"RIC contains an invalid birth date\",\n );\n }\n\n if (!mod112validate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"RIC check character does not match\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/**\n * Extract birth date and gender from an RIC number.\n * Returns null if the value is not valid.\n */\nconst parse = (value: string): ParsedPersonId | null => {\n const result = validate(value);\n if (!result.valid) return null;\n\n const v = result.compact;\n\n let year: number;\n let month: number;\n let day: number;\n let seq: number;\n\n if (v.length === 15) {\n year = 1900 + Number(v.slice(6, 8));\n month = Number(v.slice(8, 10));\n day = Number(v.slice(10, 12));\n seq = Number(v.slice(12, 15));\n } else {\n year = Number(v.slice(6, 10));\n month = Number(v.slice(10, 12));\n day = Number(v.slice(12, 14));\n seq = Number(v.slice(14, 17));\n }\n\n const gender = seq % 2 === 1 ? \"male\" : \"female\";\n\n return {\n birthDate: new Date(year, month - 1, day),\n gender,\n };\n};\n\n/** Generate a random valid 18-digit RIC. */\nconst generate = (): string => {\n // Use a simple area code prefix\n const area = String(randomInt(110000, 659999));\n const year = randomInt(1950, 2005);\n const month = randomInt(1, 12);\n const day = randomInt(1, 28);\n const seqNum = randomInt(1, 999);\n const seq = String(seqNum).padStart(3, \"0\");\n\n const yStr = String(year);\n const mStr = String(month).padStart(2, \"0\");\n const dStr = String(day).padStart(2, \"0\");\n\n const payload = `${area}${yStr}${mStr}${dStr}${seq}`;\n const check = mod112checkChar(payload);\n return `${payload}${check}`;\n};\n\n/** Chinese Resident Identity Card number. */\nconst ric: Validator = {\n name: \"Chinese Resident Identity Card\",\n localName: \"居民身份证号码\",\n abbreviation: \"RIC\",\n aliases: [\"身份证\", \"居民身份证号码\", \"RIC\"] as const,\n candidatePattern: \"\\\\d{17}[\\\\dX]\",\n country: \"CN\",\n entityType: \"person\",\n description:\n \"18-character national ID encoding area, birth date, gender, and check digit\",\n sourceUrl:\n \"https://en.wikipedia.org/wiki/Resident_Identity_Card\",\n lengths: [15, 18] as const,\n examples: [\n \"11010519491231002X\",\n \"440524188001010014\",\n ] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default ric;\nexport { compact, format, generate, parse, validate };\n"],"mappings":"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"}
1
+ {"version":3,"file":"ric.js","names":[],"sources":["../../src/cn/ric.ts"],"sourcesContent":["/**\n * RIC (Resident Identity Card number, 居民身份证号码).\n *\n * Chinese national identifier. 18 characters:\n * 6 (area code) + 8 (YYYYMMDD birth) + 3 (sequence,\n * odd = male) + 1 (check, 0-9 or X).\n *\n * Also accepts the legacy 15-digit format (no check\n * digit, 2-digit year).\n *\n * @see https://en.wikipedia.org/wiki/Resident_Identity_Card\n */\n\nimport {\n mod112checkChar,\n mod112validate,\n} from \"#checksums/mod112\";\nimport { clean } from \"#util/clean\";\nimport { isValidDate } from \"#util/date\";\nimport { randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type {\n ParsedPersonId,\n ValidateResult,\n Validator,\n} from \"../types\";\n\nconst compact = (value: string): string =>\n clean(value, \" -\").toUpperCase();\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 15 && v.length !== 18) {\n return err(\n \"INVALID_LENGTH\",\n \"RIC must be 15 or 18 characters\",\n );\n }\n\n if (v.length === 15) {\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"15-digit RIC must contain only digits\",\n );\n }\n // Validate date: digits 6-11 are YYMMDD\n const year = 1900 + Number(v.slice(6, 8));\n const month = Number(v.slice(8, 10));\n const day = Number(v.slice(10, 12));\n if (!isValidDate(year, month, day)) {\n return err(\n \"INVALID_COMPONENT\",\n \"RIC contains an invalid birth date\",\n );\n }\n return { valid: true, compact: v };\n }\n\n // 18-character format\n if (!isdigits(v.slice(0, 17))) {\n return err(\n \"INVALID_FORMAT\",\n \"RIC must contain only digits (plus check char)\",\n );\n }\n // SAFETY: 18-character branch guarantees v[17] exists.\n // eslint-disable-next-line no-non-null-assertion\n const lastChar = v[17]!;\n if (!isdigits(lastChar) && lastChar !== \"X\") {\n return err(\n \"INVALID_FORMAT\",\n \"RIC check character must be 0-9 or X\",\n );\n }\n\n // Validate date: digits 6-13 are YYYYMMDD\n const year = Number(v.slice(6, 10));\n const month = Number(v.slice(10, 12));\n const day = Number(v.slice(12, 14));\n if (!isValidDate(year, month, day)) {\n return err(\n \"INVALID_COMPONENT\",\n \"RIC contains an invalid birth date\",\n );\n }\n\n if (!mod112validate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"RIC check character does not match\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/**\n * Extract birth date and gender from an RIC number.\n * Returns null if the value is not valid.\n */\nconst parse = (value: string): ParsedPersonId | null => {\n const result = validate(value);\n if (!result.valid) return null;\n\n const v = result.compact;\n\n let year: number;\n let month: number;\n let day: number;\n let seq: number;\n\n if (v.length === 15) {\n year = 1900 + Number(v.slice(6, 8));\n month = Number(v.slice(8, 10));\n day = Number(v.slice(10, 12));\n seq = Number(v.slice(12, 15));\n } else {\n year = Number(v.slice(6, 10));\n month = Number(v.slice(10, 12));\n day = Number(v.slice(12, 14));\n seq = Number(v.slice(14, 17));\n }\n\n const gender = seq % 2 === 1 ? \"male\" : \"female\";\n\n return {\n birthDate: new Date(year, month - 1, day),\n gender,\n };\n};\n\n/** Generate a random valid 18-digit RIC. */\nconst generate = (): string => {\n // Use a simple area code prefix\n const area = String(randomInt(110000, 659999));\n const year = randomInt(1950, 2005);\n const month = randomInt(1, 12);\n const day = randomInt(1, 28);\n const seqNum = randomInt(1, 999);\n const seq = String(seqNum).padStart(3, \"0\");\n\n const yStr = String(year);\n const mStr = String(month).padStart(2, \"0\");\n const dStr = String(day).padStart(2, \"0\");\n\n const payload = `${area}${yStr}${mStr}${dStr}${seq}`;\n const check = mod112checkChar(payload);\n return `${payload}${check}`;\n};\n\n/** Chinese Resident Identity Card number. */\nconst ric: Validator<ParsedPersonId> = {\n name: \"Chinese Resident Identity Card\",\n localName: \"居民身份证号码\",\n abbreviation: \"RIC\",\n aliases: [\"身份证\", \"居民身份证号码\", \"RIC\"] as const,\n candidatePattern: \"\\\\d{17}[\\\\dX]\",\n country: \"CN\",\n entityType: \"person\",\n description:\n \"18-character national ID encoding area, birth date, gender, and check digit\",\n sourceUrl:\n \"https://en.wikipedia.org/wiki/Resident_Identity_Card\",\n lengths: [15, 18] as const,\n examples: [\n \"11010519491231002X\",\n \"440524188001010014\",\n ] as const,\n compact,\n format,\n parse,\n validate,\n generate,\n};\n\nexport default ric;\nexport { compact, format, generate, parse, validate };\n"],"mappings":"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"}
package/dist/cn/uscc.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/cn/uscc.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/cn/uscc.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { clean } from "../_util/clean.js";
2
- import { randomDigits, randomInt } from "../_util/generate.js";
2
+ import { randomChar, randomDigits, randomInt } from "../_util/generate.js";
3
3
  import { err } from "../_util/result.js";
4
4
  import { isdigits } from "../_util/strings.js";
5
5
  //#region src/cn/uscc.ts
@@ -36,16 +36,17 @@ const WEIGHTS = [
36
36
  const compact = (value) => clean(value, " -").toUpperCase();
37
37
  const calcCheckChar = (value) => {
38
38
  let total = 0;
39
- for (let i = 0; i < 17; i++) {
40
- const idx = ALPHABET.indexOf(value[i]);
41
- total += idx * WEIGHTS[i];
39
+ for (const [i, weight] of WEIGHTS.entries()) {
40
+ const ch = value[i];
41
+ if (ch === void 0) continue;
42
+ total += ALPHABET.indexOf(ch) * weight;
42
43
  }
43
44
  return ALPHABET[(31 - total % 31) % 31];
44
45
  };
45
46
  const validate = (value) => {
46
47
  const v = compact(value);
47
48
  if (v.length !== 18) return err("INVALID_LENGTH", "USCC must be 18 characters");
48
- for (let i = 0; i < 18; i++) if (!ALPHABET.includes(v[i])) return err("INVALID_FORMAT", "USCC contains invalid character");
49
+ for (const ch of v) if (!ALPHABET.includes(ch)) return err("INVALID_FORMAT", "USCC contains invalid character");
49
50
  if (!isdigits(v.slice(2, 8))) return err("INVALID_FORMAT", "USCC region code (positions 3-8) must be digits");
50
51
  if (v[17] !== calcCheckChar(v)) return err("INVALID_CHECKSUM", "USCC check character does not match");
51
52
  return {
@@ -60,7 +61,7 @@ const generate = () => {
60
61
  const etype = ALPHABET[randomInt(1, 9)];
61
62
  const region = randomDigits(6);
62
63
  let org = "";
63
- for (let i = 0; i < 9; i++) org += ALPHABET[randomInt(0, 30)];
64
+ for (let i = 0; i < 9; i++) org += randomChar(ALPHABET);
64
65
  const payload = reg + etype + region + org;
65
66
  return payload + calcCheckChar(payload);
66
67
  };
@@ -1 +1 @@
1
- {"version":3,"file":"uscc.js","names":[],"sources":["../../src/cn/uscc.ts"],"sourcesContent":["/**\n * USCC (Unified Social Credit Code, 统一社会信用代码).\n *\n * 18 alphanumeric characters (excluding I, O, Z, S, V):\n * 1 (registering authority) + 1 (entity type) +\n * 6 (region code, digits only) + 9 (organisation code) +\n * 1 (mod 31 check character).\n *\n * @see https://zh.wikipedia.org/wiki/统一社会信用代码\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 ALPHABET = \"0123456789ABCDEFGHJKLMNPQRTUWXY\";\n\nconst WEIGHTS = [\n 1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10,\n 30, 28,\n] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -\").toUpperCase();\n\nconst calcCheckChar = (value: string): string => {\n let total = 0;\n for (let i = 0; i < 17; i++) {\n const idx = ALPHABET.indexOf(value[i]!);\n total += idx * WEIGHTS[i]!;\n }\n return ALPHABET[(31 - (total % 31)) % 31]!;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 18) {\n return err(\n \"INVALID_LENGTH\",\n \"USCC must be 18 characters\",\n );\n }\n\n for (let i = 0; i < 18; i++) {\n if (!ALPHABET.includes(v[i]!)) {\n return err(\n \"INVALID_FORMAT\",\n \"USCC contains invalid character\",\n );\n }\n }\n\n if (!isdigits(v.slice(2, 8))) {\n return err(\n \"INVALID_FORMAT\",\n \"USCC region code (positions 3-8) must be digits\",\n );\n }\n\n if (v[17] !== calcCheckChar(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"USCC check character does not match\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid USCC. */\nconst generate = (): string => {\n const reg = ALPHABET[randomInt(1, 9)]!;\n const etype = ALPHABET[randomInt(1, 9)]!;\n const region = randomDigits(6);\n let org = \"\";\n for (let i = 0; i < 9; i++)\n org += ALPHABET[randomInt(0, ALPHABET.length - 1)]!;\n const payload = reg + etype + region + org;\n return payload + calcCheckChar(payload);\n};\n\n/** Chinese Unified Social Credit Code. */\nconst uscc: Validator = {\n name: \"Unified Social Credit Code\",\n localName: \"统一社会信用代码\",\n abbreviation: \"USCC\",\n aliases: [\"统一社会信用代码\", \"USCC\"] as const,\n candidatePattern:\n \"[0-9A-HJ-NP-RTUW-Y]{2}\\\\d{6}[0-9A-HJ-NP-RTUW-Y]{10}\",\n country: \"CN\",\n entityType: \"company\",\n description:\n \"18-character tax/registration code for Chinese entities\",\n sourceUrl:\n \"https://zh.wikipedia.org/wiki/统一社会信用代码\",\n lengths: [18] as const,\n examples: [\"91110000600037341L\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default uscc;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,MAAM,WAAW;AAEjB,MAAM,UAAU;CACd;CAAG;CAAG;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAI;CACpD;CAAI;CACL;AAED,MAAM,WAAW,UACf,MAAM,OAAO,KAAK,CAAC,aAAa;AAElC,MAAM,iBAAiB,UAA0B;CAC/C,IAAI,QAAQ;AACZ,MAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;EAC3B,MAAM,MAAM,SAAS,QAAQ,MAAM,GAAI;AACvC,WAAS,MAAM,QAAQ;;AAEzB,QAAO,UAAU,KAAM,QAAQ,MAAO;;AAGxC,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,GACf,QAAO,IACL,kBACA,6BACD;AAGH,MAAK,IAAI,IAAI,GAAG,IAAI,IAAI,IACtB,KAAI,CAAC,SAAS,SAAS,EAAE,GAAI,CAC3B,QAAO,IACL,kBACA,kCACD;AAIL,KAAI,CAAC,SAAS,EAAE,MAAM,GAAG,EAAE,CAAC,CAC1B,QAAO,IACL,kBACA,kDACD;AAGH,KAAI,EAAE,QAAQ,cAAc,EAAE,CAC5B,QAAO,IACL,oBACA,sCACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B,QAAQ,MAAM;;AAGxD,MAAM,iBAAyB;CAC7B,MAAM,MAAM,SAAS,UAAU,GAAG,EAAE;CACpC,MAAM,QAAQ,SAAS,UAAU,GAAG,EAAE;CACtC,MAAM,SAAS,aAAa,EAAE;CAC9B,IAAI,MAAM;AACV,MAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IACrB,QAAO,SAAS,UAAU,GAAG,GAAoB;CACnD,MAAM,UAAU,MAAM,QAAQ,SAAS;AACvC,QAAO,UAAU,cAAc,QAAQ;;;AAIzC,MAAM,OAAkB;CACtB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,YAAY,OAAO;CAC7B,kBACE;CACF,SAAS;CACT,YAAY;CACZ,aACE;CACF,WACE;CACF,SAAS,CAAC,GAAG;CACb,UAAU,CAAC,qBAAqB;CAChC;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"uscc.js","names":[],"sources":["../../src/cn/uscc.ts"],"sourcesContent":["/**\n * USCC (Unified Social Credit Code, 统一社会信用代码).\n *\n * 18 alphanumeric characters (excluding I, O, Z, S, V):\n * 1 (registering authority) + 1 (entity type) +\n * 6 (region code, digits only) + 9 (organisation code) +\n * 1 (mod 31 check character).\n *\n * @see https://zh.wikipedia.org/wiki/统一社会信用代码\n */\n\nimport { clean } from \"#util/clean\";\nimport {\n randomChar,\n randomDigits,\n randomInt,\n} from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst ALPHABET = \"0123456789ABCDEFGHJKLMNPQRTUWXY\";\n\nconst WEIGHTS = [\n 1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10,\n 30, 28,\n] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -\").toUpperCase();\n\nconst calcCheckChar = (value: string): string => {\n let total = 0;\n for (const [i, weight] of WEIGHTS.entries()) {\n const ch = value[i];\n if (ch === undefined) continue;\n total += ALPHABET.indexOf(ch) * weight;\n }\n // SAFETY: (31 - total % 31) % 31 is in 0..30 and\n // ALPHABET has 31 characters.\n // eslint-disable-next-line no-non-null-assertion\n return ALPHABET[(31 - (total % 31)) % 31]!;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 18) {\n return err(\n \"INVALID_LENGTH\",\n \"USCC must be 18 characters\",\n );\n }\n\n for (const ch of v) {\n if (!ALPHABET.includes(ch)) {\n return err(\n \"INVALID_FORMAT\",\n \"USCC contains invalid character\",\n );\n }\n }\n\n if (!isdigits(v.slice(2, 8))) {\n return err(\n \"INVALID_FORMAT\",\n \"USCC region code (positions 3-8) must be digits\",\n );\n }\n\n if (v[17] !== calcCheckChar(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"USCC check character does not match\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid USCC. */\nconst generate = (): string => {\n // SAFETY: indices 1..9 are within ALPHABET (31 chars).\n // eslint-disable-next-line no-non-null-assertion\n const reg = ALPHABET[randomInt(1, 9)]!;\n // eslint-disable-next-line no-non-null-assertion\n const etype = ALPHABET[randomInt(1, 9)]!;\n const region = randomDigits(6);\n let org = \"\";\n for (let i = 0; i < 9; i++) {\n org += randomChar(ALPHABET);\n }\n const payload = reg + etype + region + org;\n return payload + calcCheckChar(payload);\n};\n\n/** Chinese Unified Social Credit Code. */\nconst uscc: Validator = {\n name: \"Unified Social Credit Code\",\n localName: \"统一社会信用代码\",\n abbreviation: \"USCC\",\n aliases: [\"统一社会信用代码\", \"USCC\"] as const,\n candidatePattern:\n \"[0-9A-HJ-NP-RTUW-Y]{2}\\\\d{6}[0-9A-HJ-NP-RTUW-Y]{10}\",\n country: \"CN\",\n entityType: \"company\",\n description:\n \"18-character tax/registration code for Chinese entities\",\n sourceUrl:\n \"https://zh.wikipedia.org/wiki/统一社会信用代码\",\n lengths: [18] as const,\n examples: [\"91110000600037341L\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default uscc;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;AAsBA,MAAM,WAAW;AAEjB,MAAM,UAAU;CACd;CAAG;CAAG;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAI;CACpD;CAAI;CACL;AAED,MAAM,WAAW,UACf,MAAM,OAAO,KAAK,CAAC,aAAa;AAElC,MAAM,iBAAiB,UAA0B;CAC/C,IAAI,QAAQ;AACZ,MAAK,MAAM,CAAC,GAAG,WAAW,QAAQ,SAAS,EAAE;EAC3C,MAAM,KAAK,MAAM;AACjB,MAAI,OAAO,KAAA,EAAW;AACtB,WAAS,SAAS,QAAQ,GAAG,GAAG;;AAKlC,QAAO,UAAU,KAAM,QAAQ,MAAO;;AAGxC,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,GACf,QAAO,IACL,kBACA,6BACD;AAGH,MAAK,MAAM,MAAM,EACf,KAAI,CAAC,SAAS,SAAS,GAAG,CACxB,QAAO,IACL,kBACA,kCACD;AAIL,KAAI,CAAC,SAAS,EAAE,MAAM,GAAG,EAAE,CAAC,CAC1B,QAAO,IACL,kBACA,kDACD;AAGH,KAAI,EAAE,QAAQ,cAAc,EAAE,CAC5B,QAAO,IACL,oBACA,sCACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B,QAAQ,MAAM;;AAGxD,MAAM,iBAAyB;CAG7B,MAAM,MAAM,SAAS,UAAU,GAAG,EAAE;CAEpC,MAAM,QAAQ,SAAS,UAAU,GAAG,EAAE;CACtC,MAAM,SAAS,aAAa,EAAE;CAC9B,IAAI,MAAM;AACV,MAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IACrB,QAAO,WAAW,SAAS;CAE7B,MAAM,UAAU,MAAM,QAAQ,SAAS;AACvC,QAAO,UAAU,cAAc,QAAQ;;;AAIzC,MAAM,OAAkB;CACtB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,YAAY,OAAO;CAC7B,kBACE;CACF,SAAS;CACT,YAAY;CACZ,aACE;CACF,WACE;CACF,SAAS,CAAC,GAAG;CACb,UAAU,CAAC,qBAAqB;CAChC;CACA;CACA;CACA;CACD"}
package/dist/co/mod.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
1
  import nit from "./nit.js";
3
2
 
4
3
  //#region src/co/mod.d.ts
5
-
4
+ declare namespace mod_d_exports {
5
+ export { nit };
6
+ }
6
7
  //#endregion
7
8
  export { mod_d_exports, nit };
8
9
  //# sourceMappingURL=mod.d.ts.map
package/dist/co/nit.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/co/nit.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/co/nit.js CHANGED
@@ -49,7 +49,10 @@ const compact = (value) => clean(value, " -.,");
49
49
  const calcCheckDigit = (body) => {
50
50
  let sum = 0;
51
51
  const len = body.length;
52
- for (let i = 0; i < len; i++) sum += Number(body[len - 1 - i]) * WEIGHTS[i];
52
+ for (const [i, weight] of WEIGHTS.entries()) {
53
+ if (i >= len) break;
54
+ sum += Number(body[len - 1 - i]) * weight;
55
+ }
53
56
  return CHECK_DIGITS[sum % 11];
54
57
  };
55
58
  const validate = (value) => {
@@ -1 +1 @@
1
- {"version":3,"file":"nit.js","names":[],"sources":["../../src/co/nit.ts"],"sourcesContent":["/**\n * NIT (Número de Identificación Tributaria).\n *\n * Colombian tax identification number, also known as\n * RUT (Registro Unico Tributario). The last digit is\n * a check digit computed via a weighted sum mod 11\n * with weights [3,7,13,17,19,23,29,37,41,43,47,53,\n * 59,67,71] applied right-to-left.\n *\n * @see https://es.wikipedia.org/wiki/Número_de_identificación_tributaria\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 = [\n 3, 7, 13, 17, 19, 23, 29, 37, 41, 43, 47, 53, 59, 67, 71,\n] as const;\n\n/** Lookup table: remainder -> check digit. */\nconst CHECK_DIGITS = [0, 1, 9, 8, 7, 6, 5, 4, 3, 2, 1];\n\nconst compact = (value: string): string =>\n clean(value, \" -.,\");\n\nconst calcCheckDigit = (body: string): number => {\n let sum = 0;\n const len = body.length;\n for (let i = 0; i < len; i++) {\n sum += Number(body[len - 1 - i]) * WEIGHTS[i]!;\n }\n return CHECK_DIGITS[sum % 11]!;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length < 8 || v.length > 16) {\n return err(\n \"INVALID_LENGTH\",\n \"NIT must be between 8 and 16 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"NIT must contain only digits\",\n );\n }\n\n const body = v.slice(0, -1);\n const check = calcCheckDigit(body);\n if (check !== Number(v[v.length - 1])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"NIT 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 const body = v.slice(0, -1);\n const checkChar = v.slice(-1);\n const groups: string[] = [];\n for (let i = body.length; i > 0; i -= 3) {\n groups.unshift(body.slice(Math.max(0, i - 3), i));\n }\n return `${groups.join(\".\")}-${checkChar}`;\n};\n\n/** Generate a random valid NIT (10 digits). */\nconst generate = (): string => {\n const body = randomDigits(9);\n const check = calcCheckDigit(body);\n return `${body}${check}`;\n};\n\n/** Colombian tax identification number. */\nconst nit: Validator = {\n name: \"Número de Identificación Tributaria\",\n localName: \"Número de Identificación Tributaria\",\n abbreviation: \"NIT\",\n aliases: [\n \"NIT\",\n \"Número de Identificación Tributaria\",\n ] as const,\n candidatePattern: \"\\\\d{9,10}-?\\\\d\",\n country: \"CO\",\n entityType: \"any\",\n description: \"Tax identifier issued by the DIAN\",\n sourceUrl:\n \"https://es.wikipedia.org/wiki/N%C3%BAmero_de_identificaci%C3%B3n_tributaria\",\n lengths: [8, 9, 10, 11, 12, 13, 14, 15, 16] as const,\n examples: [\"2131234321\", \"8001234565\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default nit;\nexport { compact, format, generate, validate };\n"],"mappings":";;;;;;;;;;;;;;;;AAmBA,MAAM,UAAU;CACd;CAAG;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CACvD;;AAGD,MAAM,eAAe;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAEtD,MAAM,WAAW,UACf,MAAM,OAAO,OAAO;AAEtB,MAAM,kBAAkB,SAAyB;CAC/C,IAAI,MAAM;CACV,MAAM,MAAM,KAAK;AACjB,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,IACvB,QAAO,OAAO,KAAK,MAAM,IAAI,GAAG,GAAG,QAAQ;AAE7C,QAAO,aAAa,MAAM;;AAG5B,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,SAAS,KAAK,EAAE,SAAS,GAC7B,QAAO,IACL,kBACA,sCACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,+BACD;AAKH,KADc,eADD,EAAE,MAAM,GAAG,GAAG,CACO,KACpB,OAAO,EAAE,EAAE,SAAS,GAAG,CACnC,QAAO,IACL,oBACA,iCACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;CACxB,MAAM,OAAO,EAAE,MAAM,GAAG,GAAG;CAC3B,MAAM,YAAY,EAAE,MAAM,GAAG;CAC7B,MAAM,SAAmB,EAAE;AAC3B,MAAK,IAAI,IAAI,KAAK,QAAQ,IAAI,GAAG,KAAK,EACpC,QAAO,QAAQ,KAAK,MAAM,KAAK,IAAI,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC;AAEnD,QAAO,GAAG,OAAO,KAAK,IAAI,CAAC,GAAG;;;AAIhC,MAAM,iBAAyB;CAC7B,MAAM,OAAO,aAAa,EAAE;AAE5B,QAAO,GAAG,OADI,eAAe,KAAK;;;AAKpC,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CACP,OACA,sCACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,aAAa;CACb,WACE;CACF,SAAS;EAAC;EAAG;EAAG;EAAI;EAAI;EAAI;EAAI;EAAI;EAAI;EAAG;CAC3C,UAAU,CAAC,cAAc,aAAa;CACtC;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"nit.js","names":[],"sources":["../../src/co/nit.ts"],"sourcesContent":["/**\n * NIT (Número de Identificación Tributaria).\n *\n * Colombian tax identification number, also known as\n * RUT (Registro Unico Tributario). The last digit is\n * a check digit computed via a weighted sum mod 11\n * with weights [3,7,13,17,19,23,29,37,41,43,47,53,\n * 59,67,71] applied right-to-left.\n *\n * @see https://es.wikipedia.org/wiki/Número_de_identificación_tributaria\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 = [\n 3, 7, 13, 17, 19, 23, 29, 37, 41, 43, 47, 53, 59, 67, 71,\n] as const;\n\n/** Lookup table: remainder -> check digit. */\nconst CHECK_DIGITS = [0, 1, 9, 8, 7, 6, 5, 4, 3, 2, 1];\n\nconst compact = (value: string): string =>\n clean(value, \" -.,\");\n\nconst calcCheckDigit = (body: string): number => {\n let sum = 0;\n const len = body.length;\n for (const [i, weight] of WEIGHTS.entries()) {\n if (i >= len) break;\n sum += Number(body[len - 1 - i]) * weight;\n }\n // SAFETY: sum % 11 is in 0..10 and CHECK_DIGITS has\n // 11 entries.\n // eslint-disable-next-line no-non-null-assertion\n return CHECK_DIGITS[sum % 11]!;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length < 8 || v.length > 16) {\n return err(\n \"INVALID_LENGTH\",\n \"NIT must be between 8 and 16 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"NIT must contain only digits\",\n );\n }\n\n const body = v.slice(0, -1);\n const check = calcCheckDigit(body);\n if (check !== Number(v[v.length - 1])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"NIT 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 const body = v.slice(0, -1);\n const checkChar = v.slice(-1);\n const groups: string[] = [];\n for (let i = body.length; i > 0; i -= 3) {\n groups.unshift(body.slice(Math.max(0, i - 3), i));\n }\n return `${groups.join(\".\")}-${checkChar}`;\n};\n\n/** Generate a random valid NIT (10 digits). */\nconst generate = (): string => {\n const body = randomDigits(9);\n const check = calcCheckDigit(body);\n return `${body}${check}`;\n};\n\n/** Colombian tax identification number. */\nconst nit: Validator = {\n name: \"Número de Identificación Tributaria\",\n localName: \"Número de Identificación Tributaria\",\n abbreviation: \"NIT\",\n aliases: [\n \"NIT\",\n \"Número de Identificación Tributaria\",\n ] as const,\n candidatePattern: \"\\\\d{9,10}-?\\\\d\",\n country: \"CO\",\n entityType: \"any\",\n description: \"Tax identifier issued by the DIAN\",\n sourceUrl:\n \"https://es.wikipedia.org/wiki/N%C3%BAmero_de_identificaci%C3%B3n_tributaria\",\n lengths: [8, 9, 10, 11, 12, 13, 14, 15, 16] as const,\n examples: [\"2131234321\", \"8001234565\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default nit;\nexport { compact, format, generate, validate };\n"],"mappings":";;;;;;;;;;;;;;;;AAmBA,MAAM,UAAU;CACd;CAAG;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CACvD;;AAGD,MAAM,eAAe;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAEtD,MAAM,WAAW,UACf,MAAM,OAAO,OAAO;AAEtB,MAAM,kBAAkB,SAAyB;CAC/C,IAAI,MAAM;CACV,MAAM,MAAM,KAAK;AACjB,MAAK,MAAM,CAAC,GAAG,WAAW,QAAQ,SAAS,EAAE;AAC3C,MAAI,KAAK,IAAK;AACd,SAAO,OAAO,KAAK,MAAM,IAAI,GAAG,GAAG;;AAKrC,QAAO,aAAa,MAAM;;AAG5B,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,SAAS,KAAK,EAAE,SAAS,GAC7B,QAAO,IACL,kBACA,sCACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,+BACD;AAKH,KADc,eADD,EAAE,MAAM,GAAG,GAAG,CACO,KACpB,OAAO,EAAE,EAAE,SAAS,GAAG,CACnC,QAAO,IACL,oBACA,iCACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;CACxB,MAAM,OAAO,EAAE,MAAM,GAAG,GAAG;CAC3B,MAAM,YAAY,EAAE,MAAM,GAAG;CAC7B,MAAM,SAAmB,EAAE;AAC3B,MAAK,IAAI,IAAI,KAAK,QAAQ,IAAI,GAAG,KAAK,EACpC,QAAO,QAAQ,KAAK,MAAM,KAAK,IAAI,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC;AAEnD,QAAO,GAAG,OAAO,KAAK,IAAI,CAAC,GAAG;;;AAIhC,MAAM,iBAAyB;CAC7B,MAAM,OAAO,aAAa,EAAE;AAE5B,QAAO,GAAG,OADI,eAAe,KAAK;;;AAKpC,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CACP,OACA,sCACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,aAAa;CACb,WACE;CACF,SAAS;EAAC;EAAG;EAAG;EAAI;EAAI;EAAI;EAAI;EAAI;EAAI;EAAG;CAC3C,UAAU,CAAC,cAAc,aAAa;CACtC;CACA;CACA;CACA;CACD"}
package/dist/cr/cpf.js CHANGED
@@ -30,9 +30,10 @@ const compact = (value) => {
30
30
  let number = clean(value, " ").trim().toUpperCase();
31
31
  const parts = number.split("-");
32
32
  if (parts.length === 3) {
33
- const p0 = parts[0].padStart(2, "0");
34
- const p1 = parts[1].padStart(4, "0");
35
- const p2 = parts[2].padStart(4, "0");
33
+ const [raw0, raw1, raw2] = parts;
34
+ const p0 = (raw0 ?? "").padStart(2, "0");
35
+ const p1 = (raw1 ?? "").padStart(4, "0");
36
+ const p2 = (raw2 ?? "").padStart(4, "0");
36
37
  number = p0 + p1 + p2;
37
38
  } else number = number.replaceAll("-", "");
38
39
  if (number.length === 9) number = "0" + number;
@@ -1 +1 @@
1
- {"version":3,"file":"cpf.js","names":[],"sources":["../../src/cr/cpf.ts"],"sourcesContent":["/** Generate a random valid Costa Rican CPF. */\nconst generate = (): string => {\n const province = String(randomInt(1, 9));\n const volume = randomDigits(4);\n const entry = randomDigits(4);\n return `0${province}${volume}${entry}`;\n};\n\n/**\n * CPF (Cédula de Persona Física, Costa Rican\n * physical person ID number).\n *\n * 10 digits: 0P-TTTT-AAAA where:\n * - 0 = fixed leading zero\n * - P = province digit\n * - TTTT = volume (tomo), zero-padded\n * - AAAA = entry (asiento), zero-padded\n *\n * No check digit; validation is by format only.\n *\n * Ported from python-stdnum cr.cpf module.\n *\n * @see https://www.tse.go.cr/\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\n/**\n * Compact: strip spaces, pad hyphen-separated parts\n * (2-4-4), join, and prepend '0' if 9 digits.\n */\nconst compact = (value: string): string => {\n let number = clean(value, \" \").trim().toUpperCase();\n\n const parts = number.split(\"-\");\n if (parts.length === 3) {\n const p0 = parts[0]!.padStart(2, \"0\");\n const p1 = parts[1]!.padStart(4, \"0\");\n const p2 = parts[2]!.padStart(4, \"0\");\n number = p0 + p1 + p2;\n } else {\n number = number.replaceAll(\"-\", \"\");\n }\n\n if (number.length === 9) {\n number = \"0\" + number;\n }\n\n return number;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 10) {\n return err(\n \"INVALID_LENGTH\",\n \"Costa Rican CPF must be 10 digits\",\n );\n }\n\n if (!/^\\d{10}$/.test(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Costa Rican CPF must contain only digits\",\n );\n }\n\n if (v[0] !== \"0\") {\n return err(\n \"INVALID_COMPONENT\",\n \"Costa Rican CPF must start with 0\",\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, 6)}-${v.slice(6, 10)}`;\n};\n\n/**\n * Costa Rican physical person ID number (CPF).\n *\n * Examples sourced from python-stdnum test suite.\n */\nconst cpf: Validator = {\n name: \"Costa Rican Physical Person ID\",\n localName: \"Cédula de Persona Física\",\n abbreviation: \"CPF\",\n aliases: [\"CPF\", \"cédula de persona física\"] as const,\n candidatePattern: \"\\\\d{9,12}\",\n country: \"CR\",\n entityType: \"person\",\n lengths: [10] as const,\n examples: [\"0304550175\", \"0109130259\"] as const,\n compact,\n format,\n validate,\n sourceUrl: \"https://www.tse.go.cr/\",\n generate,\n};\n\nexport default cpf;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AACA,MAAM,iBAAyB;AAI7B,QAAO,IAHU,OAAO,UAAU,GAAG,EAAE,CAAC,GACzB,aAAa,EAAE,GAChB,aAAa,EAAE;;;;;;AA+B/B,MAAM,WAAW,UAA0B;CACzC,IAAI,SAAS,MAAM,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa;CAEnD,MAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,KAAI,MAAM,WAAW,GAAG;EACtB,MAAM,KAAK,MAAM,GAAI,SAAS,GAAG,IAAI;EACrC,MAAM,KAAK,MAAM,GAAI,SAAS,GAAG,IAAI;EACrC,MAAM,KAAK,MAAM,GAAI,SAAS,GAAG,IAAI;AACrC,WAAS,KAAK,KAAK;OAEnB,UAAS,OAAO,WAAW,KAAK,GAAG;AAGrC,KAAI,OAAO,WAAW,EACpB,UAAS,MAAM;AAGjB,QAAO;;AAGT,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,GACf,QAAO,IACL,kBACA,oCACD;AAGH,KAAI,CAAC,WAAW,KAAK,EAAE,CACrB,QAAO,IACL,kBACA,2CACD;AAGH,KAAI,EAAE,OAAO,IACX,QAAO,IACL,qBACA,oCACD;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;;;;;;;AAQ5D,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,OAAO,2BAA2B;CAC5C,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,GAAG;CACb,UAAU,CAAC,cAAc,aAAa;CACtC;CACA;CACA;CACA,WAAW;CACX;CACD"}
1
+ {"version":3,"file":"cpf.js","names":[],"sources":["../../src/cr/cpf.ts"],"sourcesContent":["/** Generate a random valid Costa Rican CPF. */\nconst generate = (): string => {\n const province = String(randomInt(1, 9));\n const volume = randomDigits(4);\n const entry = randomDigits(4);\n return `0${province}${volume}${entry}`;\n};\n\n/**\n * CPF (Cédula de Persona Física, Costa Rican\n * physical person ID number).\n *\n * 10 digits: 0P-TTTT-AAAA where:\n * - 0 = fixed leading zero\n * - P = province digit\n * - TTTT = volume (tomo), zero-padded\n * - AAAA = entry (asiento), zero-padded\n *\n * No check digit; validation is by format only.\n *\n * Ported from python-stdnum cr.cpf module.\n *\n * @see https://www.tse.go.cr/\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\n/**\n * Compact: strip spaces, pad hyphen-separated parts\n * (2-4-4), join, and prepend '0' if 9 digits.\n */\nconst compact = (value: string): string => {\n let number = clean(value, \" \").trim().toUpperCase();\n\n const parts = number.split(\"-\");\n if (parts.length === 3) {\n const [raw0, raw1, raw2] = parts;\n const p0 = (raw0 ?? \"\").padStart(2, \"0\");\n const p1 = (raw1 ?? \"\").padStart(4, \"0\");\n const p2 = (raw2 ?? \"\").padStart(4, \"0\");\n number = p0 + p1 + p2;\n } else {\n number = number.replaceAll(\"-\", \"\");\n }\n\n if (number.length === 9) {\n number = \"0\" + number;\n }\n\n return number;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 10) {\n return err(\n \"INVALID_LENGTH\",\n \"Costa Rican CPF must be 10 digits\",\n );\n }\n\n if (!/^\\d{10}$/.test(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Costa Rican CPF must contain only digits\",\n );\n }\n\n if (v[0] !== \"0\") {\n return err(\n \"INVALID_COMPONENT\",\n \"Costa Rican CPF must start with 0\",\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, 6)}-${v.slice(6, 10)}`;\n};\n\n/**\n * Costa Rican physical person ID number (CPF).\n *\n * Examples sourced from python-stdnum test suite.\n */\nconst cpf: Validator = {\n name: \"Costa Rican Physical Person ID\",\n localName: \"Cédula de Persona Física\",\n abbreviation: \"CPF\",\n aliases: [\"CPF\", \"cédula de persona física\"] as const,\n candidatePattern: \"\\\\d{9,12}\",\n country: \"CR\",\n entityType: \"person\",\n lengths: [10] as const,\n examples: [\"0304550175\", \"0109130259\"] as const,\n compact,\n format,\n validate,\n sourceUrl: \"https://www.tse.go.cr/\",\n generate,\n};\n\nexport default cpf;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AACA,MAAM,iBAAyB;AAI7B,QAAO,IAHU,OAAO,UAAU,GAAG,EAAE,CAAC,GACzB,aAAa,EAAE,GAChB,aAAa,EAAE;;;;;;AA+B/B,MAAM,WAAW,UAA0B;CACzC,IAAI,SAAS,MAAM,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa;CAEnD,MAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,KAAI,MAAM,WAAW,GAAG;EACtB,MAAM,CAAC,MAAM,MAAM,QAAQ;EAC3B,MAAM,MAAM,QAAQ,IAAI,SAAS,GAAG,IAAI;EACxC,MAAM,MAAM,QAAQ,IAAI,SAAS,GAAG,IAAI;EACxC,MAAM,MAAM,QAAQ,IAAI,SAAS,GAAG,IAAI;AACxC,WAAS,KAAK,KAAK;OAEnB,UAAS,OAAO,WAAW,KAAK,GAAG;AAGrC,KAAI,OAAO,WAAW,EACpB,UAAS,MAAM;AAGjB,QAAO;;AAGT,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,GACf,QAAO,IACL,kBACA,oCACD;AAGH,KAAI,CAAC,WAAW,KAAK,EAAE,CACrB,QAAO,IACL,kBACA,2CACD;AAGH,KAAI,EAAE,OAAO,IACX,QAAO,IACL,qBACA,oCACD;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;;;;;;;AAQ5D,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,OAAO,2BAA2B;CAC5C,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,GAAG;CACb,UAAU,CAAC,cAAc,aAAa;CACtC;CACA;CACA;CACA,WAAW;CACX;CACD"}
package/dist/cr/mod.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
1
  import cpf from "./cpf.js";
3
2
 
4
3
  //#region src/cr/mod.d.ts
5
-
4
+ declare namespace mod_d_exports {
5
+ export { cpf };
6
+ }
6
7
  //#endregion
7
8
  export { cpf, mod_d_exports };
8
9
  //# sourceMappingURL=mod.d.ts.map
@@ -1,7 +1,6 @@
1
1
  import { ValidateResult, Validator } from "./types.js";
2
2
 
3
3
  //#region src/creditcard.d.ts
4
-
5
4
  /**
6
5
  * Card network identifiers returned by
7
6
  * {@link detectNetwork}.
package/dist/cu/mod.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
1
  import ni from "./ni.js";
3
2
 
4
3
  //#region src/cu/mod.d.ts
5
-
4
+ declare namespace mod_d_exports {
5
+ export { ni };
6
+ }
6
7
  //#endregion
7
8
  export { mod_d_exports, ni };
8
9
  //# sourceMappingURL=mod.d.ts.map
package/dist/cu/ni.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ParsedPersonId, ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/cu/ni.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;
@@ -10,12 +9,14 @@ declare const format: (value: string) => string;
10
9
  * Returns null if the value is not valid.
11
10
  */
12
11
  declare const parse: (value: string) => ParsedPersonId | null;
12
+ /** Generate a random valid Cuban NI. */
13
+ declare const generate: () => string;
13
14
  /**
14
15
  * Cuban identity card number (NI).
15
16
  *
16
17
  * Examples sourced from python-stdnum test suite.
17
18
  */
18
- declare const ni: Validator;
19
+ declare const ni: Validator<ParsedPersonId>;
19
20
  //#endregion
20
- export { compact, ni as default, format, parse, validate };
21
+ export { compact, ni as default, format, generate, parse, validate };
21
22
  //# sourceMappingURL=ni.d.ts.map
package/dist/cu/ni.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { clean } from "../_util/clean.js";
2
+ import { randomDigits, randomInt } from "../_util/generate.js";
2
3
  import { err } from "../_util/result.js";
3
4
  import { isValidDate } from "../_util/date.js";
4
5
  //#region src/cu/ni.ts
@@ -60,6 +61,13 @@ const parse = (value) => {
60
61
  gender
61
62
  };
62
63
  };
64
+ /** Generate a random valid Cuban NI. */
65
+ const generate = () => {
66
+ const year = randomInt(1950, 2024);
67
+ const month = String(randomInt(1, 12)).padStart(2, "0");
68
+ const day = String(randomInt(1, 28)).padStart(2, "0");
69
+ return `${String(year % 100).padStart(2, "0")}${month}${day}${year >= 2e3 ? String(randomInt(6, 8)) : String(randomInt(0, 5))}${randomDigits(4)}`;
70
+ };
63
71
  /**
64
72
  * Cuban identity card number (NI).
65
73
  *
@@ -81,10 +89,12 @@ const ni = {
81
89
  examples: ["91021027775", "72062506561"],
82
90
  compact,
83
91
  format,
92
+ parse,
84
93
  validate,
94
+ generate,
85
95
  sourceUrl: "https://www.ecured.cu/Carnet_de_Identidad"
86
96
  };
87
97
  //#endregion
88
- export { compact, ni as default, format, parse, validate };
98
+ export { compact, ni as default, format, generate, parse, validate };
89
99
 
90
100
  //# sourceMappingURL=ni.js.map
package/dist/cu/ni.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ni.js","names":[],"sources":["../../src/cu/ni.ts"],"sourcesContent":["/**\n * NI (Número de Identidad, Cuban identity card number).\n *\n * 11 digits encoding birth date, century, sequence, and\n * gender. Structure: YYMMDDXNNNN where:\n * - YYMMDD = birth date\n * - X = century digit (9=1800s, 0-5=1900s, 6-8=2000s)\n * - NNNN = sequence (digit at position 9 encodes gender:\n * even=male, odd=female)\n *\n * No check digit; validation is by date and format only.\n *\n * Ported from python-stdnum cu.ni module.\n *\n * @see https://www.ecured.cu/Carnet_de_Identidad\n */\n\nimport { clean } from \"#util/clean\";\nimport { isValidDate } from \"#util/date\";\nimport { err } from \"#util/result\";\n\nimport type {\n ParsedPersonId,\n ValidateResult,\n Validator,\n} from \"../types\";\n\nconst compact = (value: string): string =>\n clean(value, \" -\").trim();\n\n/**\n * Derive the full birth year from the two-digit year\n * and the century indicator at position 6.\n */\nconst centuryOffset = (digit: string): number => {\n if (digit === \"9\") return 1800;\n if (digit >= \"0\" && digit <= \"5\") return 1900;\n return 2000;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 11) {\n return err(\n \"INVALID_LENGTH\",\n \"Cuban NI must be 11 digits\",\n );\n }\n\n if (!/^\\d{11}$/.test(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Cuban NI must contain only digits\",\n );\n }\n\n const yy = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const dd = Number(v.slice(4, 6));\n const year = centuryOffset(v[6]!) + yy;\n\n if (!isValidDate(year, mm, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Cuban NI contains an invalid birth date\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/**\n * Extract birth date and gender from a Cuban NI.\n * Returns null if the value is not valid.\n */\nconst parse = (value: string): ParsedPersonId | null => {\n const result = validate(value);\n if (!result.valid) return null;\n\n const v = result.compact;\n const yy = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const dd = Number(v.slice(4, 6));\n const year = centuryOffset(v[6]!) + yy;\n\n const genderDigit = Number(v[9]);\n const gender: \"male\" | \"female\" =\n genderDigit % 2 === 0 ? \"male\" : \"female\";\n\n return {\n birthDate: new Date(year, mm - 1, dd),\n gender,\n };\n};\n\n/**\n * Cuban identity card number (NI).\n *\n * Examples sourced from python-stdnum test suite.\n */\nconst ni: Validator = {\n name: \"Cuban Identity Card Number\",\n localName: \"Número de Identidad\",\n abbreviation: \"NI\",\n aliases: [\n \"NI\",\n \"número de identidad\",\n \"carnet de identidad\",\n ] as const,\n candidatePattern: \"\\\\d{11}\",\n country: \"CU\",\n entityType: \"person\",\n lengths: [11] as const,\n examples: [\"91021027775\", \"72062506561\"] as const,\n compact,\n format,\n validate,\n sourceUrl: \"https://www.ecured.cu/Carnet_de_Identidad\",\n};\n\nexport default ni;\nexport { compact, format, parse, validate };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA2BA,MAAM,WAAW,UACf,MAAM,OAAO,KAAK,CAAC,MAAM;;;;;AAM3B,MAAM,iBAAiB,UAA0B;AAC/C,KAAI,UAAU,IAAK,QAAO;AAC1B,KAAI,SAAS,OAAO,SAAS,IAAK,QAAO;AACzC,QAAO;;AAGT,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,GACf,QAAO,IACL,kBACA,6BACD;AAGH,KAAI,CAAC,WAAW,KAAK,EAAE,CACrB,QAAO,IACL,kBACA,oCACD;CAGH,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;CAChC,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;CAChC,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;AAGhC,KAAI,CAAC,YAFQ,cAAc,EAAE,GAAI,GAAG,IAEb,IAAI,GAAG,CAC5B,QAAO,IACL,qBACA,0CACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B,QAAQ,MAAM;;;;;AAMxD,MAAM,SAAS,UAAyC;CACtD,MAAM,SAAS,SAAS,MAAM;AAC9B,KAAI,CAAC,OAAO,MAAO,QAAO;CAE1B,MAAM,IAAI,OAAO;CACjB,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;CAChC,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;CAChC,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;CAChC,MAAM,OAAO,cAAc,EAAE,GAAI,GAAG;CAGpC,MAAM,SADc,OAAO,EAAE,GAAG,GAEhB,MAAM,IAAI,SAAS;AAEnC,QAAO;EACL,WAAW,IAAI,KAAK,MAAM,KAAK,GAAG,GAAG;EACrC;EACD;;;;;;;AAQH,MAAM,KAAgB;CACpB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;EACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,GAAG;CACb,UAAU,CAAC,eAAe,cAAc;CACxC;CACA;CACA;CACA,WAAW;CACZ"}
1
+ {"version":3,"file":"ni.js","names":[],"sources":["../../src/cu/ni.ts"],"sourcesContent":["/**\n * NI (Número de Identidad, Cuban identity card number).\n *\n * 11 digits encoding birth date, century, sequence, and\n * gender. Structure: YYMMDDXNNNN where:\n * - YYMMDD = birth date\n * - X = century digit (9=1800s, 0-5=1900s, 6-8=2000s)\n * - NNNN = sequence (digit at position 9 encodes gender:\n * even=male, odd=female)\n *\n * No check digit; validation is by date and format only.\n *\n * Ported from python-stdnum cu.ni module.\n *\n * @see https://www.ecured.cu/Carnet_de_Identidad\n */\n\nimport { clean } from \"#util/clean\";\nimport { isValidDate } from \"#util/date\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\n\nimport type {\n ParsedPersonId,\n ValidateResult,\n Validator,\n} from \"../types\";\n\nconst compact = (value: string): string =>\n clean(value, \" -\").trim();\n\n/**\n * Derive the full birth year from the two-digit year\n * and the century indicator at position 6.\n */\nconst centuryOffset = (digit: string): number => {\n if (digit === \"9\") return 1800;\n if (digit >= \"0\" && digit <= \"5\") return 1900;\n return 2000;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 11) {\n return err(\n \"INVALID_LENGTH\",\n \"Cuban NI must be 11 digits\",\n );\n }\n\n if (!/^\\d{11}$/.test(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Cuban NI must contain only digits\",\n );\n }\n\n const yy = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const dd = Number(v.slice(4, 6));\n // SAFETY: regex check above guarantees v.length === 11.\n // eslint-disable-next-line no-non-null-assertion\n const year = centuryOffset(v[6]!) + yy;\n\n if (!isValidDate(year, mm, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Cuban NI contains an invalid birth date\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/**\n * Extract birth date and gender from a Cuban NI.\n * Returns null if the value is not valid.\n */\nconst parse = (value: string): ParsedPersonId | null => {\n const result = validate(value);\n if (!result.valid) return null;\n\n const v = result.compact;\n const yy = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const dd = Number(v.slice(4, 6));\n // SAFETY: regex check above guarantees v.length === 11.\n // eslint-disable-next-line no-non-null-assertion\n const year = centuryOffset(v[6]!) + yy;\n\n const genderDigit = Number(v[9]);\n const gender: \"male\" | \"female\" =\n genderDigit % 2 === 0 ? \"male\" : \"female\";\n\n return {\n birthDate: new Date(year, mm - 1, dd),\n gender,\n };\n};\n\n/** Generate a random valid Cuban NI. */\nconst generate = (): string => {\n const year = randomInt(1950, 2024);\n const month = String(randomInt(1, 12)).padStart(2, \"0\");\n const day = String(randomInt(1, 28)).padStart(2, \"0\");\n const yy = String(year % 100).padStart(2, \"0\");\n const century =\n year >= 2000\n ? String(randomInt(6, 8))\n : String(randomInt(0, 5));\n return `${yy}${month}${day}${century}${randomDigits(4)}`;\n};\n\n/**\n * Cuban identity card number (NI).\n *\n * Examples sourced from python-stdnum test suite.\n */\nconst ni: Validator<ParsedPersonId> = {\n name: \"Cuban Identity Card Number\",\n localName: \"Número de Identidad\",\n abbreviation: \"NI\",\n aliases: [\n \"NI\",\n \"número de identidad\",\n \"carnet de identidad\",\n ] as const,\n candidatePattern: \"\\\\d{11}\",\n country: \"CU\",\n entityType: \"person\",\n lengths: [11] as const,\n examples: [\"91021027775\", \"72062506561\"] as const,\n compact,\n format,\n parse,\n validate,\n generate,\n sourceUrl: \"https://www.ecured.cu/Carnet_de_Identidad\",\n};\n\nexport default ni;\nexport { compact, format, generate, parse, validate };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA4BA,MAAM,WAAW,UACf,MAAM,OAAO,KAAK,CAAC,MAAM;;;;;AAM3B,MAAM,iBAAiB,UAA0B;AAC/C,KAAI,UAAU,IAAK,QAAO;AAC1B,KAAI,SAAS,OAAO,SAAS,IAAK,QAAO;AACzC,QAAO;;AAGT,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,GACf,QAAO,IACL,kBACA,6BACD;AAGH,KAAI,CAAC,WAAW,KAAK,EAAE,CACrB,QAAO,IACL,kBACA,oCACD;CAGH,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;CAChC,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;CAChC,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;AAKhC,KAAI,CAAC,YAFQ,cAAc,EAAE,GAAI,GAAG,IAEb,IAAI,GAAG,CAC5B,QAAO,IACL,qBACA,0CACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B,QAAQ,MAAM;;;;;AAMxD,MAAM,SAAS,UAAyC;CACtD,MAAM,SAAS,SAAS,MAAM;AAC9B,KAAI,CAAC,OAAO,MAAO,QAAO;CAE1B,MAAM,IAAI,OAAO;CACjB,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;CAChC,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;CAChC,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;CAGhC,MAAM,OAAO,cAAc,EAAE,GAAI,GAAG;CAGpC,MAAM,SADc,OAAO,EAAE,GAAG,GAEhB,MAAM,IAAI,SAAS;AAEnC,QAAO;EACL,WAAW,IAAI,KAAK,MAAM,KAAK,GAAG,GAAG;EACrC;EACD;;;AAIH,MAAM,iBAAyB;CAC7B,MAAM,OAAO,UAAU,MAAM,KAAK;CAClC,MAAM,QAAQ,OAAO,UAAU,GAAG,GAAG,CAAC,CAAC,SAAS,GAAG,IAAI;CACvD,MAAM,MAAM,OAAO,UAAU,GAAG,GAAG,CAAC,CAAC,SAAS,GAAG,IAAI;AAMrD,QAAO,GALI,OAAO,OAAO,IAAI,CAAC,SAAS,GAAG,IAAI,GAK/B,QAAQ,MAHrB,QAAQ,MACJ,OAAO,UAAU,GAAG,EAAE,CAAC,GACvB,OAAO,UAAU,GAAG,EAAE,CAAC,GACU,aAAa,EAAE;;;;;;;AAQxD,MAAM,KAAgC;CACpC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;EACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,GAAG;CACb,UAAU,CAAC,eAAe,cAAc;CACxC;CACA;CACA;CACA;CACA;CACA,WAAW;CACZ"}
package/dist/cy/mod.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
1
  import vat from "./vat.js";
3
2
 
4
3
  //#region src/cy/mod.d.ts
5
-
4
+ declare namespace mod_d_exports {
5
+ export { vat };
6
+ }
6
7
  //#endregion
7
8
  export { mod_d_exports, vat };
8
9
  //# sourceMappingURL=mod.d.ts.map
package/dist/cy/vat.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/cy/vat.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/cz/dic.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ValidateResult, Validator } from "../types.js";
2
2
 
3
3
  //#region src/cz/dic.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;