@stll/stdnum 0.0.1 → 2.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 (808) hide show
  1. package/LICENSE +1 -5
  2. package/README.md +28 -4
  3. package/dist/_checksums/luhn.js.map +1 -1
  4. package/dist/_checksums/mod1110.js +1 -1
  5. package/dist/_checksums/mod1110.js.map +1 -1
  6. package/dist/_checksums/mod112.js +5 -5
  7. package/dist/_checksums/mod112.js.map +1 -1
  8. package/dist/_checksums/mod97.js.map +1 -1
  9. package/dist/_checksums/verhoeff.js.map +1 -1
  10. package/dist/_checksums/weighted-sum.js.map +1 -1
  11. package/dist/_util/arabic.js.map +1 -1
  12. package/dist/_util/clean.js.map +1 -1
  13. package/dist/_util/date.js.map +1 -1
  14. package/dist/_util/generate.d.ts +13 -1
  15. package/dist/_util/generate.js +23 -1
  16. package/dist/_util/generate.js.map +1 -1
  17. package/dist/_util/result.js.map +1 -1
  18. package/dist/_util/strings.js.map +1 -1
  19. package/dist/ad/mod.d.ts +3 -2
  20. package/dist/ad/nrt.d.ts +16 -2
  21. package/dist/ad/nrt.js +4 -16
  22. package/dist/ad/nrt.js.map +1 -1
  23. package/dist/ae/eid.d.ts +2 -3
  24. package/dist/ae/eid.js +2 -12
  25. package/dist/ae/eid.js.map +1 -1
  26. package/dist/ae/mod.d.ts +3 -2
  27. package/dist/ai/mod.d.ts +3 -2
  28. package/dist/ai/tin.d.ts +20 -2
  29. package/dist/ai/tin.js +1 -18
  30. package/dist/ai/tin.js.map +1 -1
  31. package/dist/al/mod.d.ts +3 -2
  32. package/dist/al/nipt.d.ts +13 -2
  33. package/dist/al/nipt.js +1 -11
  34. package/dist/al/nipt.js.map +1 -1
  35. package/dist/am/mod.d.ts +3 -2
  36. package/dist/am/tin.d.ts +16 -2
  37. package/dist/am/tin.js +1 -14
  38. package/dist/am/tin.js.map +1 -1
  39. package/dist/ar/cbu.d.ts +2 -3
  40. package/dist/ar/cbu.js +2 -10
  41. package/dist/ar/cbu.js.map +1 -1
  42. package/dist/ar/cuit.d.ts +2 -3
  43. package/dist/ar/cuit.js +13 -29
  44. package/dist/ar/cuit.js.map +1 -1
  45. package/dist/ar/dni.d.ts +11 -2
  46. package/dist/ar/dni.js +1 -9
  47. package/dist/ar/dni.js.map +1 -1
  48. package/dist/ar/mod.d.ts +3 -2
  49. package/dist/at/businessid.d.ts +10 -2
  50. package/dist/at/businessid.js +1 -8
  51. package/dist/at/businessid.js.map +1 -1
  52. package/dist/at/mod.d.ts +3 -2
  53. package/dist/at/tin.d.ts +2 -3
  54. package/dist/at/tin.js +1 -11
  55. package/dist/at/tin.js.map +1 -1
  56. package/dist/at/uid.d.ts +2 -3
  57. package/dist/at/uid.js +2 -10
  58. package/dist/at/uid.js.map +1 -1
  59. package/dist/at/vnr.d.ts +5 -4
  60. package/dist/at/vnr.js +23 -16
  61. package/dist/at/vnr.js.map +1 -1
  62. package/dist/au/abn.d.ts +2 -3
  63. package/dist/au/abn.js +1 -10
  64. package/dist/au/abn.js.map +1 -1
  65. package/dist/au/acn.d.ts +2 -3
  66. package/dist/au/acn.js +1 -10
  67. package/dist/au/acn.js.map +1 -1
  68. package/dist/au/mod.d.ts +3 -2
  69. package/dist/au/tfn.d.ts +2 -3
  70. package/dist/au/tfn.js +1 -10
  71. package/dist/au/tfn.js.map +1 -1
  72. package/dist/az/mod.d.ts +3 -2
  73. package/dist/az/voen.d.ts +2 -3
  74. package/dist/az/voen.js +1 -14
  75. package/dist/az/voen.js.map +1 -1
  76. package/dist/ba/jmbg.d.ts +2 -3
  77. package/dist/ba/jmbg.js +4 -11
  78. package/dist/ba/jmbg.js.map +1 -1
  79. package/dist/ba/mod.d.ts +3 -2
  80. package/dist/bd/mod.d.ts +3 -2
  81. package/dist/bd/nid.d.ts +23 -2
  82. package/dist/bd/nid.js +11 -32
  83. package/dist/bd/nid.js.map +1 -1
  84. package/dist/be/bis.d.ts +2 -3
  85. package/dist/be/bis.js +1 -11
  86. package/dist/be/bis.js.map +1 -1
  87. package/dist/be/mod.d.ts +3 -2
  88. package/dist/be/nn.d.ts +2 -3
  89. package/dist/be/nn.js +1 -11
  90. package/dist/be/nn.js.map +1 -1
  91. package/dist/be/vat.d.ts +2 -3
  92. package/dist/be/vat.js +1 -9
  93. package/dist/be/vat.js.map +1 -1
  94. package/dist/bg/egn.d.ts +2 -3
  95. package/dist/bg/egn.js +5 -13
  96. package/dist/bg/egn.js.map +1 -1
  97. package/dist/bg/mod.d.ts +3 -2
  98. package/dist/bg/pnf.d.ts +2 -3
  99. package/dist/bg/pnf.js +1 -8
  100. package/dist/bg/pnf.js.map +1 -1
  101. package/dist/bg/vat.d.ts +2 -3
  102. package/dist/bg/vat.js +3 -9
  103. package/dist/bg/vat.js.map +1 -1
  104. package/dist/bh/cpr.d.ts +5 -4
  105. package/dist/bh/cpr.js +9 -19
  106. package/dist/bh/cpr.js.map +1 -1
  107. package/dist/bh/mod.d.ts +3 -2
  108. package/dist/bic.d.ts +13 -2
  109. package/dist/bic.js +14 -26
  110. package/dist/bic.js.map +1 -1
  111. package/dist/br/cnpj.d.ts +2 -3
  112. package/dist/br/cnpj.js +1 -20
  113. package/dist/br/cnpj.js.map +1 -1
  114. package/dist/br/cpf.d.ts +2 -3
  115. package/dist/br/cpf.js +1 -14
  116. package/dist/br/cpf.js.map +1 -1
  117. package/dist/br/mod.d.ts +3 -2
  118. package/dist/by/mod.d.ts +3 -2
  119. package/dist/by/unp.d.ts +2 -3
  120. package/dist/by/unp.js +9 -17
  121. package/dist/by/unp.js.map +1 -1
  122. package/dist/bz/mod.d.ts +3 -2
  123. package/dist/bz/tin.d.ts +5 -4
  124. package/dist/bz/tin.js +10 -27
  125. package/dist/bz/tin.js.map +1 -1
  126. package/dist/ca/bn.d.ts +2 -3
  127. package/dist/ca/bn.js +2 -10
  128. package/dist/ca/bn.js.map +1 -1
  129. package/dist/ca/mod.d.ts +3 -2
  130. package/dist/ca/sin.d.ts +2 -3
  131. package/dist/ca/sin.js +2 -10
  132. package/dist/ca/sin.js.map +1 -1
  133. package/dist/ch/mod.d.ts +3 -2
  134. package/dist/ch/ssn.d.ts +2 -3
  135. package/dist/ch/ssn.js +1 -9
  136. package/dist/ch/ssn.js.map +1 -1
  137. package/dist/ch/uid.d.ts +2 -3
  138. package/dist/ch/uid.js +1 -9
  139. package/dist/ch/uid.js.map +1 -1
  140. package/dist/ch/vat.d.ts +2 -3
  141. package/dist/ch/vat.js +1 -9
  142. package/dist/ch/vat.js.map +1 -1
  143. package/dist/cl/mod.d.ts +3 -2
  144. package/dist/cl/rut.d.ts +2 -3
  145. package/dist/cl/rut.js +2 -15
  146. package/dist/cl/rut.js.map +1 -1
  147. package/dist/cn/mod.d.ts +3 -2
  148. package/dist/cn/ric.d.ts +2 -3
  149. package/dist/cn/ric.js +4 -14
  150. package/dist/cn/ric.js.map +1 -1
  151. package/dist/cn/uscc.d.ts +2 -3
  152. package/dist/cn/uscc.js +8 -16
  153. package/dist/cn/uscc.js.map +1 -1
  154. package/dist/co/mod.d.ts +3 -2
  155. package/dist/co/nit.d.ts +2 -3
  156. package/dist/co/nit.js +6 -13
  157. package/dist/co/nit.js.map +1 -1
  158. package/dist/cr/cpf.d.ts +18 -2
  159. package/dist/cr/cpf.js +5 -19
  160. package/dist/cr/cpf.js.map +1 -1
  161. package/dist/cr/mod.d.ts +3 -2
  162. package/dist/creditcard.d.ts +2 -3
  163. package/dist/creditcard.js +5 -14
  164. package/dist/creditcard.js.map +1 -1
  165. package/dist/cu/mod.d.ts +3 -2
  166. package/dist/cu/ni.d.ts +5 -4
  167. package/dist/cu/ni.js +13 -18
  168. package/dist/cu/ni.js.map +1 -1
  169. package/dist/cy/mod.d.ts +3 -2
  170. package/dist/cy/vat.d.ts +2 -3
  171. package/dist/cy/vat.js +1 -8
  172. package/dist/cy/vat.js.map +1 -1
  173. package/dist/cz/dic.d.ts +2 -3
  174. package/dist/cz/dic.js +7 -13
  175. package/dist/cz/dic.js.map +1 -1
  176. package/dist/cz/ico.d.ts +2 -3
  177. package/dist/cz/ico.js +2 -10
  178. package/dist/cz/ico.js.map +1 -1
  179. package/dist/cz/mod.d.ts +3 -2
  180. package/dist/cz/rc.d.ts +2 -3
  181. package/dist/cz/rc.js +22 -21
  182. package/dist/cz/rc.js.map +1 -1
  183. package/dist/de/handelsreg.d.ts +19 -2
  184. package/dist/de/handelsreg.js +10 -26
  185. package/dist/de/handelsreg.js.map +1 -1
  186. package/dist/de/idnr.d.ts +2 -3
  187. package/dist/de/idnr.js +2 -12
  188. package/dist/de/idnr.js.map +1 -1
  189. package/dist/de/mod.d.ts +3 -2
  190. package/dist/de/stnr.d.ts +17 -3
  191. package/dist/de/stnr.js +1 -15
  192. package/dist/de/stnr.js.map +1 -1
  193. package/dist/de/svnr.d.ts +2 -3
  194. package/dist/de/svnr.js +4 -13
  195. package/dist/de/svnr.js.map +1 -1
  196. package/dist/de/vat.d.ts +2 -3
  197. package/dist/de/vat.js +2 -11
  198. package/dist/de/vat.js.map +1 -1
  199. package/dist/dk/cpr.d.ts +5 -4
  200. package/dist/dk/cpr.js +14 -12
  201. package/dist/dk/cpr.js.map +1 -1
  202. package/dist/dk/cvr.d.ts +2 -3
  203. package/dist/dk/cvr.js +2 -15
  204. package/dist/dk/cvr.js.map +1 -1
  205. package/dist/dk/mod.d.ts +3 -2
  206. package/dist/dk/vat.d.ts +2 -3
  207. package/dist/dk/vat.js +3 -13
  208. package/dist/dk/vat.js.map +1 -1
  209. package/dist/do/mod.d.ts +3 -2
  210. package/dist/do/rnc.d.ts +2 -3
  211. package/dist/do/rnc.js +3 -17
  212. package/dist/do/rnc.js.map +1 -1
  213. package/dist/ec/mod.d.ts +3 -2
  214. package/dist/ec/ruc.d.ts +2 -3
  215. package/dist/ec/ruc.js +2 -19
  216. package/dist/ec/ruc.js.map +1 -1
  217. package/dist/ee/ik.d.ts +2 -3
  218. package/dist/ee/ik.js +6 -15
  219. package/dist/ee/ik.js.map +1 -1
  220. package/dist/ee/mod.d.ts +3 -2
  221. package/dist/ee/registrikood.d.ts +2 -3
  222. package/dist/ee/registrikood.js +9 -15
  223. package/dist/ee/registrikood.js.map +1 -1
  224. package/dist/ee/vat.d.ts +2 -3
  225. package/dist/ee/vat.js +2 -10
  226. package/dist/ee/vat.js.map +1 -1
  227. package/dist/eg/mod.d.ts +3 -2
  228. package/dist/eg/tn.d.ts +11 -2
  229. package/dist/eg/tn.js +1 -9
  230. package/dist/eg/tn.js.map +1 -1
  231. package/dist/es/cif.d.ts +2 -3
  232. package/dist/es/cif.js +3 -12
  233. package/dist/es/cif.js.map +1 -1
  234. package/dist/es/dni.d.ts +2 -3
  235. package/dist/es/dni.js +1 -9
  236. package/dist/es/dni.js.map +1 -1
  237. package/dist/es/mod.d.ts +3 -2
  238. package/dist/es/nie.d.ts +2 -3
  239. package/dist/es/nie.js +14 -22
  240. package/dist/es/nie.js.map +1 -1
  241. package/dist/es/nss.d.ts +2 -3
  242. package/dist/es/nss.js +1 -16
  243. package/dist/es/nss.js.map +1 -1
  244. package/dist/es/vat.d.ts +2 -3
  245. package/dist/es/vat.js +5 -10
  246. package/dist/es/vat.js.map +1 -1
  247. package/dist/eu/mod.d.ts +3 -2
  248. package/dist/eu/vat.d.ts +5 -4
  249. package/dist/eu/vat.js +44 -2
  250. package/dist/eu/vat.js.map +1 -1
  251. package/dist/fi/hetu.d.ts +5 -4
  252. package/dist/fi/hetu.js +19 -12
  253. package/dist/fi/hetu.js.map +1 -1
  254. package/dist/fi/mod.d.ts +3 -2
  255. package/dist/fi/vat.d.ts +2 -3
  256. package/dist/fi/vat.js +3 -10
  257. package/dist/fi/vat.js.map +1 -1
  258. package/dist/fi/ytunnus.d.ts +2 -3
  259. package/dist/fi/ytunnus.js +2 -10
  260. package/dist/fi/ytunnus.js.map +1 -1
  261. package/dist/fr/mod.d.ts +3 -2
  262. package/dist/fr/nif.d.ts +2 -3
  263. package/dist/fr/nif.js +1 -9
  264. package/dist/fr/nif.js.map +1 -1
  265. package/dist/fr/nir.d.ts +2 -3
  266. package/dist/fr/nir.js +3 -14
  267. package/dist/fr/nir.js.map +1 -1
  268. package/dist/fr/siren.d.ts +2 -3
  269. package/dist/fr/siren.js +2 -10
  270. package/dist/fr/siren.js.map +1 -1
  271. package/dist/fr/siret.d.ts +2 -3
  272. package/dist/fr/siret.js +2 -11
  273. package/dist/fr/siret.js.map +1 -1
  274. package/dist/fr/tva.d.ts +2 -3
  275. package/dist/fr/tva.js +2 -12
  276. package/dist/fr/tva.js.map +1 -1
  277. package/dist/gb/mod.d.ts +3 -2
  278. package/dist/gb/nino.d.ts +12 -2
  279. package/dist/gb/nino.js +8 -17
  280. package/dist/gb/nino.js.map +1 -1
  281. package/dist/gb/sedol.d.ts +2 -3
  282. package/dist/gb/sedol.js +9 -18
  283. package/dist/gb/sedol.js.map +1 -1
  284. package/dist/gb/utr.d.ts +2 -3
  285. package/dist/gb/utr.js +2 -10
  286. package/dist/gb/utr.js.map +1 -1
  287. package/dist/gb/vat.d.ts +2 -3
  288. package/dist/gb/vat.js +2 -11
  289. package/dist/gb/vat.js.map +1 -1
  290. package/dist/ge/mod.d.ts +3 -2
  291. package/dist/ge/pin.d.ts +14 -2
  292. package/dist/ge/pin.js +1 -12
  293. package/dist/ge/pin.js.map +1 -1
  294. package/dist/gh/mod.d.ts +3 -2
  295. package/dist/gh/tin.d.ts +2 -3
  296. package/dist/gh/tin.js +10 -24
  297. package/dist/gh/tin.js.map +1 -1
  298. package/dist/gr/amka.d.ts +2 -3
  299. package/dist/gr/amka.js +3 -11
  300. package/dist/gr/amka.js.map +1 -1
  301. package/dist/gr/mod.d.ts +3 -2
  302. package/dist/gr/vat.d.ts +2 -3
  303. package/dist/gr/vat.js +1 -10
  304. package/dist/gr/vat.js.map +1 -1
  305. package/dist/gt/mod.d.ts +3 -2
  306. package/dist/gt/nit.d.ts +2 -3
  307. package/dist/gt/nit.js +6 -14
  308. package/dist/gt/nit.js.map +1 -1
  309. package/dist/hk/hkid.d.ts +2 -3
  310. package/dist/hk/hkid.js +2 -10
  311. package/dist/hk/hkid.js.map +1 -1
  312. package/dist/hk/mod.d.ts +3 -2
  313. package/dist/hr/mod.d.ts +3 -2
  314. package/dist/hr/vat.d.ts +2 -3
  315. package/dist/hr/vat.js +2 -9
  316. package/dist/hr/vat.js.map +1 -1
  317. package/dist/hu/mod.d.ts +3 -2
  318. package/dist/hu/vat.d.ts +2 -3
  319. package/dist/hu/vat.js +3 -10
  320. package/dist/hu/vat.js.map +1 -1
  321. package/dist/iban.d.ts +2 -3
  322. package/dist/iban.js +2 -8
  323. package/dist/iban.js.map +1 -1
  324. package/dist/id/mod.d.ts +3 -2
  325. package/dist/id/npwp.d.ts +2 -3
  326. package/dist/id/npwp.js +3 -13
  327. package/dist/id/npwp.js.map +1 -1
  328. package/dist/ie/mod.d.ts +3 -2
  329. package/dist/ie/pps.d.ts +2 -3
  330. package/dist/ie/pps.js +1 -10
  331. package/dist/ie/pps.js.map +1 -1
  332. package/dist/ie/vat.d.ts +2 -3
  333. package/dist/ie/vat.js +1 -9
  334. package/dist/ie/vat.js.map +1 -1
  335. package/dist/il/idnr.d.ts +2 -3
  336. package/dist/il/idnr.js +2 -9
  337. package/dist/il/idnr.js.map +1 -1
  338. package/dist/il/mod.d.ts +3 -2
  339. package/dist/in/aadhaar.d.ts +2 -3
  340. package/dist/in/aadhaar.js +2 -12
  341. package/dist/in/aadhaar.js.map +1 -1
  342. package/dist/in/gstin.d.ts +2 -3
  343. package/dist/in/gstin.js +4 -11
  344. package/dist/in/gstin.js.map +1 -1
  345. package/dist/in/mod.d.ts +3 -2
  346. package/dist/in/pan.d.ts +15 -2
  347. package/dist/in/pan.js +3 -15
  348. package/dist/in/pan.js.map +1 -1
  349. package/dist/index.d.ts +2 -2
  350. package/dist/index.js +6 -6
  351. package/dist/iq/mod.d.ts +3 -2
  352. package/dist/iq/nid.d.ts +16 -2
  353. package/dist/iq/nid.js +2 -15
  354. package/dist/iq/nid.js.map +1 -1
  355. package/dist/ir/mod.d.ts +3 -2
  356. package/dist/ir/nid.d.ts +2 -3
  357. package/dist/ir/nid.js +2 -24
  358. package/dist/ir/nid.js.map +1 -1
  359. package/dist/is/kennitala.d.ts +2 -3
  360. package/dist/is/kennitala.js +2 -13
  361. package/dist/is/kennitala.js.map +1 -1
  362. package/dist/is/mod.d.ts +3 -2
  363. package/dist/is/vsk.d.ts +9 -2
  364. package/dist/is/vsk.js +1 -7
  365. package/dist/is/vsk.js.map +1 -1
  366. package/dist/isin.d.ts +2 -3
  367. package/dist/isin.js +11 -21
  368. package/dist/isin.js.map +1 -1
  369. package/dist/it/codicefiscale.d.ts +5 -4
  370. package/dist/it/codicefiscale.js +27 -23
  371. package/dist/it/codicefiscale.js.map +1 -1
  372. package/dist/it/iva.d.ts +2 -3
  373. package/dist/it/iva.js +2 -9
  374. package/dist/it/iva.js.map +1 -1
  375. package/dist/it/mod.d.ts +3 -2
  376. package/dist/jp/cn.d.ts +2 -3
  377. package/dist/jp/cn.js +1 -9
  378. package/dist/jp/cn.js.map +1 -1
  379. package/dist/jp/mod.d.ts +3 -2
  380. package/dist/jp/mynumber.d.ts +2 -3
  381. package/dist/jp/mynumber.js +1 -10
  382. package/dist/jp/mynumber.js.map +1 -1
  383. package/dist/kr/brn.d.ts +11 -2
  384. package/dist/kr/brn.js +1 -9
  385. package/dist/kr/brn.js.map +1 -1
  386. package/dist/kr/mod.d.ts +3 -2
  387. package/dist/kr/rrn.d.ts +5 -4
  388. package/dist/kr/rrn.js +15 -13
  389. package/dist/kr/rrn.js.map +1 -1
  390. package/dist/kw/civil.d.ts +6 -5
  391. package/dist/kw/civil.js +20 -17
  392. package/dist/kw/civil.js.map +1 -1
  393. package/dist/kw/mod.d.ts +3 -2
  394. package/dist/kz/iin.d.ts +2 -3
  395. package/dist/kz/iin.js +4 -18
  396. package/dist/kz/iin.js.map +1 -1
  397. package/dist/kz/mod.d.ts +3 -2
  398. package/dist/lei.d.ts +2 -3
  399. package/dist/lei.js +2 -11
  400. package/dist/lei.js.map +1 -1
  401. package/dist/li/mod.d.ts +3 -2
  402. package/dist/li/peid.d.ts +11 -2
  403. package/dist/li/peid.js +1 -9
  404. package/dist/li/peid.js.map +1 -1
  405. package/dist/lk/mod.d.ts +3 -2
  406. package/dist/lk/nic.d.ts +5 -4
  407. package/dist/lk/nic.js +16 -16
  408. package/dist/lk/nic.js.map +1 -1
  409. package/dist/lt/asmens.d.ts +2 -3
  410. package/dist/lt/asmens.js +2 -1
  411. package/dist/lt/asmens.js.map +1 -1
  412. package/dist/lt/mod.d.ts +3 -2
  413. package/dist/lt/vat.d.ts +2 -3
  414. package/dist/lt/vat.js +2 -10
  415. package/dist/lt/vat.js.map +1 -1
  416. package/dist/lu/mod.d.ts +3 -2
  417. package/dist/lu/vat.d.ts +2 -3
  418. package/dist/lu/vat.js +2 -8
  419. package/dist/lu/vat.js.map +1 -1
  420. package/dist/luhn.d.ts +2 -3
  421. package/dist/luhn.js +9 -9
  422. package/dist/luhn.js.map +1 -1
  423. package/dist/lv/mod.d.ts +3 -2
  424. package/dist/lv/vat.d.ts +2 -3
  425. package/dist/lv/vat.js +19 -18
  426. package/dist/lv/vat.js.map +1 -1
  427. package/dist/ma/ice.d.ts +2 -3
  428. package/dist/ma/ice.js +2 -11
  429. package/dist/ma/ice.js.map +1 -1
  430. package/dist/ma/mod.d.ts +3 -2
  431. package/dist/mc/mod.d.ts +3 -2
  432. package/dist/mc/tva.d.ts +2 -3
  433. package/dist/mc/tva.js +1 -0
  434. package/dist/mc/tva.js.map +1 -1
  435. package/dist/md/idno.d.ts +2 -3
  436. package/dist/md/idno.js +1 -10
  437. package/dist/md/idno.js.map +1 -1
  438. package/dist/md/mod.d.ts +3 -2
  439. package/dist/me/mod.d.ts +3 -2
  440. package/dist/me/pib.d.ts +2 -3
  441. package/dist/me/pib.js +2 -10
  442. package/dist/me/pib.js.map +1 -1
  443. package/dist/mk/edb.d.ts +2 -3
  444. package/dist/mk/edb.js +2 -11
  445. package/dist/mk/edb.js.map +1 -1
  446. package/dist/mk/mod.d.ts +3 -2
  447. package/dist/mt/mod.d.ts +3 -2
  448. package/dist/mt/vat.d.ts +2 -3
  449. package/dist/mt/vat.js +3 -10
  450. package/dist/mt/vat.js.map +1 -1
  451. package/dist/mu/brn.d.ts +23 -2
  452. package/dist/mu/brn.js +1 -21
  453. package/dist/mu/brn.js.map +1 -1
  454. package/dist/mu/mod.d.ts +3 -2
  455. package/dist/mx/clabe.d.ts +2 -3
  456. package/dist/mx/clabe.js +1 -14
  457. package/dist/mx/clabe.js.map +1 -1
  458. package/dist/mx/curp.d.ts +5 -4
  459. package/dist/mx/curp.js +27 -19
  460. package/dist/mx/curp.js.map +1 -1
  461. package/dist/mx/mod.d.ts +3 -2
  462. package/dist/mx/rfc.d.ts +5 -4
  463. package/dist/mx/rfc.js +23 -20
  464. package/dist/mx/rfc.js.map +1 -1
  465. package/dist/my/mod.d.ts +3 -2
  466. package/dist/my/nric.d.ts +5 -4
  467. package/dist/my/nric.js +18 -16
  468. package/dist/my/nric.js.map +1 -1
  469. package/dist/ng/mod.d.ts +3 -2
  470. package/dist/ng/nin.d.ts +13 -2
  471. package/dist/ng/nin.js +1 -11
  472. package/dist/ng/nin.js.map +1 -1
  473. package/dist/ni/mod.d.ts +3 -2
  474. package/dist/ni/ruc.d.ts +2 -3
  475. package/dist/ni/ruc.js +1 -23
  476. package/dist/ni/ruc.js.map +1 -1
  477. package/dist/nl/bsn.d.ts +2 -3
  478. package/dist/nl/bsn.js +2 -10
  479. package/dist/nl/bsn.js.map +1 -1
  480. package/dist/nl/kvk.d.ts +9 -2
  481. package/dist/nl/kvk.js +1 -7
  482. package/dist/nl/kvk.js.map +1 -1
  483. package/dist/nl/mod.d.ts +3 -2
  484. package/dist/nl/vat.d.ts +2 -3
  485. package/dist/nl/vat.js +4 -50
  486. package/dist/nl/vat.js.map +1 -1
  487. package/dist/no/fodselsnummer.d.ts +2 -3
  488. package/dist/no/fodselsnummer.js +3 -10
  489. package/dist/no/fodselsnummer.js.map +1 -1
  490. package/dist/no/mod.d.ts +3 -2
  491. package/dist/no/mva.d.ts +2 -3
  492. package/dist/no/mva.js +1 -8
  493. package/dist/no/mva.js.map +1 -1
  494. package/dist/no/orgnr.d.ts +2 -3
  495. package/dist/no/orgnr.js +2 -8
  496. package/dist/no/orgnr.js.map +1 -1
  497. package/dist/nz/ird.d.ts +2 -3
  498. package/dist/nz/ird.js +4 -13
  499. package/dist/nz/ird.js.map +1 -1
  500. package/dist/nz/mod.d.ts +3 -2
  501. package/dist/pa/mod.d.ts +3 -2
  502. package/dist/pa/ruc.d.ts +2 -3
  503. package/dist/pa/ruc.js +4 -19
  504. package/dist/pa/ruc.js.map +1 -1
  505. package/dist/patterns.d.ts +8 -10
  506. package/dist/patterns.js +83 -28
  507. package/dist/patterns.js.map +1 -1
  508. package/dist/pe/mod.d.ts +3 -2
  509. package/dist/pe/ruc.d.ts +2 -3
  510. package/dist/pe/ruc.js +10 -24
  511. package/dist/pe/ruc.js.map +1 -1
  512. package/dist/ph/mod.d.ts +3 -2
  513. package/dist/ph/philid.d.ts +14 -2
  514. package/dist/ph/philid.js +1 -12
  515. package/dist/ph/philid.js.map +1 -1
  516. package/dist/pk/cnic.d.ts +14 -2
  517. package/dist/pk/cnic.js +1 -12
  518. package/dist/pk/cnic.js.map +1 -1
  519. package/dist/pk/mod.d.ts +3 -2
  520. package/dist/pl/mod.d.ts +3 -2
  521. package/dist/pl/nip.d.ts +2 -3
  522. package/dist/pl/nip.js +2 -10
  523. package/dist/pl/nip.js.map +1 -1
  524. package/dist/pl/pesel.d.ts +2 -3
  525. package/dist/pl/pesel.js +4 -13
  526. package/dist/pl/pesel.js.map +1 -1
  527. package/dist/pl/regon.d.ts +2 -3
  528. package/dist/pl/regon.js +2 -11
  529. package/dist/pl/regon.js.map +1 -1
  530. package/dist/pt/cc.d.ts +2 -3
  531. package/dist/pt/cc.js +7 -13
  532. package/dist/pt/cc.js.map +1 -1
  533. package/dist/pt/mod.d.ts +3 -2
  534. package/dist/pt/vat.d.ts +2 -3
  535. package/dist/pt/vat.js +3 -11
  536. package/dist/pt/vat.js.map +1 -1
  537. package/dist/ro/cnp.d.ts +2 -3
  538. package/dist/ro/cnp.js +5 -14
  539. package/dist/ro/cnp.js.map +1 -1
  540. package/dist/ro/mod.d.ts +3 -2
  541. package/dist/ro/vat.d.ts +2 -3
  542. package/dist/ro/vat.js +13 -11
  543. package/dist/ro/vat.js.map +1 -1
  544. package/dist/rs/mod.d.ts +3 -2
  545. package/dist/rs/pib.d.ts +2 -3
  546. package/dist/rs/pib.js +1 -9
  547. package/dist/rs/pib.js.map +1 -1
  548. package/dist/ru/inn.d.ts +2 -3
  549. package/dist/ru/inn.js +2 -12
  550. package/dist/ru/inn.js.map +1 -1
  551. package/dist/ru/mod.d.ts +3 -2
  552. package/dist/se/mod.d.ts +3 -2
  553. package/dist/se/orgnr.d.ts +2 -3
  554. package/dist/se/orgnr.js +2 -9
  555. package/dist/se/orgnr.js.map +1 -1
  556. package/dist/se/personnummer.d.ts +2 -3
  557. package/dist/se/personnummer.js +8 -15
  558. package/dist/se/personnummer.js.map +1 -1
  559. package/dist/se/vat.d.ts +2 -3
  560. package/dist/se/vat.js +3 -10
  561. package/dist/se/vat.js.map +1 -1
  562. package/dist/sg/mod.d.ts +3 -2
  563. package/dist/sg/uen.d.ts +2 -3
  564. package/dist/sg/uen.js +47 -70
  565. package/dist/sg/uen.js.map +1 -1
  566. package/dist/si/emso.d.ts +2 -3
  567. package/dist/si/emso.js +12 -14
  568. package/dist/si/emso.js.map +1 -1
  569. package/dist/si/mod.d.ts +3 -2
  570. package/dist/si/vat.d.ts +2 -3
  571. package/dist/si/vat.js +3 -12
  572. package/dist/si/vat.js.map +1 -1
  573. package/dist/sk/dic.d.ts +2 -3
  574. package/dist/sk/dic.js +1 -0
  575. package/dist/sk/dic.js.map +1 -1
  576. package/dist/sk/ico.d.ts +2 -3
  577. package/dist/sk/ico.js +1 -0
  578. package/dist/sk/ico.js.map +1 -1
  579. package/dist/sk/mod.d.ts +3 -2
  580. package/dist/sk/rc.d.ts +4 -5
  581. package/dist/sk/rc.js +6 -2
  582. package/dist/sk/rc.js.map +1 -1
  583. package/dist/th/mod.d.ts +3 -2
  584. package/dist/th/tin.d.ts +2 -3
  585. package/dist/th/tin.js +1 -11
  586. package/dist/th/tin.js.map +1 -1
  587. package/dist/tr/mod.d.ts +3 -2
  588. package/dist/tr/tckimlik.d.ts +2 -3
  589. package/dist/tr/tckimlik.js +1 -20
  590. package/dist/tr/tckimlik.js.map +1 -1
  591. package/dist/tr/vkn.d.ts +2 -3
  592. package/dist/tr/vkn.js +1 -20
  593. package/dist/tr/vkn.js.map +1 -1
  594. package/dist/tw/mod.d.ts +3 -2
  595. package/dist/tw/ubn.d.ts +2 -3
  596. package/dist/tw/ubn.js +2 -12
  597. package/dist/tw/ubn.js.map +1 -1
  598. package/dist/types.d.ts +56 -21
  599. package/dist/ua/edrpou.d.ts +2 -3
  600. package/dist/ua/edrpou.js +5 -12
  601. package/dist/ua/edrpou.js.map +1 -1
  602. package/dist/ua/mod.d.ts +3 -2
  603. package/dist/us/ein.d.ts +12 -2
  604. package/dist/us/ein.js +88 -97
  605. package/dist/us/ein.js.map +1 -1
  606. package/dist/us/itin.d.ts +13 -2
  607. package/dist/us/itin.js +4 -15
  608. package/dist/us/itin.js.map +1 -1
  609. package/dist/us/mod.d.ts +3 -2
  610. package/dist/us/rtn.d.ts +2 -3
  611. package/dist/us/rtn.js +11 -23
  612. package/dist/us/rtn.js.map +1 -1
  613. package/dist/us/ssn.d.ts +13 -2
  614. package/dist/us/ssn.js +1 -11
  615. package/dist/us/ssn.js.map +1 -1
  616. package/dist/uy/mod.d.ts +3 -2
  617. package/dist/uy/rut.d.ts +2 -3
  618. package/dist/uy/rut.js +2 -15
  619. package/dist/uy/rut.js.map +1 -1
  620. package/dist/ve/mod.d.ts +3 -2
  621. package/dist/ve/rif.d.ts +2 -3
  622. package/dist/ve/rif.js +13 -26
  623. package/dist/ve/rif.js.map +1 -1
  624. package/dist/vn/mod.d.ts +3 -2
  625. package/dist/vn/mst.d.ts +2 -3
  626. package/dist/vn/mst.js +1 -12
  627. package/dist/vn/mst.js.map +1 -1
  628. package/dist/za/idnr.d.ts +2 -3
  629. package/dist/za/idnr.js +4 -16
  630. package/dist/za/idnr.js.map +1 -1
  631. package/dist/za/mod.d.ts +3 -2
  632. package/package.json +34 -21
  633. package/src/_checksums/mod1110.ts +1 -1
  634. package/src/_checksums/mod112.ts +7 -6
  635. package/src/_util/generate.ts +38 -0
  636. package/src/ad/nrt.ts +19 -7
  637. package/src/ae/eid.ts +7 -3
  638. package/src/ai/tin.ts +7 -3
  639. package/src/al/nipt.ts +7 -3
  640. package/src/am/tin.ts +7 -3
  641. package/src/ar/cbu.ts +9 -5
  642. package/src/ar/cuit.ts +22 -10
  643. package/src/ar/dni.ts +7 -3
  644. package/src/at/businessid.ts +7 -3
  645. package/src/at/tin.ts +7 -3
  646. package/src/at/uid.ts +7 -3
  647. package/src/at/vnr.ts +62 -12
  648. package/src/au/abn.ts +7 -3
  649. package/src/au/acn.ts +7 -3
  650. package/src/au/tfn.ts +7 -3
  651. package/src/az/voen.ts +9 -3
  652. package/src/ba/jmbg.ts +9 -7
  653. package/src/bd/nid.ts +11 -7
  654. package/src/be/bis.ts +8 -4
  655. package/src/be/nn.ts +7 -3
  656. package/src/be/vat.ts +7 -3
  657. package/src/bg/egn.ts +19 -10
  658. package/src/bg/pnf.ts +7 -3
  659. package/src/bg/vat.ts +8 -3
  660. package/src/bh/cpr.ts +17 -4
  661. package/src/bic.ts +26 -20
  662. package/src/br/cnpj.ts +7 -3
  663. package/src/br/cpf.ts +7 -3
  664. package/src/by/unp.ts +19 -9
  665. package/src/bz/tin.ts +19 -4
  666. package/src/ca/bn.ts +7 -3
  667. package/src/ca/sin.ts +7 -3
  668. package/src/ch/ssn.ts +7 -3
  669. package/src/ch/uid.ts +7 -3
  670. package/src/ch/vat.ts +9 -5
  671. package/src/cl/rut.ts +11 -5
  672. package/src/cn/ric.ts +11 -7
  673. package/src/cn/uscc.ts +27 -11
  674. package/src/co/nit.ts +14 -6
  675. package/src/cr/cpf.ts +11 -6
  676. package/src/creditcard.ts +10 -6
  677. package/src/cu/ni.ts +28 -7
  678. package/src/cy/vat.ts +7 -3
  679. package/src/cz/dic.ts +9 -4
  680. package/src/cz/ico.ts +7 -3
  681. package/src/cz/rc.ts +61 -29
  682. package/src/de/handelsreg.ts +21 -6
  683. package/src/de/idnr.ts +10 -3
  684. package/src/de/stnr.ts +11 -3
  685. package/src/de/svnr.ts +14 -5
  686. package/src/de/vat.ts +7 -3
  687. package/src/dk/cpr.ts +23 -8
  688. package/src/dk/cvr.ts +7 -3
  689. package/src/dk/vat.ts +8 -3
  690. package/src/do/rnc.ts +9 -5
  691. package/src/ec/ruc.ts +9 -5
  692. package/src/ee/ik.ts +21 -10
  693. package/src/ee/registrikood.ts +12 -7
  694. package/src/ee/vat.ts +7 -3
  695. package/src/eg/tn.ts +7 -3
  696. package/src/es/cif.ts +10 -7
  697. package/src/es/dni.ts +7 -3
  698. package/src/es/nie.ts +18 -9
  699. package/src/es/nss.ts +7 -3
  700. package/src/es/vat.ts +13 -5
  701. package/src/eu/vat.ts +55 -6
  702. package/src/fi/hetu.ts +26 -8
  703. package/src/fi/vat.ts +8 -3
  704. package/src/fi/ytunnus.ts +7 -3
  705. package/src/fr/nif.ts +7 -3
  706. package/src/fr/nir.ts +9 -7
  707. package/src/fr/siren.ts +7 -3
  708. package/src/fr/siret.ts +7 -3
  709. package/src/fr/tva.ts +7 -3
  710. package/src/gb/nino.ts +18 -13
  711. package/src/gb/sedol.ts +21 -15
  712. package/src/gb/utr.ts +7 -3
  713. package/src/gb/vat.ts +7 -3
  714. package/src/ge/pin.ts +7 -3
  715. package/src/gh/tin.ts +11 -6
  716. package/src/gr/amka.ts +7 -3
  717. package/src/gr/vat.ts +7 -3
  718. package/src/gt/nit.ts +13 -6
  719. package/src/hk/hkid.ts +9 -4
  720. package/src/hr/vat.ts +7 -3
  721. package/src/hu/vat.ts +8 -3
  722. package/src/iban.ts +7 -3
  723. package/src/id/npwp.ts +7 -3
  724. package/src/ie/pps.ts +7 -3
  725. package/src/ie/vat.ts +7 -3
  726. package/src/il/idnr.ts +7 -3
  727. package/src/in/aadhaar.ts +7 -3
  728. package/src/in/gstin.ts +10 -4
  729. package/src/in/pan.ts +15 -6
  730. package/src/index.ts +6 -0
  731. package/src/iq/nid.ts +7 -3
  732. package/src/ir/nid.ts +7 -3
  733. package/src/is/kennitala.ts +7 -3
  734. package/src/is/vsk.ts +7 -3
  735. package/src/isin.ts +17 -7
  736. package/src/it/codicefiscale.ts +49 -7
  737. package/src/it/iva.ts +7 -3
  738. package/src/jp/cn.ts +7 -3
  739. package/src/jp/mynumber.ts +7 -3
  740. package/src/kr/brn.ts +7 -3
  741. package/src/kr/rrn.ts +27 -8
  742. package/src/kw/civil.ts +31 -14
  743. package/src/kz/iin.ts +9 -8
  744. package/src/lei.ts +7 -3
  745. package/src/li/peid.ts +7 -3
  746. package/src/lk/nic.ts +31 -8
  747. package/src/lt/asmens.ts +8 -4
  748. package/src/lt/vat.ts +8 -3
  749. package/src/lu/vat.ts +8 -3
  750. package/src/luhn.ts +10 -3
  751. package/src/lv/vat.ts +53 -23
  752. package/src/ma/ice.ts +7 -3
  753. package/src/mc/tva.ts +9 -5
  754. package/src/md/idno.ts +7 -3
  755. package/src/me/pib.ts +7 -3
  756. package/src/mk/edb.ts +7 -3
  757. package/src/mt/vat.ts +8 -3
  758. package/src/mu/brn.ts +7 -3
  759. package/src/mx/clabe.ts +7 -3
  760. package/src/mx/curp.ts +47 -10
  761. package/src/mx/rfc.ts +42 -7
  762. package/src/my/nric.ts +33 -8
  763. package/src/ng/nin.ts +7 -3
  764. package/src/ni/ruc.ts +7 -3
  765. package/src/nl/bsn.ts +7 -3
  766. package/src/nl/kvk.ts +7 -3
  767. package/src/nl/vat.ts +18 -69
  768. package/src/no/fodselsnummer.ts +12 -7
  769. package/src/no/mva.ts +9 -5
  770. package/src/no/orgnr.ts +7 -3
  771. package/src/nz/ird.ts +12 -8
  772. package/src/pa/ruc.ts +39 -11
  773. package/src/patterns.ts +184 -46
  774. package/src/pe/ruc.ts +13 -10
  775. package/src/ph/philid.ts +7 -3
  776. package/src/pk/cnic.ts +9 -3
  777. package/src/pl/nip.ts +7 -3
  778. package/src/pl/pesel.ts +9 -7
  779. package/src/pl/regon.ts +7 -3
  780. package/src/pt/cc.ts +13 -7
  781. package/src/pt/vat.ts +8 -3
  782. package/src/ro/cnp.ts +16 -8
  783. package/src/ro/vat.ts +8 -3
  784. package/src/rs/pib.ts +7 -3
  785. package/src/ru/inn.ts +9 -5
  786. package/src/se/orgnr.ts +7 -3
  787. package/src/se/personnummer.ts +35 -32
  788. package/src/se/vat.ts +8 -3
  789. package/src/sg/uen.ts +44 -23
  790. package/src/si/emso.ts +37 -11
  791. package/src/si/vat.ts +8 -3
  792. package/src/sk/dic.ts +8 -4
  793. package/src/sk/ico.ts +3 -2
  794. package/src/sk/rc.ts +17 -4
  795. package/src/th/tin.ts +7 -3
  796. package/src/tr/tckimlik.ts +7 -3
  797. package/src/tr/vkn.ts +7 -3
  798. package/src/tw/ubn.ts +9 -5
  799. package/src/types.ts +69 -7
  800. package/src/ua/edrpou.ts +10 -5
  801. package/src/us/ein.ts +95 -91
  802. package/src/us/itin.ts +14 -11
  803. package/src/us/rtn.ts +32 -19
  804. package/src/us/ssn.ts +7 -3
  805. package/src/uy/rut.ts +9 -5
  806. package/src/ve/rif.ts +19 -12
  807. package/src/vn/mst.ts +7 -3
  808. package/src/za/idnr.ts +9 -7
package/dist/cu/ni.d.ts CHANGED
@@ -1,7 +1,6 @@
1
- import { ParsedPersonId, ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ParsedPersonId, ValidateResult } 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: CountryValidator<"CU", 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,23 +1,8 @@
1
1
  import { clean } from "../_util/clean.js";
2
- import { err } from "../_util/result.js";
3
2
  import { isValidDate } from "../_util/date.js";
3
+ import { randomDigits, randomInt } from "../_util/generate.js";
4
+ import { err } from "../_util/result.js";
4
5
  //#region src/cu/ni.ts
5
- /**
6
- * NI (Número de Identidad, Cuban identity card number).
7
- *
8
- * 11 digits encoding birth date, century, sequence, and
9
- * gender. Structure: YYMMDDXNNNN where:
10
- * - YYMMDD = birth date
11
- * - X = century digit (9=1800s, 0-5=1900s, 6-8=2000s)
12
- * - NNNN = sequence (digit at position 9 encodes gender:
13
- * even=male, odd=female)
14
- *
15
- * No check digit; validation is by date and format only.
16
- *
17
- * Ported from python-stdnum cu.ni module.
18
- *
19
- * @see https://www.ecured.cu/Carnet_de_Identidad
20
- */
21
6
  const compact = (value) => clean(value, " -").trim();
22
7
  /**
23
8
  * Derive the full birth year from the two-digit year
@@ -60,6 +45,13 @@ const parse = (value) => {
60
45
  gender
61
46
  };
62
47
  };
48
+ /** Generate a random valid Cuban NI. */
49
+ const generate = () => {
50
+ const year = randomInt(1950, 2024);
51
+ const month = String(randomInt(1, 12)).padStart(2, "0");
52
+ const day = String(randomInt(1, 28)).padStart(2, "0");
53
+ return `${String(year % 100).padStart(2, "0")}${month}${day}${year >= 2e3 ? String(randomInt(6, 8)) : String(randomInt(0, 5))}${randomDigits(4)}`;
54
+ };
63
55
  /**
64
56
  * Cuban identity card number (NI).
65
57
  *
@@ -75,16 +67,19 @@ const ni = {
75
67
  "carnet de identidad"
76
68
  ],
77
69
  candidatePattern: "\\d{11}",
70
+ scope: "country",
78
71
  country: "CU",
79
72
  entityType: "person",
80
73
  lengths: [11],
81
74
  examples: ["91021027775", "72062506561"],
82
75
  compact,
83
76
  format,
77
+ parse,
84
78
  validate,
79
+ generate,
85
80
  sourceUrl: "https://www.ecured.cu/Carnet_de_Identidad"
86
81
  };
87
82
  //#endregion
88
- export { compact, ni as default, format, parse, validate };
83
+ export { compact, ni as default, format, generate, parse, validate };
89
84
 
90
85
  //# 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 type {\n ParsedPersonId,\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport { isValidDate } from \"#util/date\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\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: CountryValidator<\"CU\", 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 scope: \"country\",\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,IAAI,EAAE,KAAK;;;;;AAM1B,MAAM,iBAAiB,UAA0B;CAC/C,IAAI,UAAU,KAAK,OAAO;CAC1B,IAAI,SAAS,OAAO,SAAS,KAAK,OAAO;CACzC,OAAO;AACT;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CAEvB,IAAI,EAAE,WAAW,IACf,OAAO,IACL,kBACA,4BACF;CAGF,IAAI,CAAC,WAAW,KAAK,CAAC,GACpB,OAAO,IACL,kBACA,mCACF;CAGF,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC/B,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC/B,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAK/B,IAAI,CAAC,YAFQ,cAAc,EAAE,EAAG,IAAI,IAEb,IAAI,EAAE,GAC3B,OAAO,IACL,qBACA,yCACF;CAGF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B,QAAQ,KAAK;;;;;AAMvD,MAAM,SAAS,UAAyC;CACtD,MAAM,SAAS,SAAS,KAAK;CAC7B,IAAI,CAAC,OAAO,OAAO,OAAO;CAE1B,MAAM,IAAI,OAAO;CACjB,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC/B,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC/B,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAG/B,MAAM,OAAO,cAAc,EAAE,EAAG,IAAI;CAGpC,MAAM,SADc,OAAO,EAAE,EAEjB,IAAI,MAAM,IAAI,SAAS;CAEnC,OAAO;EACL,WAAW,IAAI,KAAK,MAAM,KAAK,GAAG,EAAE;EACpC;CACF;AACF;;AAGA,MAAM,iBAAyB;CAC7B,MAAM,OAAO,UAAU,MAAM,IAAI;CACjC,MAAM,QAAQ,OAAO,UAAU,GAAG,EAAE,CAAC,EAAE,SAAS,GAAG,GAAG;CACtD,MAAM,MAAM,OAAO,UAAU,GAAG,EAAE,CAAC,EAAE,SAAS,GAAG,GAAG;CAMpD,OAAO,GALI,OAAO,OAAO,GAAG,EAAE,SAAS,GAAG,GAK/B,IAAI,QAAQ,MAHrB,QAAQ,MACJ,OAAO,UAAU,GAAG,CAAC,CAAC,IACtB,OAAO,UAAU,GAAG,CAAC,CAAC,IACW,aAAa,CAAC;AACvD;;;;;;AAOA,MAAM,KAA6C;CACjD,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;CACF;CACA,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,EAAE;CACZ,UAAU,CAAC,eAAe,aAAa;CACvC;CACA;CACA;CACA;CACA;CACA,WAAW;AACb"}
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,14 +1,13 @@
1
- import { ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ValidateResult } 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;
8
7
  /** Generate a random valid Cypriot VAT number. */
9
8
  declare const generate: () => string;
10
9
  /** Cypriot VAT Number. */
11
- declare const vat: Validator;
10
+ declare const vat: CountryValidator<"CY">;
12
11
  //#endregion
13
12
  export { compact, vat as default, format, generate, validate };
14
13
  //# sourceMappingURL=vat.d.ts.map
package/dist/cy/vat.js CHANGED
@@ -3,14 +3,6 @@ import { randomDigits } from "../_util/generate.js";
3
3
  import { err } from "../_util/result.js";
4
4
  import { isdigits } from "../_util/strings.js";
5
5
  //#region src/cy/vat.ts
6
- /**
7
- * ΦΠΑ (Cypriot VAT number).
8
- *
9
- * 8 digits + 1 check letter. Cannot start with "12".
10
- *
11
- * @see https://www.vatify.eu/cyprus-vat-number.html
12
- * @see https://www.oecd.org/content/dam/oecd/en/topics/policy-issue-focus/aeoi/cyprus-tin.pdf
13
- */
14
6
  const ODD_MAP = {
15
7
  0: 1,
16
8
  1: 0,
@@ -73,6 +65,7 @@ const vat = {
73
65
  abbreviation: "ΦΠΑ",
74
66
  aliases: ["ΦΠΑ", "VAT CY"],
75
67
  candidatePattern: "CY\\d{8}[A-Z]",
68
+ scope: "country",
76
69
  country: "CY",
77
70
  entityType: "company",
78
71
  sourceUrl: "https://www.mof.gov.cy/",
@@ -1 +1 @@
1
- {"version":3,"file":"vat.js","names":[],"sources":["../../src/cy/vat.ts"],"sourcesContent":["/**\n * ΦΠΑ (Cypriot VAT number).\n *\n * 8 digits + 1 check letter. Cannot start with \"12\".\n *\n * @see https://www.vatify.eu/cyprus-vat-number.html\n * @see https://www.oecd.org/content/dam/oecd/en/topics/policy-issue-focus/aeoi/cyprus-tin.pdf\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 ODD_MAP: Record<number, number> = {\n 0: 1,\n 1: 0,\n 2: 5,\n 3: 7,\n 4: 9,\n 5: 13,\n 6: 15,\n 7: 17,\n 8: 19,\n 9: 21,\n};\n\nconst LETTERS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -/.\");\n if (v.startsWith(\"CY\") || v.startsWith(\"cy\")) {\n v = v.slice(2);\n }\n return v.toUpperCase();\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"Cypriot VAT number must be 8 digits + 1 letter\",\n );\n }\n const digits = v.slice(0, 8);\n const checkLetter = v[8];\n if (!isdigits(digits)) {\n return err(\n \"INVALID_FORMAT\",\n \"Cypriot VAT number must start with 8 digits\",\n );\n }\n if (\n checkLetter === undefined ||\n !LETTERS.includes(checkLetter)\n ) {\n return err(\n \"INVALID_FORMAT\",\n \"Cypriot VAT number must end with a letter\",\n );\n }\n if (v.startsWith(\"12\")) {\n return err(\n \"INVALID_COMPONENT\",\n \"Cypriot VAT number cannot start with 12\",\n );\n }\n let odd = 0;\n let even = 0;\n for (let i = 0; i < 8; i++) {\n const d = Number(digits.charAt(i));\n if (i % 2 === 0) {\n // Odd position (1-indexed: 1,3,5,7)\n odd += ODD_MAP[d] ?? 0;\n } else {\n // Even position (1-indexed: 2,4,6,8)\n even += d;\n }\n }\n const expected = LETTERS.charAt((odd + even) % 26);\n if (checkLetter !== expected) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Cypriot VAT number check letter mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string =>\n `CY${compact(value)}`;\n\n/** Generate a random valid Cypriot VAT number. */\nconst generate = (): string => {\n for (;;) {\n const digits = randomDigits(8);\n if (digits.startsWith(\"12\")) continue;\n let odd = 0;\n let even = 0;\n for (let i = 0; i < 8; i++) {\n const d = Number(digits.charAt(i));\n if (i % 2 === 0) odd += ODD_MAP[d] ?? 0;\n else even += d;\n }\n return digits + LETTERS.charAt((odd + even) % 26);\n }\n};\n\n/** Cypriot VAT Number. */\nconst vat: Validator = {\n name: \"Cypriot VAT Number\",\n localName: \"Αριθμός Εγγραφής Φ.Π.Α.\",\n abbreviation: \"ΦΠΑ\",\n aliases: [\"ΦΠΑ\", \"VAT CY\"] as const,\n candidatePattern: \"CY\\\\d{8}[A-Z]\",\n country: \"CY\",\n entityType: \"company\",\n sourceUrl: \"https://www.mof.gov.cy/\",\n examples: [\"10259033P\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default vat;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;AAgBA,MAAM,UAAkC;CACtC,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACJ;AAED,MAAM,UAAU;AAEhB,MAAM,WAAW,UAA0B;CACzC,IAAI,IAAI,MAAM,OAAO,OAAO;AAC5B,KAAI,EAAE,WAAW,KAAK,IAAI,EAAE,WAAW,KAAK,CAC1C,KAAI,EAAE,MAAM,EAAE;AAEhB,QAAO,EAAE,aAAa;;AAGxB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,IACL,kBACA,iDACD;CAEH,MAAM,SAAS,EAAE,MAAM,GAAG,EAAE;CAC5B,MAAM,cAAc,EAAE;AACtB,KAAI,CAAC,SAAS,OAAO,CACnB,QAAO,IACL,kBACA,8CACD;AAEH,KACE,gBAAgB,KAAA,KAChB,CAAC,QAAQ,SAAS,YAAY,CAE9B,QAAO,IACL,kBACA,4CACD;AAEH,KAAI,EAAE,WAAW,KAAK,CACpB,QAAO,IACL,qBACA,0CACD;CAEH,IAAI,MAAM;CACV,IAAI,OAAO;AACX,MAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,MAAM,IAAI,OAAO,OAAO,OAAO,EAAE,CAAC;AAClC,MAAI,IAAI,MAAM,EAEZ,QAAO,QAAQ,MAAM;MAGrB,SAAQ;;AAIZ,KAAI,gBADa,QAAQ,QAAQ,MAAM,QAAQ,GAAG,CAEhD,QAAO,IACL,oBACA,2CACD;AAEH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UACd,KAAK,QAAQ,MAAM;;AAGrB,MAAM,iBAAyB;AAC7B,UAAS;EACP,MAAM,SAAS,aAAa,EAAE;AAC9B,MAAI,OAAO,WAAW,KAAK,CAAE;EAC7B,IAAI,MAAM;EACV,IAAI,OAAO;AACX,OAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAC1B,MAAM,IAAI,OAAO,OAAO,OAAO,EAAE,CAAC;AAClC,OAAI,IAAI,MAAM,EAAG,QAAO,QAAQ,MAAM;OACjC,SAAQ;;AAEf,SAAO,SAAS,QAAQ,QAAQ,MAAM,QAAQ,GAAG;;;;AAKrD,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,OAAO,SAAS;CAC1B,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,YAAY;CACvB;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"vat.js","names":[],"sources":["../../src/cy/vat.ts"],"sourcesContent":["/**\n * ΦΠΑ (Cypriot VAT number).\n *\n * 8 digits + 1 check letter. Cannot start with \"12\".\n *\n * @see https://www.vatify.eu/cyprus-vat-number.html\n * @see https://www.oecd.org/content/dam/oecd/en/topics/policy-issue-focus/aeoi/cyprus-tin.pdf\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst ODD_MAP: Record<number, number> = {\n 0: 1,\n 1: 0,\n 2: 5,\n 3: 7,\n 4: 9,\n 5: 13,\n 6: 15,\n 7: 17,\n 8: 19,\n 9: 21,\n};\n\nconst LETTERS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -/.\");\n if (v.startsWith(\"CY\") || v.startsWith(\"cy\")) {\n v = v.slice(2);\n }\n return v.toUpperCase();\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"Cypriot VAT number must be 8 digits + 1 letter\",\n );\n }\n const digits = v.slice(0, 8);\n const checkLetter = v[8];\n if (!isdigits(digits)) {\n return err(\n \"INVALID_FORMAT\",\n \"Cypriot VAT number must start with 8 digits\",\n );\n }\n if (\n checkLetter === undefined ||\n !LETTERS.includes(checkLetter)\n ) {\n return err(\n \"INVALID_FORMAT\",\n \"Cypriot VAT number must end with a letter\",\n );\n }\n if (v.startsWith(\"12\")) {\n return err(\n \"INVALID_COMPONENT\",\n \"Cypriot VAT number cannot start with 12\",\n );\n }\n let odd = 0;\n let even = 0;\n for (let i = 0; i < 8; i++) {\n const d = Number(digits.charAt(i));\n if (i % 2 === 0) {\n // Odd position (1-indexed: 1,3,5,7)\n odd += ODD_MAP[d] ?? 0;\n } else {\n // Even position (1-indexed: 2,4,6,8)\n even += d;\n }\n }\n const expected = LETTERS.charAt((odd + even) % 26);\n if (checkLetter !== expected) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Cypriot VAT number check letter mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string =>\n `CY${compact(value)}`;\n\n/** Generate a random valid Cypriot VAT number. */\nconst generate = (): string => {\n for (;;) {\n const digits = randomDigits(8);\n if (digits.startsWith(\"12\")) continue;\n let odd = 0;\n let even = 0;\n for (let i = 0; i < 8; i++) {\n const d = Number(digits.charAt(i));\n if (i % 2 === 0) odd += ODD_MAP[d] ?? 0;\n else even += d;\n }\n return digits + LETTERS.charAt((odd + even) % 26);\n }\n};\n\n/** Cypriot VAT Number. */\nconst vat: CountryValidator<\"CY\"> = {\n name: \"Cypriot VAT Number\",\n localName: \"Αριθμός Εγγραφής Φ.Π.Α.\",\n abbreviation: \"ΦΠΑ\",\n aliases: [\"ΦΠΑ\", \"VAT CY\"] as const,\n candidatePattern: \"CY\\\\d{8}[A-Z]\",\n scope: \"country\",\n country: \"CY\",\n entityType: \"company\",\n sourceUrl: \"https://www.mof.gov.cy/\",\n examples: [\"10259033P\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default vat;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;AAmBA,MAAM,UAAkC;CACtC,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;AACL;AAEA,MAAM,UAAU;AAEhB,MAAM,WAAW,UAA0B;CACzC,IAAI,IAAI,MAAM,OAAO,MAAM;CAC3B,IAAI,EAAE,WAAW,IAAI,KAAK,EAAE,WAAW,IAAI,GACzC,IAAI,EAAE,MAAM,CAAC;CAEf,OAAO,EAAE,YAAY;AACvB;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,GACf,OAAO,IACL,kBACA,gDACF;CAEF,MAAM,SAAS,EAAE,MAAM,GAAG,CAAC;CAC3B,MAAM,cAAc,EAAE;CACtB,IAAI,CAAC,SAAS,MAAM,GAClB,OAAO,IACL,kBACA,6CACF;CAEF,IACE,gBAAgB,KAAA,KAChB,CAAC,QAAQ,SAAS,WAAW,GAE7B,OAAO,IACL,kBACA,2CACF;CAEF,IAAI,EAAE,WAAW,IAAI,GACnB,OAAO,IACL,qBACA,yCACF;CAEF,IAAI,MAAM;CACV,IAAI,OAAO;CACX,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,MAAM,IAAI,OAAO,OAAO,OAAO,CAAC,CAAC;EACjC,IAAI,IAAI,MAAM,GAEZ,OAAO,QAAQ,MAAM;OAGrB,QAAQ;CAEZ;CAEA,IAAI,gBADa,QAAQ,QAAQ,MAAM,QAAQ,EACpB,GACzB,OAAO,IACL,oBACA,0CACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UACd,KAAK,QAAQ,KAAK;;AAGpB,MAAM,iBAAyB;CAC7B,SAAS;EACP,MAAM,SAAS,aAAa,CAAC;EAC7B,IAAI,OAAO,WAAW,IAAI,GAAG;EAC7B,IAAI,MAAM;EACV,IAAI,OAAO;EACX,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAC1B,MAAM,IAAI,OAAO,OAAO,OAAO,CAAC,CAAC;GACjC,IAAI,IAAI,MAAM,GAAG,OAAO,QAAQ,MAAM;QACjC,QAAQ;EACf;EACA,OAAO,SAAS,QAAQ,QAAQ,MAAM,QAAQ,EAAE;CAClD;AACF;;AAGA,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,OAAO,QAAQ;CACzB,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,WAAW;CACtB;CACA;CACA;CACA;AACF"}
package/dist/cz/dic.d.ts CHANGED
@@ -1,14 +1,13 @@
1
- import { ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ValidateResult } 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;
8
7
  /** Generate a random valid 8-digit DIČ. */
9
8
  declare const generate: () => string;
10
9
  /** Czech VAT Number. */
11
- declare const dic: Validator;
10
+ declare const dic: CountryValidator<"CZ">;
12
11
  //#endregion
13
12
  export { compact, dic as default, format, generate, validate };
14
13
  //# sourceMappingURL=dic.d.ts.map
package/dist/cz/dic.js CHANGED
@@ -1,22 +1,10 @@
1
+ import { weightedSum } from "../_checksums/weighted-sum.js";
1
2
  import { clean } from "../_util/clean.js";
2
3
  import { randomDigits, randomInt } from "../_util/generate.js";
3
4
  import { err } from "../_util/result.js";
4
5
  import { isdigits } from "../_util/strings.js";
5
- import { weightedSum } from "../_checksums/weighted-sum.js";
6
6
  import { validate as validate$1 } from "./rc.js";
7
7
  //#region src/cz/dic.ts
8
- /**
9
- * DIČ (Daňové identifikační číslo).
10
- *
11
- * Czech tax identification number / VAT number.
12
- * Format: "CZ" prefix + 8, 9, or 10 digits.
13
- * - 8 digits: company (same checksum as IČO,
14
- * but first digit cannot be 9)
15
- * - 9 digits starting with 6: special entity
16
- * - 9-10 digits: individual (birth number)
17
- *
18
- * @see https://adisspr.mfcr.cz/dpr/DphReg
19
- */
20
8
  const ICO_WEIGHTS = [
21
9
  8,
22
10
  7,
@@ -82,9 +70,15 @@ const dic = {
82
70
  abbreviation: "DIČ",
83
71
  aliases: ["DIČ", "daňové identifikační číslo"],
84
72
  candidatePattern: "CZ\\d{8,10}",
73
+ scope: "country",
85
74
  country: "CZ",
86
75
  entityType: "any",
87
76
  sourceUrl: "https://adisspr.mfcr.cz/dpr/DphReg",
77
+ lengths: [
78
+ 8,
79
+ 9,
80
+ 10
81
+ ],
88
82
  examples: ["25123891", "7103192745"],
89
83
  compact,
90
84
  format,
@@ -1 +1 @@
1
- {"version":3,"file":"dic.js","names":["validateRc"],"sources":["../../src/cz/dic.ts"],"sourcesContent":["/**\n * DIČ (Daňové identifikační číslo).\n *\n * Czech tax identification number / VAT number.\n * Format: \"CZ\" prefix + 8, 9, or 10 digits.\n * - 8 digits: company (same checksum as IČO,\n * but first digit cannot be 9)\n * - 9 digits starting with 6: special entity\n * - 9-10 digits: individual (birth number)\n *\n * @see https://adisspr.mfcr.cz/dpr/DphReg\n */\n\nimport { weightedSum } from \"#checksums/weighted-sum\";\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\";\nimport { validate as validateRc } from \"./rc\";\n\nconst ICO_WEIGHTS = [8, 7, 6, 5, 4, 3, 2] as const;\n\nconst compact = (value: string): string => {\n const v = clean(value, \" -\");\n if (v.startsWith(\"CZ\") || v.startsWith(\"cz\")) {\n return v.slice(2);\n }\n return v;\n};\n\nconst checkLegal = (value: string): boolean => {\n const sum = weightedSum(\n value.slice(0, 7),\n ICO_WEIGHTS,\n 11,\n );\n const v11 = (11 - sum) % 11;\n const check = v11 === 0 ? 1 : v11 % 10;\n return check === Number(value[7]);\n};\n\nconst checkSpecial = (value: string): boolean => {\n // Skip the leading \"6\"; check digits 1..7\n const sum = weightedSum(\n value.slice(1, 8),\n [8, 7, 6, 5, 4, 3, 2],\n 11,\n );\n const check =\n (((8 - ((((10 - sum) % 11) + 11) % 11)) % 10) + 10) %\n 10;\n return check === Number(value[8]);\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length < 8 || v.length > 10) {\n return err(\n \"INVALID_LENGTH\",\n \"DIČ must be 8-10 digits (without CZ prefix)\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"DIČ must contain only digits\",\n );\n }\n\n // 8-digit: legal entity (IČO-like checksum)\n if (v.length === 8) {\n if (v[0] === \"9\") {\n return err(\n \"INVALID_COMPONENT\",\n \"8-digit DIČ cannot start with 9\",\n );\n }\n if (!checkLegal(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"DIČ check digit does not match\",\n );\n }\n return { valid: true, compact: v };\n }\n\n // 9-digit starting with 6: special entity\n if (v.length === 9 && v[0] === \"6\") {\n if (!checkSpecial(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"DIČ special entity check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n }\n\n // 9-10 digit: birth number\n return validateRc(v);\n};\n\nconst format = (value: string): string =>\n `CZ${compact(value)}`;\n\n/** Generate a random valid 8-digit DIČ. */\nconst generate = (): string => {\n const first = String(randomInt(1, 8));\n const payload = first + randomDigits(6);\n const sum = weightedSum(payload, ICO_WEIGHTS, 11);\n const v11 = (11 - sum) % 11;\n const check = v11 === 0 ? 1 : v11 % 10;\n return payload + String(check);\n};\n\n/** Czech VAT Number. */\nconst dic: Validator = {\n name: \"Czech VAT Number\",\n localName: \"Daňové identifikační číslo\",\n abbreviation: \"DIČ\",\n aliases: [\"DIČ\", \"daňové identifikační číslo\"] as const,\n candidatePattern: \"CZ\\\\d{8,10}\",\n country: \"CZ\",\n entityType: \"any\",\n sourceUrl: \"https://adisspr.mfcr.cz/dpr/DphReg\",\n examples: [\"25123891\", \"7103192745\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default dic;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAsBA,MAAM,cAAc;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAEzC,MAAM,WAAW,UAA0B;CACzC,MAAM,IAAI,MAAM,OAAO,KAAK;AAC5B,KAAI,EAAE,WAAW,KAAK,IAAI,EAAE,WAAW,KAAK,CAC1C,QAAO,EAAE,MAAM,EAAE;AAEnB,QAAO;;AAGT,MAAM,cAAc,UAA2B;CAM7C,MAAM,OAAO,KALD,YACV,MAAM,MAAM,GAAG,EAAE,EACjB,aACA,GACD,IACwB;AAEzB,SADc,QAAQ,IAAI,IAAI,MAAM,QACnB,OAAO,MAAM,GAAG;;AAGnC,MAAM,gBAAgB,UAA2B;AAU/C,UAFK,MAAQ,KAND,YACV,MAAM,MAAM,GAAG,EAAE,EACjB;EAAC;EAAG;EAAG;EAAG;EAAG;EAAG;EAAG;EAAE,EACrB,GACD,IAEwB,KAAM,MAAM,MAAO,KAAM,MAChD,OACe,OAAO,MAAM,GAAG;;AAGnC,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,SAAS,KAAK,EAAE,SAAS,GAC7B,QAAO,IACL,kBACA,8CACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,+BACD;AAIH,KAAI,EAAE,WAAW,GAAG;AAClB,MAAI,EAAE,OAAO,IACX,QAAO,IACL,qBACA,kCACD;AAEH,MAAI,CAAC,WAAW,EAAE,CAChB,QAAO,IACL,oBACA,iCACD;AAEH,SAAO;GAAE,OAAO;GAAM,SAAS;GAAG;;AAIpC,KAAI,EAAE,WAAW,KAAK,EAAE,OAAO,KAAK;AAClC,MAAI,CAAC,aAAa,EAAE,CAClB,QAAO,IACL,oBACA,0CACD;AAEH,SAAO;GAAE,OAAO;GAAM,SAAS;GAAG;;AAIpC,QAAOA,WAAW,EAAE;;AAGtB,MAAM,UAAU,UACd,KAAK,QAAQ,MAAM;;AAGrB,MAAM,iBAAyB;CAE7B,MAAM,UADQ,OAAO,UAAU,GAAG,EAAE,CAAC,GACb,aAAa,EAAE;CAEvC,MAAM,OAAO,KADD,YAAY,SAAS,aAAa,GAAG,IACxB;CACzB,MAAM,QAAQ,QAAQ,IAAI,IAAI,MAAM;AACpC,QAAO,UAAU,OAAO,MAAM;;;AAIhC,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,OAAO,6BAA6B;CAC9C,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,YAAY,aAAa;CACpC;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"dic.js","names":["validateRc"],"sources":["../../src/cz/dic.ts"],"sourcesContent":["/**\n * DIČ (Daňové identifikační číslo).\n *\n * Czech tax identification number / VAT number.\n * Format: \"CZ\" prefix + 8, 9, or 10 digits.\n * - 8 digits: company (same checksum as IČO,\n * but first digit cannot be 9)\n * - 9 digits starting with 6: special entity\n * - 9-10 digits: individual (birth number)\n *\n * @see https://adisspr.mfcr.cz/dpr/DphReg\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\nimport { validate as validateRc } from \"./rc\";\n\nimport { weightedSum } from \"#checksums/weighted-sum\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst ICO_WEIGHTS = [8, 7, 6, 5, 4, 3, 2] as const;\n\nconst compact = (value: string): string => {\n const v = clean(value, \" -\");\n if (v.startsWith(\"CZ\") || v.startsWith(\"cz\")) {\n return v.slice(2);\n }\n return v;\n};\n\nconst checkLegal = (value: string): boolean => {\n const sum = weightedSum(\n value.slice(0, 7),\n ICO_WEIGHTS,\n 11,\n );\n const v11 = (11 - sum) % 11;\n const check = v11 === 0 ? 1 : v11 % 10;\n return check === Number(value[7]);\n};\n\nconst checkSpecial = (value: string): boolean => {\n // Skip the leading \"6\"; check digits 1..7\n const sum = weightedSum(\n value.slice(1, 8),\n [8, 7, 6, 5, 4, 3, 2],\n 11,\n );\n const check =\n (((8 - ((((10 - sum) % 11) + 11) % 11)) % 10) + 10) %\n 10;\n return check === Number(value[8]);\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length < 8 || v.length > 10) {\n return err(\n \"INVALID_LENGTH\",\n \"DIČ must be 8-10 digits (without CZ prefix)\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"DIČ must contain only digits\",\n );\n }\n\n // 8-digit: legal entity (IČO-like checksum)\n if (v.length === 8) {\n if (v[0] === \"9\") {\n return err(\n \"INVALID_COMPONENT\",\n \"8-digit DIČ cannot start with 9\",\n );\n }\n if (!checkLegal(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"DIČ check digit does not match\",\n );\n }\n return { valid: true, compact: v };\n }\n\n // 9-digit starting with 6: special entity\n if (v.length === 9 && v[0] === \"6\") {\n if (!checkSpecial(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"DIČ special entity check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n }\n\n // 9-10 digit: birth number\n return validateRc(v);\n};\n\nconst format = (value: string): string =>\n `CZ${compact(value)}`;\n\n/** Generate a random valid 8-digit DIČ. */\nconst generate = (): string => {\n const first = String(randomInt(1, 8));\n const payload = first + randomDigits(6);\n const sum = weightedSum(payload, ICO_WEIGHTS, 11);\n const v11 = (11 - sum) % 11;\n const check = v11 === 0 ? 1 : v11 % 10;\n return payload + String(check);\n};\n\n/** Czech VAT Number. */\nconst dic: CountryValidator<\"CZ\"> = {\n name: \"Czech VAT Number\",\n localName: \"Daňové identifikační číslo\",\n abbreviation: \"DIČ\",\n aliases: [\"DIČ\", \"daňové identifikační číslo\"] as const,\n candidatePattern: \"CZ\\\\d{8,10}\",\n scope: \"country\",\n country: \"CZ\",\n entityType: \"any\",\n sourceUrl: \"https://adisspr.mfcr.cz/dpr/DphReg\",\n lengths: [8, 9, 10] as const,\n examples: [\"25123891\", \"7103192745\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default dic;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;AAyBA,MAAM,cAAc;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAAC;AAExC,MAAM,WAAW,UAA0B;CACzC,MAAM,IAAI,MAAM,OAAO,IAAI;CAC3B,IAAI,EAAE,WAAW,IAAI,KAAK,EAAE,WAAW,IAAI,GACzC,OAAO,EAAE,MAAM,CAAC;CAElB,OAAO;AACT;AAEA,MAAM,cAAc,UAA2B;CAM7C,MAAM,OAAO,KALD,YACV,MAAM,MAAM,GAAG,CAAC,GAChB,aACA,EAEkB,KAAK;CAEzB,QADc,QAAQ,IAAI,IAAI,MAAM,QACnB,OAAO,MAAM,EAAE;AAClC;AAEA,MAAM,gBAAgB,UAA2B;CAU/C,SAFK,MAAQ,KAND,YACV,MAAM,MAAM,GAAG,CAAC,GAChB;EAAC;EAAG;EAAG;EAAG;EAAG;EAAG;EAAG;CAAC,GACpB,EAGkB,KAAK,KAAM,MAAM,MAAO,KAAM,MAChD,OACe,OAAO,MAAM,EAAE;AAClC;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,SAAS,KAAK,EAAE,SAAS,IAC7B,OAAO,IACL,kBACA,6CACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,8BACF;CAIF,IAAI,EAAE,WAAW,GAAG;EAClB,IAAI,EAAE,OAAO,KACX,OAAO,IACL,qBACA,iCACF;EAEF,IAAI,CAAC,WAAW,CAAC,GACf,OAAO,IACL,oBACA,gCACF;EAEF,OAAO;GAAE,OAAO;GAAM,SAAS;EAAE;CACnC;CAGA,IAAI,EAAE,WAAW,KAAK,EAAE,OAAO,KAAK;EAClC,IAAI,CAAC,aAAa,CAAC,GACjB,OAAO,IACL,oBACA,yCACF;EAEF,OAAO;GAAE,OAAO;GAAM,SAAS;EAAE;CACnC;CAGA,OAAOA,WAAW,CAAC;AACrB;AAEA,MAAM,UAAU,UACd,KAAK,QAAQ,KAAK;;AAGpB,MAAM,iBAAyB;CAE7B,MAAM,UADQ,OAAO,UAAU,GAAG,CAAC,CACf,IAAI,aAAa,CAAC;CAEtC,MAAM,OAAO,KADD,YAAY,SAAS,aAAa,EAC1B,KAAK;CACzB,MAAM,QAAQ,QAAQ,IAAI,IAAI,MAAM;CACpC,OAAO,UAAU,OAAO,KAAK;AAC/B;;AAGA,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,OAAO,4BAA4B;CAC7C,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WAAW;CACX,SAAS;EAAC;EAAG;EAAG;CAAE;CAClB,UAAU,CAAC,YAAY,YAAY;CACnC;CACA;CACA;CACA;AACF"}
package/dist/cz/ico.d.ts CHANGED
@@ -1,14 +1,13 @@
1
- import { ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ValidateResult } from "../types.js";
2
2
 
3
3
  //#region src/cz/ico.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;
8
7
  /** Generate a random valid ICO. */
9
8
  declare const generate: () => string;
10
9
  /** Czech Company Identification Number. */
11
- declare const ico: Validator;
10
+ declare const ico: CountryValidator<"CZ">;
12
11
  //#endregion
13
12
  export { compact, ico as default, format, generate, validate };
14
13
  //# sourceMappingURL=ico.d.ts.map
package/dist/cz/ico.js CHANGED
@@ -1,18 +1,9 @@
1
+ import { weightedSum } from "../_checksums/weighted-sum.js";
1
2
  import { clean } from "../_util/clean.js";
2
3
  import { randomDigits } from "../_util/generate.js";
3
4
  import { err } from "../_util/result.js";
4
5
  import { isdigits } from "../_util/strings.js";
5
- import { weightedSum } from "../_checksums/weighted-sum.js";
6
6
  //#region src/cz/ico.ts
7
- /**
8
- * IČO (Identifikační číslo osoby).
9
- *
10
- * Czech company identification number. 8 digits
11
- * with a weighted checksum. Assigned by the Czech
12
- * Statistical Office.
13
- *
14
- * @see https://www.czso.cz/
15
- */
16
7
  const WEIGHTS = [
17
8
  8,
18
9
  7,
@@ -53,6 +44,7 @@ const ico = {
53
44
  "identifikační číslo"
54
45
  ],
55
46
  candidatePattern: "\\d{8}",
47
+ scope: "country",
56
48
  country: "CZ",
57
49
  entityType: "company",
58
50
  description: "8-digit company ID assigned by the Czech Statistical Office",
@@ -1 +1 @@
1
- {"version":3,"file":"ico.js","names":[],"sources":["../../src/cz/ico.ts"],"sourcesContent":["/**\n * IČO (Identifikační číslo osoby).\n *\n * Czech company identification number. 8 digits\n * with a weighted checksum. Assigned by the Czech\n * Statistical Office.\n *\n * @see https://www.czso.cz/\n */\n\nimport { weightedSum } from \"#checksums/weighted-sum\";\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 = [8, 7, 6, 5, 4, 3, 2] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 8) {\n return err(\n \"INVALID_LENGTH\",\n \"IČO must be exactly 8 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"IČO must contain only digits\",\n );\n }\n const sum = weightedSum(v.slice(0, 7), WEIGHTS, 11);\n const v11 = (11 - sum) % 11;\n const check = v11 === 0 ? 1 : v11 % 10;\n if (check !== Number(v[7])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"IČO check digit does not match\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid ICO. */\nconst generate = (): string => {\n const payload = randomDigits(7);\n const sum = weightedSum(payload, WEIGHTS, 11);\n const v11 = (11 - sum) % 11;\n const check = v11 === 0 ? 1 : v11 % 10;\n return `${payload}${String(check)}`;\n};\n\n/** Czech Company Identification Number. */\nconst ico: Validator = {\n name: \"Czech Company ID\",\n localName: \"Identifikační číslo osoby\",\n abbreviation: \"IČO\",\n aliases: [\"IČO\", \"IČ\", \"identifikační číslo\"] as const,\n candidatePattern: \"\\\\d{8}\",\n country: \"CZ\",\n entityType: \"company\",\n description:\n \"8-digit company ID assigned by the Czech Statistical Office\",\n sourceUrl: \"https://www.czso.cz/\",\n lengths: [8] as const,\n examples: [\"25123891\", \"27074358\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default ico;\nexport { compact, format, generate, validate };\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAErC,MAAM,WAAW,UACf,MAAM,OAAO,KAAK;AAEpB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,IACL,kBACA,+BACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,+BACD;CAGH,MAAM,OAAO,KADD,YAAY,EAAE,MAAM,GAAG,EAAE,EAAE,SAAS,GAAG,IAC1B;AAEzB,MADc,QAAQ,IAAI,IAAI,MAAM,QACtB,OAAO,EAAE,GAAG,CACxB,QAAO,IACL,oBACA,iCACD;AAEH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B,QAAQ,MAAM;;AAGxD,MAAM,iBAAyB;CAC7B,MAAM,UAAU,aAAa,EAAE;CAE/B,MAAM,OAAO,KADD,YAAY,SAAS,SAAS,GAAG,IACpB;CACzB,MAAM,QAAQ,QAAQ,IAAI,IAAI,MAAM;AACpC,QAAO,GAAG,UAAU,OAAO,MAAM;;;AAInC,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EAAC;EAAO;EAAM;EAAsB;CAC7C,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,aACE;CACF,WAAW;CACX,SAAS,CAAC,EAAE;CACZ,UAAU,CAAC,YAAY,WAAW;CAClC;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"ico.js","names":[],"sources":["../../src/cz/ico.ts"],"sourcesContent":["/**\n * IČO (Identifikační číslo osoby).\n *\n * Czech company identification number. 8 digits\n * with a weighted checksum. Assigned by the Czech\n * Statistical Office.\n *\n * @see https://www.czso.cz/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { weightedSum } from \"#checksums/weighted-sum\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst WEIGHTS = [8, 7, 6, 5, 4, 3, 2] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 8) {\n return err(\n \"INVALID_LENGTH\",\n \"IČO must be exactly 8 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"IČO must contain only digits\",\n );\n }\n const sum = weightedSum(v.slice(0, 7), WEIGHTS, 11);\n const v11 = (11 - sum) % 11;\n const check = v11 === 0 ? 1 : v11 % 10;\n if (check !== Number(v[7])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"IČO check digit does not match\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid ICO. */\nconst generate = (): string => {\n const payload = randomDigits(7);\n const sum = weightedSum(payload, WEIGHTS, 11);\n const v11 = (11 - sum) % 11;\n const check = v11 === 0 ? 1 : v11 % 10;\n return `${payload}${String(check)}`;\n};\n\n/** Czech Company Identification Number. */\nconst ico: CountryValidator<\"CZ\"> = {\n name: \"Czech Company ID\",\n localName: \"Identifikační číslo osoby\",\n abbreviation: \"IČO\",\n aliases: [\"IČO\", \"IČ\", \"identifikační číslo\"] as const,\n candidatePattern: \"\\\\d{8}\",\n scope: \"country\",\n country: \"CZ\",\n entityType: \"company\",\n description:\n \"8-digit company ID assigned by the Czech Statistical Office\",\n sourceUrl: \"https://www.czso.cz/\",\n lengths: [8] as const,\n examples: [\"25123891\", \"27074358\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default ico;\nexport { compact, format, generate, validate };\n"],"mappings":";;;;;;AAqBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAAC;AAEpC,MAAM,WAAW,UACf,MAAM,OAAO,IAAI;AAEnB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,GACf,OAAO,IACL,kBACA,8BACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,8BACF;CAGF,MAAM,OAAO,KADD,YAAY,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,EAC5B,KAAK;CAEzB,KADc,QAAQ,IAAI,IAAI,MAAM,QACtB,OAAO,EAAE,EAAE,GACvB,OAAO,IACL,oBACA,gCACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B,QAAQ,KAAK;;AAGvD,MAAM,iBAAyB;CAC7B,MAAM,UAAU,aAAa,CAAC;CAE9B,MAAM,OAAO,KADD,YAAY,SAAS,SAAS,EACtB,KAAK;CACzB,MAAM,QAAQ,QAAQ,IAAI,IAAI,MAAM;CACpC,OAAO,GAAG,UAAU,OAAO,KAAK;AAClC;;AAGA,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EAAC;EAAO;EAAM;CAAqB;CAC5C,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,aACE;CACF,WAAW;CACX,SAAS,CAAC,CAAC;CACX,UAAU,CAAC,YAAY,UAAU;CACjC;CACA;CACA;CACA;AACF"}
package/dist/cz/mod.d.ts CHANGED
@@ -1,10 +1,11 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
1
  import dic from "./dic.js";
3
2
  import ico from "./ico.js";
4
3
  import rc from "./rc.js";
5
4
 
6
5
  //#region src/cz/mod.d.ts
7
-
6
+ declare namespace mod_d_exports {
7
+ export { dic, ico, rc };
8
+ }
8
9
  //#endregion
9
10
  export { dic, ico, mod_d_exports, rc };
10
11
  //# sourceMappingURL=mod.d.ts.map
package/dist/cz/rc.d.ts CHANGED
@@ -1,7 +1,6 @@
1
- import { ParsedPersonId, ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ParsedPersonId, ValidateResult } from "../types.js";
2
2
 
3
3
  //#region src/cz/rc.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;
@@ -16,7 +15,7 @@ declare const parse: (value: string) => ParsedPersonId | null;
16
15
  */
17
16
  declare const generate: () => string;
18
17
  /** Czech/Slovak Birth Number. */
19
- declare const rc: Validator;
18
+ declare const rc: CountryValidator<"CZ", ParsedPersonId>;
20
19
  //#endregion
21
20
  export { compact, rc as default, format, generate, parse, validate };
22
21
  //# sourceMappingURL=rc.d.ts.map
package/dist/cz/rc.js CHANGED
@@ -1,25 +1,23 @@
1
1
  import { clean } from "../_util/clean.js";
2
+ import { isValidDate } from "../_util/date.js";
2
3
  import { randomInt } from "../_util/generate.js";
3
4
  import { err } from "../_util/result.js";
4
5
  import { isdigits } from "../_util/strings.js";
5
- import { isValidDate } from "../_util/date.js";
6
6
  //#region src/cz/rc.ts
7
- /**
8
- * RČ (Rodné číslo).
9
- *
10
- * Czech and Slovak national identifier (birth
11
- * number). 9 or 10 digits encoding date of birth
12
- * and gender. 10-digit numbers (post-1954) must
13
- * be divisible by 11.
14
- *
15
- * Women have 50 added to the month. Since 2004,
16
- * an extra +20 offset is used when the serial
17
- * range is exhausted.
18
- *
19
- * @see https://www.mvcr.cz/mvcren/docDetail.aspx?docid=21975362&doctype=ART
20
- * @see Law 133/2000 Sb.
21
- */
22
7
  const compact = (value) => clean(value, " /");
8
+ const decodeMonth = (rawMonth, year, length) => {
9
+ const candidates = length === 10 && year >= 2004 ? [
10
+ 0,
11
+ 50,
12
+ 20,
13
+ 70
14
+ ] : [0, 50];
15
+ for (const offset of candidates) {
16
+ const month = rawMonth - offset;
17
+ if (month >= 1 && month <= 12) return month;
18
+ }
19
+ return null;
20
+ };
23
21
  const validate = (value) => {
24
22
  const v = compact(value);
25
23
  if (v.length !== 9 && v.length !== 10) return err("INVALID_LENGTH", "Birth number must be 9 or 10 digits");
@@ -27,14 +25,14 @@ const validate = (value) => {
27
25
  const yy = Number(v.slice(0, 2));
28
26
  const mm = Number(v.slice(2, 4));
29
27
  const dd = Number(v.slice(4, 6));
30
- const month = mm % 50 % 20 || mm % 50;
31
- if (month < 1 || month > 12) return err("INVALID_COMPONENT", "Birth number contains an invalid month");
32
- if (dd < 1 || dd > 31) return err("INVALID_COMPONENT", "Birth number contains an invalid day");
33
28
  let year = yy + 1900;
34
29
  if (v.length === 9) {
35
30
  if (year >= 1980) year -= 100;
36
31
  if (year > 1953) return err("INVALID_COMPONENT", "9-digit birth numbers are pre-1954 only");
37
32
  } else if (year < 1954) year += 100;
33
+ const month = decodeMonth(mm, year, v.length);
34
+ if (month === null) return err("INVALID_COMPONENT", "Birth number contains an invalid month");
35
+ if (dd < 1 || dd > 31) return err("INVALID_COMPONENT", "Birth number contains an invalid day");
38
36
  if (!isValidDate(year, month, dd)) return err("INVALID_COMPONENT", "Birth number contains an invalid date");
39
37
  if (v.length === 10) {
40
38
  const check = Number(v.slice(0, 9)) % 11 % 10;
@@ -60,11 +58,12 @@ const parse = (value) => {
60
58
  const yy = Number(v.slice(0, 2));
61
59
  const mm = Number(v.slice(2, 4));
62
60
  const dd = Number(v.slice(4, 6));
63
- const gender = mm > 50 ? "female" : "male";
64
- const month = mm % 50 % 20 || mm % 50;
61
+ const gender = mm >= 50 ? "female" : "male";
65
62
  let year = yy + 1900;
66
63
  if (v.length === 10 && year < 1954) year += 100;
67
64
  if (v.length === 9 && year >= 1980) year -= 100;
65
+ const month = decodeMonth(mm, year, v.length);
66
+ if (month === null) return null;
68
67
  return {
69
68
  birthDate: new Date(year, month - 1, dd),
70
69
  gender
@@ -99,6 +98,7 @@ const rc = {
99
98
  "birth number"
100
99
  ],
101
100
  candidatePattern: "\\d{6}/\\d{3,4}",
101
+ scope: "country",
102
102
  country: "CZ",
103
103
  entityType: "person",
104
104
  description: "Czech/Slovak national identifier encoding birth date and gender",
@@ -107,6 +107,7 @@ const rc = {
107
107
  examples: ["7103192745"],
108
108
  compact,
109
109
  format,
110
+ parse,
110
111
  validate,
111
112
  generate
112
113
  };
package/dist/cz/rc.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"rc.js","names":[],"sources":["../../src/cz/rc.ts"],"sourcesContent":["/**\n * RČ (Rodné číslo).\n *\n * Czech and Slovak national identifier (birth\n * number). 9 or 10 digits encoding date of birth\n * and gender. 10-digit numbers (post-1954) must\n * be divisible by 11.\n *\n * Women have 50 added to the month. Since 2004,\n * an extra +20 offset is used when the serial\n * range is exhausted.\n *\n * @see https://www.mvcr.cz/mvcren/docDetail.aspx?docid=21975362&doctype=ART\n * @see Law 133/2000 Sb.\n */\n\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, \" /\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 9 && v.length !== 10) {\n return err(\n \"INVALID_LENGTH\",\n \"Birth number must be 9 or 10 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Birth number 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\n // Strip gender (+50) and overflow (+20) offsets\n const month = (mm % 50) % 20 || mm % 50;\n if (month < 1 || month > 12) {\n return err(\n \"INVALID_COMPONENT\",\n \"Birth number contains an invalid month\",\n );\n }\n\n if (dd < 1 || dd > 31) {\n return err(\n \"INVALID_COMPONENT\",\n \"Birth number contains an invalid day\",\n );\n }\n\n // Resolve full year\n let year = yy + 1900;\n if (v.length === 9) {\n // 9-digit: pre-1954 only\n if (year >= 1980) year -= 100;\n if (year > 1953) {\n return err(\n \"INVALID_COMPONENT\",\n \"9-digit birth numbers are pre-1954 only\",\n );\n }\n } else {\n // 10-digit: if year < 1954, it's 2000s\n if (year < 1954) year += 100;\n }\n\n // Validate the actual date\n if (!isValidDate(year, month, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Birth number contains an invalid date\",\n );\n }\n\n // 10-digit: check digit is first 9 digits\n // mod 11 mod 10\n if (v.length === 10) {\n const front = Number(v.slice(0, 9));\n const check = (front % 11) % 10;\n if (String(check) !== v[9]) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Birth number is not divisible by 11\",\n );\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, 6)}/${v.slice(6)}`;\n};\n\n/**\n * Extract birth date and gender from a birth 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 const yy = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const dd = Number(v.slice(4, 6));\n\n const gender = mm > 50 ? \"female\" : \"male\";\n const month = (mm % 50) % 20 || mm % 50;\n\n let year = yy + 1900;\n if (v.length === 10 && year < 1954) year += 100;\n if (v.length === 9 && year >= 1980) year -= 100;\n\n return {\n birthDate: new Date(year, month - 1, dd),\n gender,\n };\n};\n\n/**\n * Generate a random valid 10-digit birth number.\n * Uses a random date between 1954 and 2024.\n */\nconst generate = (): string => {\n const year = randomInt(1954, 2024);\n const month = randomInt(1, 12);\n const day = randomInt(1, 28);\n const isFemale = Math.random() < 0.5;\n const mm = isFemale ? month + 50 : month;\n\n const yy = String(year % 100).padStart(2, \"0\");\n const mmStr = String(mm).padStart(2, \"0\");\n const dd = String(day).padStart(2, \"0\");\n\n const datePart = `${yy}${mmStr}${dd}`;\n for (let seq = 0; seq < 1000; seq++) {\n const seqStr = String(seq).padStart(3, \"0\");\n const front = `${datePart}${seqStr}`;\n const num = Number(front);\n const check = (num % 11) % 10;\n const result = `${front}${String(check)}`;\n if (validate(result).valid) {\n return result;\n }\n }\n\n throw new Error(\"Failed to generate valid birth number\");\n};\n\n/** Czech/Slovak Birth Number. */\nconst rc: Validator = {\n name: \"Czech Birth Number\",\n localName: \"Rodné číslo\",\n abbreviation: \"RČ\",\n aliases: [\"rodné číslo\", \"RČ\", \"birth number\"] as const,\n candidatePattern: \"\\\\d{6}/\\\\d{3,4}\",\n country: \"CZ\",\n entityType: \"person\",\n description:\n \"Czech/Slovak national identifier encoding birth date and gender\",\n sourceUrl:\n \"https://www.mvcr.cz/mvcren/docDetail.aspx?docid=21975362&doctype=ART\",\n lengths: [9, 10] as const,\n examples: [\"7103192745\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default rc;\nexport { compact, format, generate, parse, validate };\n"],"mappings":"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"}
1
+ {"version":3,"file":"rc.js","names":[],"sources":["../../src/cz/rc.ts"],"sourcesContent":["/**\n * RČ (Rodné číslo).\n *\n * Czech and Slovak national identifier (birth\n * number). 9 or 10 digits encoding date of birth\n * and gender. 10-digit numbers (post-1954) must\n * be divisible by 11.\n *\n * Women have 50 added to the month. For modern\n * 10-digit numbers, an additional +20 offset may\n * be used when the daily serial range is exhausted\n * (+70 for women).\n *\n * Canonical source:\n * - Czech Ministry of the Interior guidance on rodne\n * cislo, with the modern overflow-month rules\n *\n * We use this to keep the 9-digit historical form\n * valid while rejecting modern +20/+70 month offsets\n * on 9-digit numbers. Those overflow offsets are a\n * modern rule for 10-digit values.\n *\n * @see https://www.mvcr.cz/mvcren/docDetail.aspx?docid=21975362&doctype=ART\n * @see Law 133/2000 Sb.\n */\n\nimport type {\n ParsedPersonId,\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\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\nconst compact = (value: string): string =>\n clean(value, \" /\");\n\nconst decodeMonth = (\n rawMonth: number,\n year: number,\n length: number,\n): number | null => {\n const candidates =\n length === 10 && year >= 2004\n ? [0, 50, 20, 70]\n : [0, 50];\n for (const offset of candidates) {\n const month = rawMonth - offset;\n if (month >= 1 && month <= 12) {\n return month;\n }\n }\n return null;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 9 && v.length !== 10) {\n return err(\n \"INVALID_LENGTH\",\n \"Birth number must be 9 or 10 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Birth number 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\n // Resolve full year\n let year = yy + 1900;\n if (v.length === 9) {\n // 9-digit: pre-1954 only\n if (year >= 1980) year -= 100;\n if (year > 1953) {\n return err(\n \"INVALID_COMPONENT\",\n \"9-digit birth numbers are pre-1954 only\",\n );\n }\n } else {\n // 10-digit: if year < 1954, it's 2000s\n if (year < 1954) year += 100;\n }\n\n const month = decodeMonth(mm, year, v.length);\n if (month === null) {\n return err(\n \"INVALID_COMPONENT\",\n \"Birth number contains an invalid month\",\n );\n }\n\n if (dd < 1 || dd > 31) {\n return err(\n \"INVALID_COMPONENT\",\n \"Birth number contains an invalid day\",\n );\n }\n\n // Validate the actual date\n if (!isValidDate(year, month, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Birth number contains an invalid date\",\n );\n }\n\n // 10-digit: check digit is first 9 digits\n // mod 11 mod 10\n if (v.length === 10) {\n const front = Number(v.slice(0, 9));\n const check = (front % 11) % 10;\n if (String(check) !== v[9]) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Birth number is not divisible by 11\",\n );\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, 6)}/${v.slice(6)}`;\n};\n\n/**\n * Extract birth date and gender from a birth 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 const yy = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const dd = Number(v.slice(4, 6));\n\n const gender = mm >= 50 ? \"female\" : \"male\";\n let year = yy + 1900;\n if (v.length === 10 && year < 1954) year += 100;\n if (v.length === 9 && year >= 1980) year -= 100;\n\n const month = decodeMonth(mm, year, v.length);\n if (month === null) {\n return null;\n }\n\n return {\n birthDate: new Date(year, month - 1, dd),\n gender,\n };\n};\n\n/**\n * Generate a random valid 10-digit birth number.\n * Uses a random date between 1954 and 2024.\n */\nconst generate = (): string => {\n const year = randomInt(1954, 2024);\n const month = randomInt(1, 12);\n const day = randomInt(1, 28);\n const isFemale = Math.random() < 0.5;\n const mm = isFemale ? month + 50 : month;\n\n const yy = String(year % 100).padStart(2, \"0\");\n const mmStr = String(mm).padStart(2, \"0\");\n const dd = String(day).padStart(2, \"0\");\n\n const datePart = `${yy}${mmStr}${dd}`;\n for (let seq = 0; seq < 1000; seq++) {\n const seqStr = String(seq).padStart(3, \"0\");\n const front = `${datePart}${seqStr}`;\n const num = Number(front);\n const check = (num % 11) % 10;\n const result = `${front}${String(check)}`;\n if (validate(result).valid) {\n return result;\n }\n }\n\n throw new Error(\"Failed to generate valid birth number\");\n};\n\n/** Czech/Slovak Birth Number. */\nconst rc: CountryValidator<\"CZ\", ParsedPersonId> = {\n name: \"Czech Birth Number\",\n localName: \"Rodné číslo\",\n abbreviation: \"RČ\",\n aliases: [\"rodné číslo\", \"RČ\", \"birth number\"] as const,\n candidatePattern: \"\\\\d{6}/\\\\d{3,4}\",\n scope: \"country\",\n country: \"CZ\",\n entityType: \"person\",\n description:\n \"Czech/Slovak national identifier encoding birth date and gender\",\n sourceUrl:\n \"https://www.mvcr.cz/mvcren/docDetail.aspx?docid=21975362&doctype=ART\",\n lengths: [9, 10] as const,\n examples: [\"7103192745\"] as const,\n compact,\n format,\n parse,\n validate,\n generate,\n};\n\nexport default rc;\nexport { compact, format, generate, parse, validate };\n"],"mappings":"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"}
@@ -1,8 +1,25 @@
1
- import { ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ValidateResult } from "../types.js";
2
2
 
3
3
  //#region src/de/handelsreg.d.ts
4
4
  /** Generate a random valid Handelsregisternummer. */
5
5
  declare const generate: () => string;
6
+ /**
7
+ * Handelsregisternummer (German Company Register Number).
8
+ *
9
+ * German commercial register number assigned by the
10
+ * local court (Amtsgericht). Format: register type
11
+ * (HRA, HRB, GnR, PR, VR) + number.
12
+ *
13
+ * HRA = Handelsregister Abteilung A (partnerships,
14
+ * sole proprietors). HRB = Abteilung B (corporations).
15
+ * GnR = Genossenschaftsregister.
16
+ * PR = Partnerschaftsregister.
17
+ * VR = Vereinsregister.
18
+ *
19
+ * No check digit; validation is structural only.
20
+ *
21
+ * @see https://de.wikipedia.org/wiki/Handelsregister_(Deutschland)
22
+ */
6
23
  /**
7
24
  * Strip separators and normalize to canonical form.
8
25
  * Accepts "HRB 12345", "HRB12345", "hrb 12345".
@@ -11,7 +28,7 @@ declare const compact: (value: string) => string;
11
28
  declare const validate: (value: string) => ValidateResult;
12
29
  declare const format: (value: string) => string;
13
30
  /** German Company Register Number. */
14
- declare const handelsreg: Validator;
31
+ declare const handelsreg: CountryValidator<"DE">;
15
32
  //#endregion
16
33
  export { compact, handelsreg as default, format, generate, validate };
17
34
  //# sourceMappingURL=handelsreg.d.ts.map
@@ -1,34 +1,17 @@
1
1
  import { clean } from "../_util/clean.js";
2
- import { randomDigits, randomInt } from "../_util/generate.js";
2
+ import { randomDigits, randomPick } from "../_util/generate.js";
3
3
  import { err } from "../_util/result.js";
4
4
  //#region src/de/handelsreg.ts
5
- /**
6
- * Handelsregisternummer (German Company Register Number).
7
- *
8
- * German commercial register number assigned by the
9
- * local court (Amtsgericht). Format: register type
10
- * (HRA, HRB, GnR, PR, VR) + number.
11
- *
12
- * HRA = Handelsregister Abteilung A (partnerships,
13
- * sole proprietors). HRB = Abteilung B (corporations).
14
- * GnR = Genossenschaftsregister.
15
- * PR = Partnerschaftsregister.
16
- * VR = Vereinsregister.
17
- *
18
- * No check digit; validation is structural only.
19
- *
20
- * @see https://de.wikipedia.org/wiki/Handelsregister_(Deutschland)
21
- */
5
+ const GENERATE_TYPES = [
6
+ "HRA",
7
+ "HRB",
8
+ "GNR",
9
+ "PR",
10
+ "VR"
11
+ ];
22
12
  /** Generate a random valid Handelsregisternummer. */
23
13
  const generate = () => {
24
- const types = [
25
- "HRA",
26
- "HRB",
27
- "GNR",
28
- "PR",
29
- "VR"
30
- ];
31
- return `${types[randomInt(0, types.length - 1)]} ${randomDigits(5)}`;
14
+ return `${randomPick(GENERATE_TYPES)} ${randomDigits(5)}`;
32
15
  };
33
16
  const REGISTER_TYPES = new Set([
34
17
  "HRA",
@@ -71,6 +54,7 @@ const handelsreg = {
71
54
  "HRA"
72
55
  ],
73
56
  candidatePattern: "(?:HRA|HRB|GnR|PR|VR)\\s*\\d{1,7}",
57
+ scope: "country",
74
58
  country: "DE",
75
59
  entityType: "company",
76
60
  sourceUrl: "https://de.wikipedia.org/wiki/Handelsregister_(Deutschland)",