@stll/stdnum 1.0.0 → 2.0.1

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 (705) hide show
  1. package/README.md +1 -4
  2. package/dist/_checksums/luhn.js.map +1 -1
  3. package/dist/_checksums/mod1110.js +1 -1
  4. package/dist/_checksums/mod1110.js.map +1 -1
  5. package/dist/_checksums/mod112.js.map +1 -1
  6. package/dist/_checksums/mod97.js.map +1 -1
  7. package/dist/_checksums/verhoeff.js.map +1 -1
  8. package/dist/_checksums/weighted-sum.js.map +1 -1
  9. package/dist/_util/arabic.js.map +1 -1
  10. package/dist/_util/clean.js.map +1 -1
  11. package/dist/_util/date.js.map +1 -1
  12. package/dist/_util/generate.js.map +1 -1
  13. package/dist/_util/result.js.map +1 -1
  14. package/dist/_util/strings.js.map +1 -1
  15. package/dist/ad/nrt.d.ts +16 -2
  16. package/dist/ad/nrt.js +1 -14
  17. package/dist/ad/nrt.js.map +1 -1
  18. package/dist/ae/eid.d.ts +2 -2
  19. package/dist/ae/eid.js +2 -12
  20. package/dist/ae/eid.js.map +1 -1
  21. package/dist/ai/tin.d.ts +20 -2
  22. package/dist/ai/tin.js +1 -18
  23. package/dist/ai/tin.js.map +1 -1
  24. package/dist/al/nipt.d.ts +13 -2
  25. package/dist/al/nipt.js +1 -11
  26. package/dist/al/nipt.js.map +1 -1
  27. package/dist/am/tin.d.ts +16 -2
  28. package/dist/am/tin.js +1 -14
  29. package/dist/am/tin.js.map +1 -1
  30. package/dist/ar/cbu.d.ts +2 -2
  31. package/dist/ar/cbu.js +1 -9
  32. package/dist/ar/cbu.js.map +1 -1
  33. package/dist/ar/cuit.d.ts +2 -2
  34. package/dist/ar/cuit.js +1 -17
  35. package/dist/ar/cuit.js.map +1 -1
  36. package/dist/ar/dni.d.ts +11 -2
  37. package/dist/ar/dni.js +1 -9
  38. package/dist/ar/dni.js.map +1 -1
  39. package/dist/at/businessid.d.ts +10 -2
  40. package/dist/at/businessid.js +1 -8
  41. package/dist/at/businessid.js.map +1 -1
  42. package/dist/at/tin.d.ts +2 -2
  43. package/dist/at/tin.js +1 -11
  44. package/dist/at/tin.js.map +1 -1
  45. package/dist/at/uid.d.ts +2 -2
  46. package/dist/at/uid.js +2 -10
  47. package/dist/at/uid.js.map +1 -1
  48. package/dist/at/vnr.d.ts +2 -2
  49. package/dist/at/vnr.js +4 -14
  50. package/dist/at/vnr.js.map +1 -1
  51. package/dist/au/abn.d.ts +2 -2
  52. package/dist/au/abn.js +1 -10
  53. package/dist/au/abn.js.map +1 -1
  54. package/dist/au/acn.d.ts +2 -2
  55. package/dist/au/acn.js +1 -10
  56. package/dist/au/acn.js.map +1 -1
  57. package/dist/au/tfn.d.ts +2 -2
  58. package/dist/au/tfn.js +1 -10
  59. package/dist/au/tfn.js.map +1 -1
  60. package/dist/az/voen.d.ts +2 -2
  61. package/dist/az/voen.js +1 -14
  62. package/dist/az/voen.js.map +1 -1
  63. package/dist/ba/jmbg.d.ts +2 -2
  64. package/dist/ba/jmbg.js +3 -11
  65. package/dist/ba/jmbg.js.map +1 -1
  66. package/dist/bd/nid.d.ts +23 -2
  67. package/dist/bd/nid.js +1 -21
  68. package/dist/bd/nid.js.map +1 -1
  69. package/dist/be/bis.d.ts +2 -2
  70. package/dist/be/bis.js +1 -11
  71. package/dist/be/bis.js.map +1 -1
  72. package/dist/be/nn.d.ts +2 -2
  73. package/dist/be/nn.js +1 -11
  74. package/dist/be/nn.js.map +1 -1
  75. package/dist/be/vat.d.ts +2 -2
  76. package/dist/be/vat.js +1 -9
  77. package/dist/be/vat.js.map +1 -1
  78. package/dist/bg/egn.d.ts +2 -2
  79. package/dist/bg/egn.js +3 -18
  80. package/dist/bg/egn.js.map +1 -1
  81. package/dist/bg/pnf.d.ts +2 -2
  82. package/dist/bg/pnf.js +1 -8
  83. package/dist/bg/pnf.js.map +1 -1
  84. package/dist/bg/vat.d.ts +2 -2
  85. package/dist/bg/vat.js +3 -9
  86. package/dist/bg/vat.js.map +1 -1
  87. package/dist/bh/cpr.d.ts +2 -2
  88. package/dist/bh/cpr.js +1 -17
  89. package/dist/bh/cpr.js.map +1 -1
  90. package/dist/bic.d.ts +13 -2
  91. package/dist/bic.js +1 -11
  92. package/dist/bic.js.map +1 -1
  93. package/dist/br/cnpj.d.ts +2 -2
  94. package/dist/br/cnpj.js +1 -20
  95. package/dist/br/cnpj.js.map +1 -1
  96. package/dist/br/cpf.d.ts +2 -2
  97. package/dist/br/cpf.js +1 -14
  98. package/dist/br/cpf.js.map +1 -1
  99. package/dist/by/unp.d.ts +2 -2
  100. package/dist/by/unp.js +3 -14
  101. package/dist/by/unp.js.map +1 -1
  102. package/dist/bz/tin.d.ts +2 -2
  103. package/dist/bz/tin.js +1 -26
  104. package/dist/bz/tin.js.map +1 -1
  105. package/dist/ca/bn.d.ts +2 -2
  106. package/dist/ca/bn.js +2 -10
  107. package/dist/ca/bn.js.map +1 -1
  108. package/dist/ca/sin.d.ts +2 -2
  109. package/dist/ca/sin.js +2 -10
  110. package/dist/ca/sin.js.map +1 -1
  111. package/dist/ch/ssn.d.ts +2 -2
  112. package/dist/ch/ssn.js +1 -9
  113. package/dist/ch/ssn.js.map +1 -1
  114. package/dist/ch/uid.d.ts +2 -2
  115. package/dist/ch/uid.js +1 -9
  116. package/dist/ch/uid.js.map +1 -1
  117. package/dist/ch/vat.d.ts +2 -2
  118. package/dist/ch/vat.js +1 -9
  119. package/dist/ch/vat.js.map +1 -1
  120. package/dist/cl/rut.d.ts +2 -2
  121. package/dist/cl/rut.js +1 -14
  122. package/dist/cl/rut.js.map +1 -1
  123. package/dist/cn/ric.d.ts +2 -2
  124. package/dist/cn/ric.js +3 -14
  125. package/dist/cn/ric.js.map +1 -1
  126. package/dist/cn/uscc.d.ts +2 -2
  127. package/dist/cn/uscc.js +1 -10
  128. package/dist/cn/uscc.js.map +1 -1
  129. package/dist/co/nit.d.ts +2 -2
  130. package/dist/co/nit.js +2 -12
  131. package/dist/co/nit.js.map +1 -1
  132. package/dist/cr/cpf.d.ts +18 -2
  133. package/dist/cr/cpf.js +1 -16
  134. package/dist/cr/cpf.js.map +1 -1
  135. package/dist/creditcard.d.ts +2 -2
  136. package/dist/creditcard.js +5 -14
  137. package/dist/creditcard.js.map +1 -1
  138. package/dist/cu/ni.d.ts +2 -2
  139. package/dist/cu/ni.js +2 -17
  140. package/dist/cu/ni.js.map +1 -1
  141. package/dist/cy/vat.d.ts +2 -2
  142. package/dist/cy/vat.js +1 -8
  143. package/dist/cy/vat.js.map +1 -1
  144. package/dist/cz/dic.d.ts +2 -2
  145. package/dist/cz/dic.js +7 -13
  146. package/dist/cz/dic.js.map +1 -1
  147. package/dist/cz/ico.d.ts +2 -2
  148. package/dist/cz/ico.js +2 -10
  149. package/dist/cz/ico.js.map +1 -1
  150. package/dist/cz/rc.d.ts +2 -2
  151. package/dist/cz/rc.js +2 -26
  152. package/dist/cz/rc.js.map +1 -1
  153. package/dist/de/handelsreg.d.ts +19 -2
  154. package/dist/de/handelsreg.js +1 -17
  155. package/dist/de/handelsreg.js.map +1 -1
  156. package/dist/de/idnr.d.ts +2 -2
  157. package/dist/de/idnr.js +2 -12
  158. package/dist/de/idnr.js.map +1 -1
  159. package/dist/de/stnr.d.ts +17 -2
  160. package/dist/de/stnr.js +1 -15
  161. package/dist/de/stnr.js.map +1 -1
  162. package/dist/de/svnr.d.ts +2 -2
  163. package/dist/de/svnr.js +2 -11
  164. package/dist/de/svnr.js.map +1 -1
  165. package/dist/de/vat.d.ts +2 -2
  166. package/dist/de/vat.js +2 -11
  167. package/dist/de/vat.js.map +1 -1
  168. package/dist/dk/cpr.d.ts +2 -2
  169. package/dist/dk/cpr.js +2 -10
  170. package/dist/dk/cpr.js.map +1 -1
  171. package/dist/dk/cvr.d.ts +2 -2
  172. package/dist/dk/cvr.js +2 -15
  173. package/dist/dk/cvr.js.map +1 -1
  174. package/dist/dk/vat.d.ts +2 -2
  175. package/dist/dk/vat.js +3 -13
  176. package/dist/dk/vat.js.map +1 -1
  177. package/dist/do/rnc.d.ts +2 -2
  178. package/dist/do/rnc.js +2 -16
  179. package/dist/do/rnc.js.map +1 -1
  180. package/dist/ec/ruc.d.ts +2 -2
  181. package/dist/ec/ruc.js +1 -18
  182. package/dist/ec/ruc.js.map +1 -1
  183. package/dist/ee/ik.d.ts +2 -2
  184. package/dist/ee/ik.js +3 -20
  185. package/dist/ee/ik.js.map +1 -1
  186. package/dist/ee/registrikood.d.ts +2 -2
  187. package/dist/ee/registrikood.js +1 -8
  188. package/dist/ee/registrikood.js.map +1 -1
  189. package/dist/ee/vat.d.ts +2 -2
  190. package/dist/ee/vat.js +2 -10
  191. package/dist/ee/vat.js.map +1 -1
  192. package/dist/eg/tn.d.ts +11 -2
  193. package/dist/eg/tn.js +1 -9
  194. package/dist/eg/tn.js.map +1 -1
  195. package/dist/es/cif.d.ts +2 -2
  196. package/dist/es/cif.js +1 -10
  197. package/dist/es/cif.js.map +1 -1
  198. package/dist/es/dni.d.ts +2 -2
  199. package/dist/es/dni.js +1 -9
  200. package/dist/es/dni.js.map +1 -1
  201. package/dist/es/nie.d.ts +2 -2
  202. package/dist/es/nie.js +1 -9
  203. package/dist/es/nie.js.map +1 -1
  204. package/dist/es/nss.d.ts +2 -2
  205. package/dist/es/nss.js +1 -16
  206. package/dist/es/nss.js.map +1 -1
  207. package/dist/es/vat.d.ts +2 -2
  208. package/dist/es/vat.js +5 -10
  209. package/dist/es/vat.js.map +1 -1
  210. package/dist/eu/vat.d.ts +2 -2
  211. package/dist/eu/vat.js +1 -0
  212. package/dist/eu/vat.js.map +1 -1
  213. package/dist/fi/hetu.d.ts +2 -2
  214. package/dist/fi/hetu.js +2 -10
  215. package/dist/fi/hetu.js.map +1 -1
  216. package/dist/fi/vat.d.ts +2 -2
  217. package/dist/fi/vat.js +3 -10
  218. package/dist/fi/vat.js.map +1 -1
  219. package/dist/fi/ytunnus.d.ts +2 -2
  220. package/dist/fi/ytunnus.js +2 -10
  221. package/dist/fi/ytunnus.js.map +1 -1
  222. package/dist/fr/nif.d.ts +2 -2
  223. package/dist/fr/nif.js +1 -9
  224. package/dist/fr/nif.js.map +1 -1
  225. package/dist/fr/nir.d.ts +2 -2
  226. package/dist/fr/nir.js +2 -14
  227. package/dist/fr/nir.js.map +1 -1
  228. package/dist/fr/siren.d.ts +2 -2
  229. package/dist/fr/siren.js +2 -10
  230. package/dist/fr/siren.js.map +1 -1
  231. package/dist/fr/siret.d.ts +2 -2
  232. package/dist/fr/siret.js +2 -11
  233. package/dist/fr/siret.js.map +1 -1
  234. package/dist/fr/tva.d.ts +2 -2
  235. package/dist/fr/tva.js +2 -12
  236. package/dist/fr/tva.js.map +1 -1
  237. package/dist/gb/nino.d.ts +12 -2
  238. package/dist/gb/nino.js +1 -10
  239. package/dist/gb/nino.js.map +1 -1
  240. package/dist/gb/sedol.d.ts +2 -2
  241. package/dist/gb/sedol.js +1 -11
  242. package/dist/gb/sedol.js.map +1 -1
  243. package/dist/gb/utr.d.ts +2 -2
  244. package/dist/gb/utr.js +2 -10
  245. package/dist/gb/utr.js.map +1 -1
  246. package/dist/gb/vat.d.ts +2 -2
  247. package/dist/gb/vat.js +2 -11
  248. package/dist/gb/vat.js.map +1 -1
  249. package/dist/ge/pin.d.ts +14 -2
  250. package/dist/ge/pin.js +1 -12
  251. package/dist/ge/pin.js.map +1 -1
  252. package/dist/gh/tin.d.ts +2 -2
  253. package/dist/gh/tin.js +1 -15
  254. package/dist/gh/tin.js.map +1 -1
  255. package/dist/gr/amka.d.ts +2 -2
  256. package/dist/gr/amka.js +3 -11
  257. package/dist/gr/amka.js.map +1 -1
  258. package/dist/gr/vat.d.ts +2 -2
  259. package/dist/gr/vat.js +1 -10
  260. package/dist/gr/vat.js.map +1 -1
  261. package/dist/gt/nit.d.ts +2 -2
  262. package/dist/gt/nit.js +1 -12
  263. package/dist/gt/nit.js.map +1 -1
  264. package/dist/hk/hkid.d.ts +2 -2
  265. package/dist/hk/hkid.js +1 -10
  266. package/dist/hk/hkid.js.map +1 -1
  267. package/dist/hr/vat.d.ts +2 -2
  268. package/dist/hr/vat.js +2 -9
  269. package/dist/hr/vat.js.map +1 -1
  270. package/dist/hu/vat.d.ts +2 -2
  271. package/dist/hu/vat.js +3 -10
  272. package/dist/hu/vat.js.map +1 -1
  273. package/dist/iban.d.ts +2 -2
  274. package/dist/iban.js +2 -8
  275. package/dist/iban.js.map +1 -1
  276. package/dist/id/npwp.d.ts +2 -2
  277. package/dist/id/npwp.js +3 -13
  278. package/dist/id/npwp.js.map +1 -1
  279. package/dist/ie/pps.d.ts +2 -2
  280. package/dist/ie/pps.js +1 -10
  281. package/dist/ie/pps.js.map +1 -1
  282. package/dist/ie/vat.d.ts +2 -2
  283. package/dist/ie/vat.js +1 -9
  284. package/dist/ie/vat.js.map +1 -1
  285. package/dist/il/idnr.d.ts +2 -2
  286. package/dist/il/idnr.js +2 -9
  287. package/dist/il/idnr.js.map +1 -1
  288. package/dist/in/aadhaar.d.ts +2 -2
  289. package/dist/in/aadhaar.js +2 -12
  290. package/dist/in/aadhaar.js.map +1 -1
  291. package/dist/in/gstin.d.ts +2 -2
  292. package/dist/in/gstin.js +1 -10
  293. package/dist/in/gstin.js.map +1 -1
  294. package/dist/in/pan.d.ts +15 -2
  295. package/dist/in/pan.js +1 -13
  296. package/dist/in/pan.js.map +1 -1
  297. package/dist/index.d.ts +2 -2
  298. package/dist/index.js +6 -6
  299. package/dist/iq/nid.d.ts +16 -2
  300. package/dist/iq/nid.js +2 -15
  301. package/dist/iq/nid.js.map +1 -1
  302. package/dist/ir/nid.d.ts +2 -2
  303. package/dist/ir/nid.js +2 -24
  304. package/dist/ir/nid.js.map +1 -1
  305. package/dist/is/kennitala.d.ts +2 -2
  306. package/dist/is/kennitala.js +2 -13
  307. package/dist/is/kennitala.js.map +1 -1
  308. package/dist/is/vsk.d.ts +9 -2
  309. package/dist/is/vsk.js +1 -7
  310. package/dist/is/vsk.js.map +1 -1
  311. package/dist/isin.d.ts +2 -2
  312. package/dist/isin.js +2 -12
  313. package/dist/isin.js.map +1 -1
  314. package/dist/it/codicefiscale.d.ts +2 -2
  315. package/dist/it/codicefiscale.js +1 -21
  316. package/dist/it/codicefiscale.js.map +1 -1
  317. package/dist/it/iva.d.ts +2 -2
  318. package/dist/it/iva.js +2 -9
  319. package/dist/it/iva.js.map +1 -1
  320. package/dist/jp/cn.d.ts +2 -2
  321. package/dist/jp/cn.js +1 -9
  322. package/dist/jp/cn.js.map +1 -1
  323. package/dist/jp/mynumber.d.ts +2 -2
  324. package/dist/jp/mynumber.js +1 -10
  325. package/dist/jp/mynumber.js.map +1 -1
  326. package/dist/kr/brn.d.ts +11 -2
  327. package/dist/kr/brn.js +1 -9
  328. package/dist/kr/brn.js.map +1 -1
  329. package/dist/kr/rrn.d.ts +2 -2
  330. package/dist/kr/rrn.js +2 -11
  331. package/dist/kr/rrn.js.map +1 -1
  332. package/dist/kw/civil.d.ts +2 -2
  333. package/dist/kw/civil.js +2 -14
  334. package/dist/kw/civil.js.map +1 -1
  335. package/dist/kz/iin.d.ts +2 -2
  336. package/dist/kz/iin.js +3 -18
  337. package/dist/kz/iin.js.map +1 -1
  338. package/dist/lei.d.ts +2 -2
  339. package/dist/lei.js +2 -11
  340. package/dist/lei.js.map +1 -1
  341. package/dist/li/peid.d.ts +11 -2
  342. package/dist/li/peid.js +1 -9
  343. package/dist/li/peid.js.map +1 -1
  344. package/dist/lk/nic.d.ts +2 -2
  345. package/dist/lk/nic.js +2 -14
  346. package/dist/lk/nic.js.map +1 -1
  347. package/dist/lt/asmens.d.ts +2 -2
  348. package/dist/lt/asmens.js +2 -1
  349. package/dist/lt/asmens.js.map +1 -1
  350. package/dist/lt/vat.d.ts +2 -2
  351. package/dist/lt/vat.js +2 -10
  352. package/dist/lt/vat.js.map +1 -1
  353. package/dist/lu/vat.d.ts +2 -2
  354. package/dist/lu/vat.js +2 -8
  355. package/dist/lu/vat.js.map +1 -1
  356. package/dist/luhn.d.ts +2 -2
  357. package/dist/luhn.js +2 -9
  358. package/dist/luhn.js.map +1 -1
  359. package/dist/lv/vat.d.ts +2 -2
  360. package/dist/lv/vat.js +2 -28
  361. package/dist/lv/vat.js.map +1 -1
  362. package/dist/ma/ice.d.ts +2 -2
  363. package/dist/ma/ice.js +2 -11
  364. package/dist/ma/ice.js.map +1 -1
  365. package/dist/mc/tva.d.ts +2 -2
  366. package/dist/mc/tva.js +1 -0
  367. package/dist/mc/tva.js.map +1 -1
  368. package/dist/md/idno.d.ts +2 -2
  369. package/dist/md/idno.js +1 -10
  370. package/dist/md/idno.js.map +1 -1
  371. package/dist/me/pib.d.ts +2 -2
  372. package/dist/me/pib.js +2 -10
  373. package/dist/me/pib.js.map +1 -1
  374. package/dist/mk/edb.d.ts +2 -2
  375. package/dist/mk/edb.js +2 -11
  376. package/dist/mk/edb.js.map +1 -1
  377. package/dist/mt/vat.d.ts +2 -2
  378. package/dist/mt/vat.js +3 -10
  379. package/dist/mt/vat.js.map +1 -1
  380. package/dist/mu/brn.d.ts +23 -2
  381. package/dist/mu/brn.js +1 -21
  382. package/dist/mu/brn.js.map +1 -1
  383. package/dist/mx/clabe.d.ts +2 -2
  384. package/dist/mx/clabe.js +1 -14
  385. package/dist/mx/clabe.js.map +1 -1
  386. package/dist/mx/curp.d.ts +2 -2
  387. package/dist/mx/curp.js +3 -17
  388. package/dist/mx/curp.js.map +1 -1
  389. package/dist/mx/rfc.d.ts +2 -2
  390. package/dist/mx/rfc.js +3 -19
  391. package/dist/mx/rfc.js.map +1 -1
  392. package/dist/my/nric.d.ts +2 -2
  393. package/dist/my/nric.js +2 -14
  394. package/dist/my/nric.js.map +1 -1
  395. package/dist/ng/nin.d.ts +13 -2
  396. package/dist/ng/nin.js +1 -11
  397. package/dist/ng/nin.js.map +1 -1
  398. package/dist/ni/ruc.d.ts +2 -2
  399. package/dist/ni/ruc.js +1 -23
  400. package/dist/ni/ruc.js.map +1 -1
  401. package/dist/nl/bsn.d.ts +2 -2
  402. package/dist/nl/bsn.js +2 -10
  403. package/dist/nl/bsn.js.map +1 -1
  404. package/dist/nl/kvk.d.ts +9 -2
  405. package/dist/nl/kvk.js +1 -7
  406. package/dist/nl/kvk.js.map +1 -1
  407. package/dist/nl/vat.d.ts +2 -2
  408. package/dist/nl/vat.js +1 -13
  409. package/dist/nl/vat.js.map +1 -1
  410. package/dist/no/fodselsnummer.d.ts +2 -2
  411. package/dist/no/fodselsnummer.js +2 -10
  412. package/dist/no/fodselsnummer.js.map +1 -1
  413. package/dist/no/mva.d.ts +2 -2
  414. package/dist/no/mva.js +1 -8
  415. package/dist/no/mva.js.map +1 -1
  416. package/dist/no/orgnr.d.ts +2 -2
  417. package/dist/no/orgnr.js +2 -8
  418. package/dist/no/orgnr.js.map +1 -1
  419. package/dist/nz/ird.d.ts +2 -2
  420. package/dist/nz/ird.js +2 -11
  421. package/dist/nz/ird.js.map +1 -1
  422. package/dist/pa/ruc.d.ts +2 -2
  423. package/dist/pa/ruc.js +1 -18
  424. package/dist/pa/ruc.js.map +1 -1
  425. package/dist/patterns.d.ts +8 -7
  426. package/dist/patterns.js +3 -5
  427. package/dist/patterns.js.map +1 -1
  428. package/dist/pe/ruc.d.ts +2 -2
  429. package/dist/pe/ruc.js +1 -15
  430. package/dist/pe/ruc.js.map +1 -1
  431. package/dist/ph/philid.d.ts +14 -2
  432. package/dist/ph/philid.js +1 -12
  433. package/dist/ph/philid.js.map +1 -1
  434. package/dist/pk/cnic.d.ts +14 -2
  435. package/dist/pk/cnic.js +1 -12
  436. package/dist/pk/cnic.js.map +1 -1
  437. package/dist/pl/nip.d.ts +2 -2
  438. package/dist/pl/nip.js +2 -10
  439. package/dist/pl/nip.js.map +1 -1
  440. package/dist/pl/pesel.d.ts +2 -2
  441. package/dist/pl/pesel.js +3 -13
  442. package/dist/pl/pesel.js.map +1 -1
  443. package/dist/pl/regon.d.ts +2 -2
  444. package/dist/pl/regon.js +2 -11
  445. package/dist/pl/regon.js.map +1 -1
  446. package/dist/pt/cc.d.ts +2 -2
  447. package/dist/pt/cc.js +1 -9
  448. package/dist/pt/cc.js.map +1 -1
  449. package/dist/pt/vat.d.ts +2 -2
  450. package/dist/pt/vat.js +3 -11
  451. package/dist/pt/vat.js.map +1 -1
  452. package/dist/ro/cnp.d.ts +2 -2
  453. package/dist/ro/cnp.js +4 -14
  454. package/dist/ro/cnp.js.map +1 -1
  455. package/dist/ro/vat.d.ts +2 -2
  456. package/dist/ro/vat.js +13 -11
  457. package/dist/ro/vat.js.map +1 -1
  458. package/dist/rs/pib.d.ts +2 -2
  459. package/dist/rs/pib.js +1 -9
  460. package/dist/rs/pib.js.map +1 -1
  461. package/dist/ru/inn.d.ts +2 -2
  462. package/dist/ru/inn.js +1 -11
  463. package/dist/ru/inn.js.map +1 -1
  464. package/dist/se/orgnr.d.ts +2 -2
  465. package/dist/se/orgnr.js +2 -9
  466. package/dist/se/orgnr.js.map +1 -1
  467. package/dist/se/personnummer.d.ts +2 -2
  468. package/dist/se/personnummer.js +7 -15
  469. package/dist/se/personnummer.js.map +1 -1
  470. package/dist/se/vat.d.ts +2 -2
  471. package/dist/se/vat.js +3 -10
  472. package/dist/se/vat.js.map +1 -1
  473. package/dist/sg/uen.d.ts +2 -2
  474. package/dist/sg/uen.js +1 -15
  475. package/dist/sg/uen.js.map +1 -1
  476. package/dist/si/emso.d.ts +2 -2
  477. package/dist/si/emso.js +3 -18
  478. package/dist/si/emso.js.map +1 -1
  479. package/dist/si/vat.d.ts +2 -2
  480. package/dist/si/vat.js +3 -12
  481. package/dist/si/vat.js.map +1 -1
  482. package/dist/sk/dic.d.ts +2 -2
  483. package/dist/sk/dic.js +1 -0
  484. package/dist/sk/dic.js.map +1 -1
  485. package/dist/sk/ico.d.ts +2 -2
  486. package/dist/sk/ico.js +1 -0
  487. package/dist/sk/ico.js.map +1 -1
  488. package/dist/sk/rc.d.ts +2 -2
  489. package/dist/sk/rc.js +1 -0
  490. package/dist/sk/rc.js.map +1 -1
  491. package/dist/th/tin.d.ts +2 -2
  492. package/dist/th/tin.js +1 -11
  493. package/dist/th/tin.js.map +1 -1
  494. package/dist/tr/tckimlik.d.ts +2 -2
  495. package/dist/tr/tckimlik.js +1 -20
  496. package/dist/tr/tckimlik.js.map +1 -1
  497. package/dist/tr/vkn.d.ts +2 -2
  498. package/dist/tr/vkn.js +1 -20
  499. package/dist/tr/vkn.js.map +1 -1
  500. package/dist/tw/ubn.d.ts +2 -2
  501. package/dist/tw/ubn.js +1 -11
  502. package/dist/tw/ubn.js.map +1 -1
  503. package/dist/types.d.ts +26 -4
  504. package/dist/ua/edrpou.d.ts +2 -2
  505. package/dist/ua/edrpou.js +1 -11
  506. package/dist/ua/edrpou.js.map +1 -1
  507. package/dist/us/ein.d.ts +12 -2
  508. package/dist/us/ein.js +1 -10
  509. package/dist/us/ein.js.map +1 -1
  510. package/dist/us/itin.d.ts +13 -2
  511. package/dist/us/itin.js +1 -11
  512. package/dist/us/itin.js.map +1 -1
  513. package/dist/us/rtn.d.ts +2 -2
  514. package/dist/us/rtn.js +3 -18
  515. package/dist/us/rtn.js.map +1 -1
  516. package/dist/us/ssn.d.ts +13 -2
  517. package/dist/us/ssn.js +1 -11
  518. package/dist/us/ssn.js.map +1 -1
  519. package/dist/uy/rut.d.ts +2 -2
  520. package/dist/uy/rut.js +1 -14
  521. package/dist/uy/rut.js.map +1 -1
  522. package/dist/ve/rif.d.ts +2 -2
  523. package/dist/ve/rif.js +2 -15
  524. package/dist/ve/rif.js.map +1 -1
  525. package/dist/vn/mst.d.ts +2 -2
  526. package/dist/vn/mst.js +1 -12
  527. package/dist/vn/mst.js.map +1 -1
  528. package/dist/za/idnr.d.ts +2 -2
  529. package/dist/za/idnr.js +3 -16
  530. package/dist/za/idnr.js.map +1 -1
  531. package/package.json +22 -12
  532. package/src/_checksums/mod1110.ts +1 -1
  533. package/src/ad/nrt.ts +7 -3
  534. package/src/ae/eid.ts +7 -3
  535. package/src/ai/tin.ts +7 -3
  536. package/src/al/nipt.ts +7 -3
  537. package/src/am/tin.ts +7 -3
  538. package/src/ar/cbu.ts +7 -3
  539. package/src/ar/cuit.ts +7 -3
  540. package/src/ar/dni.ts +7 -3
  541. package/src/at/businessid.ts +7 -3
  542. package/src/at/tin.ts +7 -3
  543. package/src/at/uid.ts +7 -3
  544. package/src/at/vnr.ts +37 -9
  545. package/src/au/abn.ts +7 -3
  546. package/src/au/acn.ts +7 -3
  547. package/src/au/tfn.ts +7 -3
  548. package/src/az/voen.ts +7 -3
  549. package/src/ba/jmbg.ts +8 -7
  550. package/src/bd/nid.ts +7 -3
  551. package/src/be/bis.ts +8 -4
  552. package/src/be/nn.ts +7 -3
  553. package/src/be/vat.ts +7 -3
  554. package/src/bg/egn.ts +8 -7
  555. package/src/bg/pnf.ts +7 -3
  556. package/src/bg/vat.ts +8 -3
  557. package/src/bh/cpr.ts +7 -3
  558. package/src/bic.ts +7 -3
  559. package/src/br/cnpj.ts +7 -3
  560. package/src/br/cpf.ts +7 -3
  561. package/src/by/unp.ts +10 -5
  562. package/src/bz/tin.ts +7 -3
  563. package/src/ca/bn.ts +7 -3
  564. package/src/ca/sin.ts +7 -3
  565. package/src/ch/ssn.ts +7 -3
  566. package/src/ch/uid.ts +7 -3
  567. package/src/ch/vat.ts +9 -5
  568. package/src/cl/rut.ts +7 -3
  569. package/src/cn/ric.ts +8 -7
  570. package/src/cn/uscc.ts +7 -3
  571. package/src/co/nit.ts +8 -4
  572. package/src/cr/cpf.ts +7 -3
  573. package/src/creditcard.ts +10 -6
  574. package/src/cu/ni.ts +8 -7
  575. package/src/cy/vat.ts +7 -3
  576. package/src/cz/dic.ts +9 -4
  577. package/src/cz/ico.ts +7 -3
  578. package/src/cz/rc.ts +8 -7
  579. package/src/de/handelsreg.ts +7 -3
  580. package/src/de/idnr.ts +7 -3
  581. package/src/de/stnr.ts +7 -3
  582. package/src/de/svnr.ts +7 -3
  583. package/src/de/vat.ts +7 -3
  584. package/src/dk/cpr.ts +8 -7
  585. package/src/dk/cvr.ts +7 -3
  586. package/src/dk/vat.ts +8 -3
  587. package/src/do/rnc.ts +7 -3
  588. package/src/ec/ruc.ts +7 -3
  589. package/src/ee/ik.ts +8 -7
  590. package/src/ee/registrikood.ts +8 -4
  591. package/src/ee/vat.ts +7 -3
  592. package/src/eg/tn.ts +7 -3
  593. package/src/es/cif.ts +8 -4
  594. package/src/es/dni.ts +7 -3
  595. package/src/es/nie.ts +8 -4
  596. package/src/es/nss.ts +7 -3
  597. package/src/es/vat.ts +13 -5
  598. package/src/eu/vat.ts +10 -6
  599. package/src/fi/hetu.ts +8 -7
  600. package/src/fi/vat.ts +8 -3
  601. package/src/fi/ytunnus.ts +7 -3
  602. package/src/fr/nif.ts +7 -3
  603. package/src/fr/nir.ts +8 -7
  604. package/src/fr/siren.ts +7 -3
  605. package/src/fr/siret.ts +7 -3
  606. package/src/fr/tva.ts +7 -3
  607. package/src/gb/nino.ts +7 -3
  608. package/src/gb/sedol.ts +7 -3
  609. package/src/gb/utr.ts +7 -3
  610. package/src/gb/vat.ts +7 -3
  611. package/src/ge/pin.ts +7 -3
  612. package/src/gh/tin.ts +7 -3
  613. package/src/gr/amka.ts +7 -3
  614. package/src/gr/vat.ts +7 -3
  615. package/src/gt/nit.ts +7 -3
  616. package/src/hk/hkid.ts +7 -3
  617. package/src/hr/vat.ts +7 -3
  618. package/src/hu/vat.ts +8 -3
  619. package/src/iban.ts +7 -3
  620. package/src/id/npwp.ts +7 -3
  621. package/src/ie/pps.ts +7 -3
  622. package/src/ie/vat.ts +7 -3
  623. package/src/il/idnr.ts +7 -3
  624. package/src/in/aadhaar.ts +7 -3
  625. package/src/in/gstin.ts +7 -3
  626. package/src/in/pan.ts +7 -3
  627. package/src/index.ts +3 -0
  628. package/src/iq/nid.ts +7 -3
  629. package/src/ir/nid.ts +7 -3
  630. package/src/is/kennitala.ts +7 -3
  631. package/src/is/vsk.ts +7 -3
  632. package/src/isin.ts +7 -3
  633. package/src/it/codicefiscale.ts +11 -7
  634. package/src/it/iva.ts +7 -3
  635. package/src/jp/cn.ts +7 -3
  636. package/src/jp/mynumber.ts +7 -3
  637. package/src/kr/brn.ts +7 -3
  638. package/src/kr/rrn.ts +8 -7
  639. package/src/kw/civil.ts +8 -7
  640. package/src/kz/iin.ts +8 -8
  641. package/src/lei.ts +7 -3
  642. package/src/li/peid.ts +7 -3
  643. package/src/lk/nic.ts +8 -7
  644. package/src/lt/asmens.ts +8 -4
  645. package/src/lt/vat.ts +8 -3
  646. package/src/lu/vat.ts +8 -3
  647. package/src/luhn.ts +7 -3
  648. package/src/lv/vat.ts +7 -3
  649. package/src/ma/ice.ts +7 -3
  650. package/src/mc/tva.ts +9 -5
  651. package/src/md/idno.ts +7 -3
  652. package/src/me/pib.ts +7 -3
  653. package/src/mk/edb.ts +7 -3
  654. package/src/mt/vat.ts +8 -3
  655. package/src/mu/brn.ts +7 -3
  656. package/src/mx/clabe.ts +7 -3
  657. package/src/mx/curp.ts +9 -8
  658. package/src/mx/rfc.ts +8 -4
  659. package/src/my/nric.ts +8 -7
  660. package/src/ng/nin.ts +7 -3
  661. package/src/ni/ruc.ts +7 -3
  662. package/src/nl/bsn.ts +7 -3
  663. package/src/nl/kvk.ts +7 -3
  664. package/src/nl/vat.ts +7 -3
  665. package/src/no/fodselsnummer.ts +11 -7
  666. package/src/no/mva.ts +9 -5
  667. package/src/no/orgnr.ts +7 -3
  668. package/src/nz/ird.ts +8 -4
  669. package/src/pa/ruc.ts +7 -3
  670. package/src/patterns.ts +49 -18
  671. package/src/pe/ruc.ts +7 -3
  672. package/src/ph/philid.ts +7 -3
  673. package/src/pk/cnic.ts +7 -3
  674. package/src/pl/nip.ts +7 -3
  675. package/src/pl/pesel.ts +8 -7
  676. package/src/pl/regon.ts +7 -3
  677. package/src/pt/cc.ts +7 -3
  678. package/src/pt/vat.ts +8 -3
  679. package/src/ro/cnp.ts +15 -8
  680. package/src/ro/vat.ts +8 -3
  681. package/src/rs/pib.ts +7 -3
  682. package/src/ru/inn.ts +7 -3
  683. package/src/se/orgnr.ts +7 -3
  684. package/src/se/personnummer.ts +35 -33
  685. package/src/se/vat.ts +8 -3
  686. package/src/sg/uen.ts +7 -3
  687. package/src/si/emso.ts +8 -7
  688. package/src/si/vat.ts +8 -3
  689. package/src/sk/dic.ts +8 -4
  690. package/src/sk/ico.ts +3 -2
  691. package/src/sk/rc.ts +6 -2
  692. package/src/th/tin.ts +7 -3
  693. package/src/tr/tckimlik.ts +7 -3
  694. package/src/tr/vkn.ts +7 -3
  695. package/src/tw/ubn.ts +7 -3
  696. package/src/types.ts +34 -3
  697. package/src/ua/edrpou.ts +7 -3
  698. package/src/us/ein.ts +7 -3
  699. package/src/us/itin.ts +7 -3
  700. package/src/us/rtn.ts +16 -8
  701. package/src/us/ssn.ts +7 -3
  702. package/src/uy/rut.ts +7 -3
  703. package/src/ve/rif.ts +8 -6
  704. package/src/vn/mst.ts +7 -3
  705. package/src/za/idnr.ts +8 -7
package/dist/de/vat.js CHANGED
@@ -1,19 +1,9 @@
1
+ import { mod1110checkDigit, mod1110validate } from "../_checksums/mod1110.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 { mod1110checkDigit, mod1110validate } from "../_checksums/mod1110.js";
6
6
  //#region src/de/vat.ts
7
- /**
8
- * USt-IdNr. (Umsatzsteuer-Identifikationsnummer).
9
- *
10
- * German VAT identification number. Format:
11
- * "DE" + 9 digits. The last digit is a check
12
- * digit computed using ISO 7064 Mod 11,10.
13
- *
14
- * @see https://www.bzst.de/DE/Unternehmen/Identifikationsnummern/Umsatzsteuer-Identifikationsnummer/umsatzsteuer-identifikationsnummer_node.html
15
- * @see https://www.bzst.de/SharedDocs/Downloads/DE/Merkblaetter/ust_idnr_aufbau.pdf
16
- */
17
7
  const compact = (value) => {
18
8
  const v = clean(value, " -/");
19
9
  if (v.startsWith("DE") || v.startsWith("de")) return v.slice(2);
@@ -48,6 +38,7 @@ const vat = {
48
38
  "VAT DE"
49
39
  ],
50
40
  candidatePattern: "DE\\d{9}",
41
+ scope: "country",
51
42
  country: "DE",
52
43
  entityType: "company",
53
44
  description: "German VAT ID issued by the Federal Tax Office (BZSt)",
@@ -1 +1 @@
1
- {"version":3,"file":"vat.js","names":[],"sources":["../../src/de/vat.ts"],"sourcesContent":["/**\n * USt-IdNr. (Umsatzsteuer-Identifikationsnummer).\n *\n * German VAT identification number. Format:\n * \"DE\" + 9 digits. The last digit is a check\n * digit computed using ISO 7064 Mod 11,10.\n *\n * @see https://www.bzst.de/DE/Unternehmen/Identifikationsnummern/Umsatzsteuer-Identifikationsnummer/umsatzsteuer-identifikationsnummer_node.html\n * @see https://www.bzst.de/SharedDocs/Downloads/DE/Merkblaetter/ust_idnr_aufbau.pdf\n */\n\nimport {\n mod1110checkDigit,\n mod1110validate,\n} from \"#checksums/mod1110\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst compact = (value: string): string => {\n const v = clean(value, \" -/\");\n if (v.startsWith(\"DE\") || v.startsWith(\"de\")) {\n return v.slice(2);\n }\n return v;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"German VAT number must be 9 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"German VAT number must contain only digits\",\n );\n }\n if (v[0] === \"0\") {\n return err(\n \"INVALID_COMPONENT\",\n \"German VAT number cannot start with 0\",\n );\n }\n if (!mod1110validate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"German VAT number check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string =>\n `DE${compact(value)}`;\n\n/** Generate a random valid German VAT number. */\nconst generate = (): string => {\n const first = String(randomInt(1, 9));\n const rest = randomDigits(7);\n const payload = `${first}${rest}`;\n const check = mod1110checkDigit(payload);\n return `${payload}${String(check)}`;\n};\n\n/** German VAT Identification Number. */\nconst vat: Validator = {\n name: \"German VAT Number\",\n localName: \"Umsatzsteuer-Identifikationsnummer\",\n abbreviation: \"USt-IdNr.\",\n aliases: [\n \"USt-IdNr\",\n \"Umsatzsteuer-Identifikationsnummer\",\n \"VAT DE\",\n ] as const,\n candidatePattern: \"DE\\\\d{9}\",\n country: \"DE\",\n entityType: \"company\",\n description:\n \"German VAT ID issued by the Federal Tax Office (BZSt)\",\n sourceUrl:\n \"https://www.bzst.de/DE/Unternehmen/Identifikationsnummern/Umsatzsteuer-Identifikationsnummer/umsatzsteuer-identifikationsnummer_node.html\",\n lengths: [9] as const,\n examples: [\"136695976\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default vat;\nexport { compact, format, generate, validate };\n"],"mappings":";;;;;;;;;;;;;;;;AAsBA,MAAM,WAAW,UAA0B;CACzC,MAAM,IAAI,MAAM,OAAO,MAAM;AAC7B,KAAI,EAAE,WAAW,KAAK,IAAI,EAAE,WAAW,KAAK,CAC1C,QAAO,EAAE,MAAM,EAAE;AAEnB,QAAO;;AAGT,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,IACL,kBACA,qCACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,6CACD;AAEH,KAAI,EAAE,OAAO,IACX,QAAO,IACL,qBACA,wCACD;AAEH,KAAI,CAAC,gBAAgB,EAAE,CACrB,QAAO,IACL,oBACA,yCACD;AAEH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UACd,KAAK,QAAQ,MAAM;;AAGrB,MAAM,iBAAyB;CAG7B,MAAM,UAAU,GAFF,OAAO,UAAU,GAAG,EAAE,CAAC,GACxB,aAAa,EAAE;CAE5B,MAAM,QAAQ,kBAAkB,QAAQ;AACxC,QAAO,GAAG,UAAU,OAAO,MAAM;;;AAInC,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;EACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,aACE;CACF,WACE;CACF,SAAS,CAAC,EAAE;CACZ,UAAU,CAAC,YAAY;CACvB;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"vat.js","names":[],"sources":["../../src/de/vat.ts"],"sourcesContent":["/**\n * USt-IdNr. (Umsatzsteuer-Identifikationsnummer).\n *\n * German VAT identification number. Format:\n * \"DE\" + 9 digits. The last digit is a check\n * digit computed using ISO 7064 Mod 11,10.\n *\n * @see https://www.bzst.de/DE/Unternehmen/Identifikationsnummern/Umsatzsteuer-Identifikationsnummer/umsatzsteuer-identifikationsnummer_node.html\n * @see https://www.bzst.de/SharedDocs/Downloads/DE/Merkblaetter/ust_idnr_aufbau.pdf\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport {\n mod1110checkDigit,\n mod1110validate,\n} from \"#checksums/mod1110\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst compact = (value: string): string => {\n const v = clean(value, \" -/\");\n if (v.startsWith(\"DE\") || v.startsWith(\"de\")) {\n return v.slice(2);\n }\n return v;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"German VAT number must be 9 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"German VAT number must contain only digits\",\n );\n }\n if (v[0] === \"0\") {\n return err(\n \"INVALID_COMPONENT\",\n \"German VAT number cannot start with 0\",\n );\n }\n if (!mod1110validate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"German VAT number check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string =>\n `DE${compact(value)}`;\n\n/** Generate a random valid German VAT number. */\nconst generate = (): string => {\n const first = String(randomInt(1, 9));\n const rest = randomDigits(7);\n const payload = `${first}${rest}`;\n const check = mod1110checkDigit(payload);\n return `${payload}${String(check)}`;\n};\n\n/** German VAT Identification Number. */\nconst vat: CountryValidator<\"DE\"> = {\n name: \"German VAT Number\",\n localName: \"Umsatzsteuer-Identifikationsnummer\",\n abbreviation: \"USt-IdNr.\",\n aliases: [\n \"USt-IdNr\",\n \"Umsatzsteuer-Identifikationsnummer\",\n \"VAT DE\",\n ] as const,\n candidatePattern: \"DE\\\\d{9}\",\n scope: \"country\",\n country: \"DE\",\n entityType: \"company\",\n description:\n \"German VAT ID issued by the Federal Tax Office (BZSt)\",\n sourceUrl:\n \"https://www.bzst.de/DE/Unternehmen/Identifikationsnummern/Umsatzsteuer-Identifikationsnummer/umsatzsteuer-identifikationsnummer_node.html\",\n lengths: [9] as const,\n examples: [\"136695976\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default vat;\nexport { compact, format, generate, validate };\n"],"mappings":";;;;;;AAyBA,MAAM,WAAW,UAA0B;CACzC,MAAM,IAAI,MAAM,OAAO,KAAK;CAC5B,IAAI,EAAE,WAAW,IAAI,KAAK,EAAE,WAAW,IAAI,GACzC,OAAO,EAAE,MAAM,CAAC;CAElB,OAAO;AACT;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,GACf,OAAO,IACL,kBACA,oCACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,4CACF;CAEF,IAAI,EAAE,OAAO,KACX,OAAO,IACL,qBACA,uCACF;CAEF,IAAI,CAAC,gBAAgB,CAAC,GACpB,OAAO,IACL,oBACA,wCACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UACd,KAAK,QAAQ,KAAK;;AAGpB,MAAM,iBAAyB;CAG7B,MAAM,UAAU,GAFF,OAAO,UAAU,GAAG,CAAC,CAEZ,IADV,aAAa,CACI;CAC9B,MAAM,QAAQ,kBAAkB,OAAO;CACvC,OAAO,GAAG,UAAU,OAAO,KAAK;AAClC;;AAGA,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;CACF;CACA,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,aACE;CACF,WACE;CACF,SAAS,CAAC,CAAC;CACX,UAAU,CAAC,WAAW;CACtB;CACA;CACA;CACA;AACF"}
package/dist/dk/cpr.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ParsedPersonId, ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ParsedPersonId, ValidateResult } from "../types.js";
2
2
 
3
3
  //#region src/dk/cpr.d.ts
4
4
  declare const compact: (value: string) => string;
@@ -12,7 +12,7 @@ declare const parse: (value: string) => ParsedPersonId | null;
12
12
  /** Generate a random valid Danish CPR. */
13
13
  declare const generate: () => string;
14
14
  /** Danish Personal Identification Number. */
15
- declare const cpr: Validator<ParsedPersonId>;
15
+ declare const cpr: CountryValidator<"DK", ParsedPersonId>;
16
16
  //#endregion
17
17
  export { compact, cpr as default, format, generate, parse, validate };
18
18
  //# sourceMappingURL=cpr.d.ts.map
package/dist/dk/cpr.js CHANGED
@@ -1,18 +1,9 @@
1
1
  import { clean } from "../_util/clean.js";
2
+ import { isValidDate } from "../_util/date.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 { isValidDate } from "../_util/date.js";
6
6
  //#region src/dk/cpr.ts
7
- /**
8
- * CPR (Det Centrale Personregister).
9
- *
10
- * Danish personal identification number. 10 digits
11
- * in format DDMMYY-SSSS. Checksum enforcement was
12
- * dropped in 2007; only date validation is performed.
13
- *
14
- * @see https://cpr.dk/
15
- */
16
7
  const compact = (value) => clean(value, " -");
17
8
  const getCentury = (yy, s7) => {
18
9
  if (s7 >= 0 && s7 <= 3) return 1900;
@@ -74,6 +65,7 @@ const cpr = {
74
65
  "CPR"
75
66
  ],
76
67
  candidatePattern: "\\d{6}-?\\d{4}",
68
+ scope: "country",
77
69
  country: "DK",
78
70
  entityType: "person",
79
71
  sourceUrl: "https://cpr.dk/",
@@ -1 +1 @@
1
- {"version":3,"file":"cpr.js","names":[],"sources":["../../src/dk/cpr.ts"],"sourcesContent":["/**\n * CPR (Det Centrale Personregister).\n *\n * Danish personal identification number. 10 digits\n * in format DDMMYY-SSSS. Checksum enforcement was\n * dropped in 2007; only date validation is performed.\n *\n * @see https://cpr.dk/\n */\n\nimport { clean } from \"#util/clean\";\nimport { isValidDate } from \"#util/date\";\nimport { randomDigits, 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 getCentury = (yy: number, s7: number): number => {\n // 7th digit (first of serial) determines century\n if (s7 >= 0 && s7 <= 3) return 1900;\n if (s7 === 4 || s7 === 9) {\n return yy <= 36 ? 2000 : 1900;\n }\n // s7 5..8\n return yy <= 57 ? 2000 : 1800;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 10) {\n return err(\n \"INVALID_LENGTH\",\n \"CPR must be exactly 10 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"CPR must contain only digits\",\n );\n }\n\n const dd = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const yy = Number(v.slice(4, 6));\n const s7 = Number(v[6]);\n\n const century = getCentury(yy, s7);\n const year = century + yy;\n\n if (!isValidDate(year, mm, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"CPR contains an invalid date\",\n );\n }\n\n // Reject future birth dates\n if (new Date(year, mm - 1, dd) > new Date()) {\n return err(\n \"INVALID_COMPONENT\",\n \"CPR birth date is in the future\",\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 CPR 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 dd = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const yy = Number(v.slice(4, 6));\n const s7 = Number(v[6]);\n const lastDigit = Number(v[9]);\n\n const century = getCentury(yy, s7);\n const year = century + yy;\n\n return {\n birthDate: new Date(year, mm - 1, dd),\n gender: lastDigit % 2 === 0 ? \"female\" : \"male\",\n };\n};\n\n/** Generate a random valid Danish CPR. */\nconst generate = (): string => {\n const year = randomInt(1900, 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 serialPrefix = String(randomInt(0, 3));\n return `${day}${month}${yy}${serialPrefix}${randomDigits(3)}`;\n};\n\n/** Danish Personal Identification Number. */\nconst cpr: Validator<ParsedPersonId> = {\n name: \"Danish Personal ID\",\n localName: \"Det Centrale Personregister\",\n abbreviation: \"CPR\",\n aliases: [\"CPR-nummer\", \"personnummer\", \"CPR\"] as const,\n candidatePattern: \"\\\\d{6}-?\\\\d{4}\",\n country: \"DK\",\n entityType: \"person\",\n sourceUrl: \"https://cpr.dk/\",\n lengths: [10] as const,\n examples: [\"2110625629\"] as const,\n compact,\n format,\n parse,\n validate,\n generate,\n};\n\nexport default cpr;\nexport { compact, format, generate, parse, validate };\n"],"mappings":";;;;;;;;;;;;;;;AAsBA,MAAM,WAAW,UACf,MAAM,OAAO,KAAK;AAEpB,MAAM,cAAc,IAAY,OAAuB;AAErD,KAAI,MAAM,KAAK,MAAM,EAAG,QAAO;AAC/B,KAAI,OAAO,KAAK,OAAO,EACrB,QAAO,MAAM,KAAK,MAAO;AAG3B,QAAO,MAAM,KAAK,MAAO;;AAG3B,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,GACf,QAAO,IACL,kBACA,gCACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,+BACD;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;CAIhC,MAAM,OADU,WAAW,IAFhB,OAAO,EAAE,GAAG,CAEW,GACX;AAEvB,KAAI,CAAC,YAAY,MAAM,IAAI,GAAG,CAC5B,QAAO,IACL,qBACA,+BACD;AAIH,KAAI,IAAI,KAAK,MAAM,KAAK,GAAG,GAAG,mBAAG,IAAI,MAAM,CACzC,QAAO,IACL,qBACA,kCACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;AACxB,QAAO,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE;;;;;;AAOvC,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,KAAK,OAAO,EAAE,GAAG;CACvB,MAAM,YAAY,OAAO,EAAE,GAAG;CAG9B,MAAM,OADU,WAAW,IAAI,GAAG,GACX;AAEvB,QAAO;EACL,WAAW,IAAI,KAAK,MAAM,KAAK,GAAG,GAAG;EACrC,QAAQ,YAAY,MAAM,IAAI,WAAW;EAC1C;;;AAIH,MAAM,iBAAyB;CAC7B,MAAM,OAAO,UAAU,MAAM,KAAK;CAClC,MAAM,QAAQ,OAAO,UAAU,GAAG,GAAG,CAAC,CAAC,SAAS,GAAG,IAAI;AAIvD,QAAO,GAHK,OAAO,UAAU,GAAG,GAAG,CAAC,CAAC,SAAS,GAAG,IAAI,GAGrC,QAFL,OAAO,OAAO,IAAI,CAAC,SAAS,GAAG,IAAI,GACzB,OAAO,UAAU,GAAG,EAAE,CAAC,GACA,aAAa,EAAE;;;AAI7D,MAAM,MAAiC;CACrC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EAAC;EAAc;EAAgB;EAAM;CAC9C,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WAAW;CACX,SAAS,CAAC,GAAG;CACb,UAAU,CAAC,aAAa;CACxB;CACA;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"cpr.js","names":[],"sources":["../../src/dk/cpr.ts"],"sourcesContent":["/**\n * CPR (Det Centrale Personregister).\n *\n * Danish personal identification number. 10 digits\n * in format DDMMYY-SSSS. Checksum enforcement was\n * dropped in 2007; only date validation is performed.\n *\n * @see https://cpr.dk/\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\";\nimport { isdigits } from \"#util/strings\";\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst getCentury = (yy: number, s7: number): number => {\n // 7th digit (first of serial) determines century\n if (s7 >= 0 && s7 <= 3) return 1900;\n if (s7 === 4 || s7 === 9) {\n return yy <= 36 ? 2000 : 1900;\n }\n // s7 5..8\n return yy <= 57 ? 2000 : 1800;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 10) {\n return err(\n \"INVALID_LENGTH\",\n \"CPR must be exactly 10 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"CPR must contain only digits\",\n );\n }\n\n const dd = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const yy = Number(v.slice(4, 6));\n const s7 = Number(v[6]);\n\n const century = getCentury(yy, s7);\n const year = century + yy;\n\n if (!isValidDate(year, mm, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"CPR contains an invalid date\",\n );\n }\n\n // Reject future birth dates\n if (new Date(year, mm - 1, dd) > new Date()) {\n return err(\n \"INVALID_COMPONENT\",\n \"CPR birth date is in the future\",\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 CPR 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 dd = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const yy = Number(v.slice(4, 6));\n const s7 = Number(v[6]);\n const lastDigit = Number(v[9]);\n\n const century = getCentury(yy, s7);\n const year = century + yy;\n\n return {\n birthDate: new Date(year, mm - 1, dd),\n gender: lastDigit % 2 === 0 ? \"female\" : \"male\",\n };\n};\n\n/** Generate a random valid Danish CPR. */\nconst generate = (): string => {\n const year = randomInt(1900, 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 serialPrefix = String(randomInt(0, 3));\n return `${day}${month}${yy}${serialPrefix}${randomDigits(3)}`;\n};\n\n/** Danish Personal Identification Number. */\nconst cpr: CountryValidator<\"DK\", ParsedPersonId> = {\n name: \"Danish Personal ID\",\n localName: \"Det Centrale Personregister\",\n abbreviation: \"CPR\",\n aliases: [\"CPR-nummer\", \"personnummer\", \"CPR\"] as const,\n candidatePattern: \"\\\\d{6}-?\\\\d{4}\",\n scope: \"country\",\n country: \"DK\",\n entityType: \"person\",\n sourceUrl: \"https://cpr.dk/\",\n lengths: [10] as const,\n examples: [\"2110625629\"] as const,\n compact,\n format,\n parse,\n validate,\n generate,\n};\n\nexport default cpr;\nexport { compact, format, generate, parse, validate };\n"],"mappings":";;;;;;AAsBA,MAAM,WAAW,UACf,MAAM,OAAO,IAAI;AAEnB,MAAM,cAAc,IAAY,OAAuB;CAErD,IAAI,MAAM,KAAK,MAAM,GAAG,OAAO;CAC/B,IAAI,OAAO,KAAK,OAAO,GACrB,OAAO,MAAM,KAAK,MAAO;CAG3B,OAAO,MAAM,KAAK,MAAO;AAC3B;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,IACf,OAAO,IACL,kBACA,+BACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,8BACF;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;CAI/B,MAAM,OADU,WAAW,IAFhB,OAAO,EAAE,EAEY,CACb,IAAI;CAEvB,IAAI,CAAC,YAAY,MAAM,IAAI,EAAE,GAC3B,OAAO,IACL,qBACA,8BACF;CAIF,IAAI,IAAI,KAAK,MAAM,KAAK,GAAG,EAAE,oBAAI,IAAI,KAAK,GACxC,OAAO,IACL,qBACA,iCACF;CAGF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,KAAK;CACvB,OAAO,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC;AACtC;;;;;AAMA,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;CAC/B,MAAM,KAAK,OAAO,EAAE,EAAE;CACtB,MAAM,YAAY,OAAO,EAAE,EAAE;CAG7B,MAAM,OADU,WAAW,IAAI,EACZ,IAAI;CAEvB,OAAO;EACL,WAAW,IAAI,KAAK,MAAM,KAAK,GAAG,EAAE;EACpC,QAAQ,YAAY,MAAM,IAAI,WAAW;CAC3C;AACF;;AAGA,MAAM,iBAAyB;CAC7B,MAAM,OAAO,UAAU,MAAM,IAAI;CACjC,MAAM,QAAQ,OAAO,UAAU,GAAG,EAAE,CAAC,EAAE,SAAS,GAAG,GAAG;CAItD,OAAO,GAHK,OAAO,UAAU,GAAG,EAAE,CAAC,EAAE,SAAS,GAAG,GAGrC,IAAI,QAFL,OAAO,OAAO,GAAG,EAAE,SAAS,GAAG,GAEjB,IADJ,OAAO,UAAU,GAAG,CAAC,CACF,IAAI,aAAa,CAAC;AAC5D;;AAGA,MAAM,MAA8C;CAClD,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EAAC;EAAc;EAAgB;CAAK;CAC7C,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WAAW;CACX,SAAS,CAAC,EAAE;CACZ,UAAU,CAAC,YAAY;CACvB;CACA;CACA;CACA;CACA;AACF"}
package/dist/dk/cvr.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ValidateResult } from "../types.js";
2
2
 
3
3
  //#region src/dk/cvr.d.ts
4
4
  declare const compact: (value: string) => string;
@@ -7,7 +7,7 @@ declare const format: (value: string) => string;
7
7
  /** Generate a random valid Danish CVR. */
8
8
  declare const generate: () => string;
9
9
  /** Danish Central Business Register Number. */
10
- declare const cvr: Validator;
10
+ declare const cvr: CountryValidator<"DK">;
11
11
  //#endregion
12
12
  export { compact, cvr as default, format, generate, validate };
13
13
  //# sourceMappingURL=cvr.d.ts.map
package/dist/dk/cvr.js CHANGED
@@ -1,23 +1,9 @@
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
  //#region src/dk/cvr.ts
7
- /**
8
- * CVR (Central Business Register number).
9
- *
10
- * 8 digits, no leading 0.
11
- * Weights [2,7,6,5,4,3,2,1], sum % 11 === 0.
12
- *
13
- * Same algorithm as the Danish VAT number, but this
14
- * is the company register identifier.
15
- *
16
- * @see https://erhvervsstyrelsen.dk/
17
- *
18
- * Denmark dropped mod-11 for CPR in 2007; unconfirmed
19
- * for CVR.
20
- */
21
7
  const WEIGHTS = [
22
8
  2,
23
9
  7,
@@ -55,6 +41,7 @@ const cvr = {
55
41
  abbreviation: "CVR",
56
42
  aliases: ["CVR-nummer", "CVR"],
57
43
  candidatePattern: "\\d{8}",
44
+ scope: "country",
58
45
  country: "DK",
59
46
  entityType: "company",
60
47
  sourceUrl: "https://erhvervsstyrelsen.dk/",
@@ -1 +1 @@
1
- {"version":3,"file":"cvr.js","names":[],"sources":["../../src/dk/cvr.ts"],"sourcesContent":["/**\n * CVR (Central Business Register number).\n *\n * 8 digits, no leading 0.\n * Weights [2,7,6,5,4,3,2,1], sum % 11 === 0.\n *\n * Same algorithm as the Danish VAT number, but this\n * is the company register identifier.\n *\n * @see https://erhvervsstyrelsen.dk/\n *\n * Denmark dropped mod-11 for CPR in 2007; unconfirmed\n * for CVR.\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\";\n\nconst WEIGHTS = [2, 7, 6, 5, 4, 3, 2, 1];\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 \"Danish CVR must be 8 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Danish CVR must contain only digits\",\n );\n }\n if (v[0] === \"0\") {\n return err(\n \"INVALID_COMPONENT\",\n \"Danish CVR cannot start with 0\",\n );\n }\n const sum = weightedSum(v, WEIGHTS, 11);\n if (sum !== 0) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Danish CVR check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid Danish CVR. */\nconst generate = (): string => {\n for (;;) {\n const c = String(randomInt(1, 9)) + randomDigits(7);\n if (validate(c).valid) return c;\n }\n};\n\n/** Danish Central Business Register Number. */\nconst cvr: Validator = {\n name: \"Danish Business Register Number\",\n localName: \"CVR-nummer\",\n abbreviation: \"CVR\",\n aliases: [\"CVR-nummer\", \"CVR\"] as const,\n candidatePattern: \"\\\\d{8}\",\n country: \"DK\",\n entityType: \"company\",\n sourceUrl: \"https://erhvervsstyrelsen.dk/\",\n examples: [\"13585628\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default cvr;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAuBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAExC,MAAM,WAAW,UACf,MAAM,OAAO,OAAO;AAEtB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,IACL,kBACA,8BACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,sCACD;AAEH,KAAI,EAAE,OAAO,IACX,QAAO,IACL,qBACA,iCACD;AAGH,KADY,YAAY,GAAG,SAAS,GAAG,KAC3B,EACV,QAAO,IACL,oBACA,kCACD;AAEH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B,QAAQ,MAAM;;AAGxD,MAAM,iBAAyB;AAC7B,UAAS;EACP,MAAM,IAAI,OAAO,UAAU,GAAG,EAAE,CAAC,GAAG,aAAa,EAAE;AACnD,MAAI,SAAS,EAAE,CAAC,MAAO,QAAO;;;;AAKlC,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,cAAc,MAAM;CAC9B,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,WAAW;CACtB;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"cvr.js","names":[],"sources":["../../src/dk/cvr.ts"],"sourcesContent":["/**\n * CVR (Central Business Register number).\n *\n * 8 digits, no leading 0.\n * Weights [2,7,6,5,4,3,2,1], sum % 11 === 0.\n *\n * Same algorithm as the Danish VAT number, but this\n * is the company register identifier.\n *\n * @see https://erhvervsstyrelsen.dk/\n *\n * Denmark dropped mod-11 for CPR in 2007; unconfirmed\n * for CVR.\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, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst WEIGHTS = [2, 7, 6, 5, 4, 3, 2, 1];\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 \"Danish CVR must be 8 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Danish CVR must contain only digits\",\n );\n }\n if (v[0] === \"0\") {\n return err(\n \"INVALID_COMPONENT\",\n \"Danish CVR cannot start with 0\",\n );\n }\n const sum = weightedSum(v, WEIGHTS, 11);\n if (sum !== 0) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Danish CVR check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid Danish CVR. */\nconst generate = (): string => {\n for (;;) {\n const c = String(randomInt(1, 9)) + randomDigits(7);\n if (validate(c).valid) return c;\n }\n};\n\n/** Danish Central Business Register Number. */\nconst cvr: CountryValidator<\"DK\"> = {\n name: \"Danish Business Register Number\",\n localName: \"CVR-nummer\",\n abbreviation: \"CVR\",\n aliases: [\"CVR-nummer\", \"CVR\"] as const,\n candidatePattern: \"\\\\d{8}\",\n scope: \"country\",\n country: \"DK\",\n entityType: \"company\",\n sourceUrl: \"https://erhvervsstyrelsen.dk/\",\n examples: [\"13585628\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default cvr;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AA0BA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAAC;AAEvC,MAAM,WAAW,UACf,MAAM,OAAO,MAAM;AAErB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,GACf,OAAO,IACL,kBACA,6BACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,qCACF;CAEF,IAAI,EAAE,OAAO,KACX,OAAO,IACL,qBACA,gCACF;CAGF,IADY,YAAY,GAAG,SAAS,EAC9B,MAAM,GACV,OAAO,IACL,oBACA,iCACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B,QAAQ,KAAK;;AAGvD,MAAM,iBAAyB;CAC7B,SAAS;EACP,MAAM,IAAI,OAAO,UAAU,GAAG,CAAC,CAAC,IAAI,aAAa,CAAC;EAClD,IAAI,SAAS,CAAC,EAAE,OAAO,OAAO;CAChC;AACF;;AAGA,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,cAAc,KAAK;CAC7B,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,UAAU;CACrB;CACA;CACA;CACA;AACF"}
package/dist/dk/vat.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ValidateResult } from "../types.js";
2
2
 
3
3
  //#region src/dk/vat.d.ts
4
4
  declare const compact: (value: string) => string;
@@ -7,7 +7,7 @@ declare const format: (value: string) => string;
7
7
  /** Generate a random valid Danish VAT number. */
8
8
  declare const generate: () => string;
9
9
  /** Danish VAT Number. */
10
- declare const vat: Validator;
10
+ declare const vat: CountryValidator<"DK">;
11
11
  //#endregion
12
12
  export { compact, vat as default, format, generate, validate };
13
13
  //# sourceMappingURL=vat.d.ts.map
package/dist/dk/vat.js CHANGED
@@ -1,21 +1,9 @@
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
  //#region src/dk/vat.ts
7
- /**
8
- * CVR (Danish VAT / business registration number).
9
- *
10
- * 8 digits, no leading 0.
11
- * Weights [2,7,6,5,4,3,2,1], sum % 11 === 0.
12
- *
13
- * @see https://www.vatify.eu/denmark-vat-number.html
14
- * @see https://erhvervsstyrelsen.dk/det-centrale-virksomhedsregister-cvr
15
- *
16
- * Denmark dropped mod-11 for CPR in 2007; unconfirmed
17
- * for CVR.
18
- */
19
7
  const WEIGHTS = [
20
8
  2,
21
9
  7,
@@ -57,9 +45,11 @@ const vat = {
57
45
  abbreviation: "CVR",
58
46
  aliases: ["momsnummer", "SE-nummer"],
59
47
  candidatePattern: "DK\\d{8}",
48
+ scope: "country",
60
49
  country: "DK",
61
50
  entityType: "company",
62
51
  sourceUrl: "https://erhvervsstyrelsen.dk/",
52
+ lengths: [8],
63
53
  examples: ["13585628"],
64
54
  compact,
65
55
  format,
@@ -1 +1 @@
1
- {"version":3,"file":"vat.js","names":[],"sources":["../../src/dk/vat.ts"],"sourcesContent":["/**\n * CVR (Danish VAT / business registration number).\n *\n * 8 digits, no leading 0.\n * Weights [2,7,6,5,4,3,2,1], sum % 11 === 0.\n *\n * @see https://www.vatify.eu/denmark-vat-number.html\n * @see https://erhvervsstyrelsen.dk/det-centrale-virksomhedsregister-cvr\n *\n * Denmark dropped mod-11 for CPR in 2007; unconfirmed\n * for CVR.\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\";\n\nconst WEIGHTS = [2, 7, 6, 5, 4, 3, 2, 1];\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -/.\");\n if (v.startsWith(\"DK\") || v.startsWith(\"dk\")) {\n v = v.slice(2);\n }\n return v;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 8) {\n return err(\n \"INVALID_LENGTH\",\n \"Danish VAT number must be 8 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Danish VAT number must contain only digits\",\n );\n }\n if (v[0] === \"0\") {\n return err(\n \"INVALID_COMPONENT\",\n \"Danish VAT number cannot start with 0\",\n );\n }\n const sum = weightedSum(v, WEIGHTS, 11);\n if (sum !== 0) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Danish VAT number check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string =>\n `DK${compact(value)}`;\n\n/** Generate a random valid Danish VAT number. */\nconst generate = (): string => {\n for (;;) {\n const c = String(randomInt(1, 9)) + randomDigits(7);\n if (validate(c).valid) return c;\n }\n};\n\n/** Danish VAT Number. */\nconst vat: Validator = {\n name: \"Danish VAT Number\",\n localName: \"Momsregistreringsnummer\",\n abbreviation: \"CVR\",\n aliases: [\"momsnummer\", \"SE-nummer\"] as const,\n candidatePattern: \"DK\\\\d{8}\",\n country: \"DK\",\n entityType: \"company\",\n sourceUrl: \"https://erhvervsstyrelsen.dk/\",\n examples: [\"13585628\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default vat;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAExC,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;;AAGT,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,IACL,kBACA,qCACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,6CACD;AAEH,KAAI,EAAE,OAAO,IACX,QAAO,IACL,qBACA,wCACD;AAGH,KADY,YAAY,GAAG,SAAS,GAAG,KAC3B,EACV,QAAO,IACL,oBACA,yCACD;AAEH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UACd,KAAK,QAAQ,MAAM;;AAGrB,MAAM,iBAAyB;AAC7B,UAAS;EACP,MAAM,IAAI,OAAO,UAAU,GAAG,EAAE,CAAC,GAAG,aAAa,EAAE;AACnD,MAAI,SAAS,EAAE,CAAC,MAAO,QAAO;;;;AAKlC,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,cAAc,YAAY;CACpC,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,WAAW;CACtB;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"vat.js","names":[],"sources":["../../src/dk/vat.ts"],"sourcesContent":["/**\n * CVR (Danish VAT / business registration number).\n *\n * 8 digits, no leading 0.\n * Weights [2,7,6,5,4,3,2,1], sum % 11 === 0.\n *\n * @see https://www.vatify.eu/denmark-vat-number.html\n * @see https://erhvervsstyrelsen.dk/det-centrale-virksomhedsregister-cvr\n *\n * Denmark dropped mod-11 for CPR in 2007; unconfirmed\n * for CVR.\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, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst WEIGHTS = [2, 7, 6, 5, 4, 3, 2, 1];\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -/.\");\n if (v.startsWith(\"DK\") || v.startsWith(\"dk\")) {\n v = v.slice(2);\n }\n return v;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 8) {\n return err(\n \"INVALID_LENGTH\",\n \"Danish VAT number must be 8 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Danish VAT number must contain only digits\",\n );\n }\n if (v[0] === \"0\") {\n return err(\n \"INVALID_COMPONENT\",\n \"Danish VAT number cannot start with 0\",\n );\n }\n const sum = weightedSum(v, WEIGHTS, 11);\n if (sum !== 0) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Danish VAT number check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string =>\n `DK${compact(value)}`;\n\n/** Generate a random valid Danish VAT number. */\nconst generate = (): string => {\n for (;;) {\n const c = String(randomInt(1, 9)) + randomDigits(7);\n if (validate(c).valid) return c;\n }\n};\n\n/** Danish VAT Number. */\nconst vat: CountryValidator<\"DK\"> = {\n name: \"Danish VAT Number\",\n localName: \"Momsregistreringsnummer\",\n abbreviation: \"CVR\",\n aliases: [\"momsnummer\", \"SE-nummer\"] as const,\n candidatePattern: \"DK\\\\d{8}\",\n scope: \"country\",\n country: \"DK\",\n entityType: \"company\",\n sourceUrl: \"https://erhvervsstyrelsen.dk/\",\n lengths: [8] as const,\n examples: [\"13585628\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default vat;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AAwBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAAC;AAEvC,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;AACT;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,GACf,OAAO,IACL,kBACA,oCACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,4CACF;CAEF,IAAI,EAAE,OAAO,KACX,OAAO,IACL,qBACA,uCACF;CAGF,IADY,YAAY,GAAG,SAAS,EAC9B,MAAM,GACV,OAAO,IACL,oBACA,wCACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UACd,KAAK,QAAQ,KAAK;;AAGpB,MAAM,iBAAyB;CAC7B,SAAS;EACP,MAAM,IAAI,OAAO,UAAU,GAAG,CAAC,CAAC,IAAI,aAAa,CAAC;EAClD,IAAI,SAAS,CAAC,EAAE,OAAO,OAAO;CAChC;AACF;;AAGA,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,cAAc,WAAW;CACnC,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WAAW;CACX,SAAS,CAAC,CAAC;CACX,UAAU,CAAC,UAAU;CACrB;CACA;CACA;CACA;AACF"}
package/dist/do/rnc.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ValidateResult } from "../types.js";
2
2
 
3
3
  //#region src/do/rnc.d.ts
4
4
  declare const compact: (value: string) => string;
@@ -11,7 +11,7 @@ declare const generate: () => string;
11
11
  *
12
12
  * Examples sourced from python-stdnum test suite.
13
13
  */
14
- declare const rnc: Validator;
14
+ declare const rnc: CountryValidator<"DO">;
15
15
  //#endregion
16
16
  export { compact, rnc as default, format, generate, validate };
17
17
  //# sourceMappingURL=rnc.d.ts.map
package/dist/do/rnc.js CHANGED
@@ -1,25 +1,10 @@
1
+ import { luhnValidate } from "../_checksums/luhn.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
- import { luhnValidate } from "../_checksums/luhn.js";
5
5
  import { isdigits } from "../_util/strings.js";
6
6
  //#region src/do/rnc.ts
7
7
  /**
8
- * RNC (Registro Nacional del Contribuyente) /
9
- * Cédula de Identidad.
10
- *
11
- * Dominican Republic tax identification number.
12
- * Companies use a 9-digit RNC with a check digit
13
- * computed via weighted sum mod 11. Individuals
14
- * use an 11-digit Cédula validated with the Luhn
15
- * algorithm.
16
- *
17
- * Format: ######### (9 digits, company RNC)
18
- * ########### (11 digits, individual Cédula)
19
- *
20
- * @see https://dgii.gov.do/
21
- */
22
- /**
23
8
  * Weights for the 9-digit RNC check digit.
24
9
  * Applied to positions 0-7; check digit is at
25
10
  * position 8.
@@ -79,6 +64,7 @@ const rnc = {
79
64
  abbreviation: "RNC",
80
65
  aliases: ["RNC", "Registro Nacional del Contribuyente"],
81
66
  candidatePattern: "\\d{9}",
67
+ scope: "country",
82
68
  country: "DO",
83
69
  entityType: "any",
84
70
  lengths: [9, 11],
@@ -1 +1 @@
1
- {"version":3,"file":"rnc.js","names":[],"sources":["../../src/do/rnc.ts"],"sourcesContent":["/**\n * RNC (Registro Nacional del Contribuyente) /\n * Cédula de Identidad.\n *\n * Dominican Republic tax identification number.\n * Companies use a 9-digit RNC with a check digit\n * computed via weighted sum mod 11. Individuals\n * use an 11-digit Cédula validated with the Luhn\n * algorithm.\n *\n * Format: ######### (9 digits, company RNC)\n * ########### (11 digits, individual Cédula)\n *\n * @see https://dgii.gov.do/\n */\n\nimport { luhnValidate } from \"#checksums/luhn\";\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\n/**\n * Weights for the 9-digit RNC check digit.\n * Applied to positions 0-7; check digit is at\n * position 8.\n */\nconst RNC_WEIGHTS = [7, 9, 8, 6, 5, 4, 3, 2] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -.\").trim();\n\n/**\n * RNC check digit: weighted sum mod 11, then\n * ((10 - remainder) % 9) + 1.\n */\nconst calcRncCheckDigit = (value: string): string => {\n let sum = 0;\n for (const [i, weight] of RNC_WEIGHTS.entries()) {\n sum += Number(value[i]) * weight;\n }\n const remainder = sum % 11;\n return String(((10 - remainder) % 9) + 1);\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 9 && v.length !== 11) {\n return err(\n \"INVALID_LENGTH\",\n \"Must be 9 digits (RNC) or 11 digits (Cédula)\",\n );\n }\n\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Must contain only digits\",\n );\n }\n\n if (v.length === 9) {\n const expected = calcRncCheckDigit(v);\n if (v.at(-1) !== expected) {\n return err(\n \"INVALID_CHECKSUM\",\n \"RNC check digit does not match\",\n );\n }\n } else {\n // 11-digit Cédula uses Luhn checksum\n if (!luhnValidate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Cédula Luhn checksum does not match\",\n );\n }\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n if (v.length === 9) {\n return `${v[0]}-${v.slice(1, 3)}-${v.slice(3, 8)}-${v.slice(8)}`;\n }\n return `${v.slice(0, 3)}-${v.slice(3, 10)}-${v.slice(10)}`;\n};\n\n/** Generate a random valid 9-digit RNC. */\nconst generate = (): string => {\n const payload = randomDigits(8);\n return payload + calcRncCheckDigit(payload);\n};\n\n/**\n * Dominican Republic RNC / Cédula.\n *\n * Examples sourced from python-stdnum test suite.\n */\nconst rnc: Validator = {\n name: \"Dominican Republic Tax ID\",\n localName: \"Registro Nacional del Contribuyente\",\n abbreviation: \"RNC\",\n aliases: [\n \"RNC\",\n \"Registro Nacional del Contribuyente\",\n ] as const,\n candidatePattern: \"\\\\d{9}\",\n country: \"DO\",\n entityType: \"any\",\n lengths: [9, 11] as const,\n examples: [\"131098193\", \"00113918205\"] as const,\n compact,\n format,\n validate,\n sourceUrl: \"https://dgii.gov.do/\",\n generate,\n};\n\nexport default rnc;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAM,cAAc;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAE5C,MAAM,WAAW,UACf,MAAM,OAAO,MAAM,CAAC,MAAM;;;;;AAM5B,MAAM,qBAAqB,UAA0B;CACnD,IAAI,MAAM;AACV,MAAK,MAAM,CAAC,GAAG,WAAW,YAAY,SAAS,CAC7C,QAAO,OAAO,MAAM,GAAG,GAAG;CAE5B,MAAM,YAAY,MAAM;AACxB,QAAO,QAAS,KAAK,aAAa,IAAK,EAAE;;AAG3C,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,KAAK,EAAE,WAAW,GACjC,QAAO,IACL,kBACA,+CACD;AAGH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,2BACD;AAGH,KAAI,EAAE,WAAW,GAAG;EAClB,MAAM,WAAW,kBAAkB,EAAE;AACrC,MAAI,EAAE,GAAG,GAAG,KAAK,SACf,QAAO,IACL,oBACA,iCACD;YAIC,CAAC,aAAa,EAAE,CAClB,QAAO,IACL,oBACA,sCACD;AAIL,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,GAAG,EAAE,GAAG,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE;AAEhE,QAAO,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG;;;AAI1D,MAAM,iBAAyB;CAC7B,MAAM,UAAU,aAAa,EAAE;AAC/B,QAAO,UAAU,kBAAkB,QAAQ;;;;;;;AAQ7C,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CACP,OACA,sCACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,GAAG,GAAG;CAChB,UAAU,CAAC,aAAa,cAAc;CACtC;CACA;CACA;CACA,WAAW;CACX;CACD"}
1
+ {"version":3,"file":"rnc.js","names":[],"sources":["../../src/do/rnc.ts"],"sourcesContent":["/**\n * RNC (Registro Nacional del Contribuyente) /\n * Cédula de Identidad.\n *\n * Dominican Republic tax identification number.\n * Companies use a 9-digit RNC with a check digit\n * computed via weighted sum mod 11. Individuals\n * use an 11-digit Cédula validated with the Luhn\n * algorithm.\n *\n * Format: ######### (9 digits, company RNC)\n * ########### (11 digits, individual Cédula)\n *\n * @see https://dgii.gov.do/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { luhnValidate } from \"#checksums/luhn\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\n/**\n * Weights for the 9-digit RNC check digit.\n * Applied to positions 0-7; check digit is at\n * position 8.\n */\nconst RNC_WEIGHTS = [7, 9, 8, 6, 5, 4, 3, 2] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -.\").trim();\n\n/**\n * RNC check digit: weighted sum mod 11, then\n * ((10 - remainder) % 9) + 1.\n */\nconst calcRncCheckDigit = (value: string): string => {\n let sum = 0;\n for (const [i, weight] of RNC_WEIGHTS.entries()) {\n sum += Number(value[i]) * weight;\n }\n const remainder = sum % 11;\n return String(((10 - remainder) % 9) + 1);\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 9 && v.length !== 11) {\n return err(\n \"INVALID_LENGTH\",\n \"Must be 9 digits (RNC) or 11 digits (Cédula)\",\n );\n }\n\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Must contain only digits\",\n );\n }\n\n if (v.length === 9) {\n const expected = calcRncCheckDigit(v);\n if (v.at(-1) !== expected) {\n return err(\n \"INVALID_CHECKSUM\",\n \"RNC check digit does not match\",\n );\n }\n } else {\n // 11-digit Cédula uses Luhn checksum\n if (!luhnValidate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Cédula Luhn checksum does not match\",\n );\n }\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n if (v.length === 9) {\n return `${v[0]}-${v.slice(1, 3)}-${v.slice(3, 8)}-${v.slice(8)}`;\n }\n return `${v.slice(0, 3)}-${v.slice(3, 10)}-${v.slice(10)}`;\n};\n\n/** Generate a random valid 9-digit RNC. */\nconst generate = (): string => {\n const payload = randomDigits(8);\n return payload + calcRncCheckDigit(payload);\n};\n\n/**\n * Dominican Republic RNC / Cédula.\n *\n * Examples sourced from python-stdnum test suite.\n */\nconst rnc: CountryValidator<\"DO\"> = {\n name: \"Dominican Republic Tax ID\",\n localName: \"Registro Nacional del Contribuyente\",\n abbreviation: \"RNC\",\n aliases: [\n \"RNC\",\n \"Registro Nacional del Contribuyente\",\n ] as const,\n candidatePattern: \"\\\\d{9}\",\n scope: \"country\",\n country: \"DO\",\n entityType: \"any\",\n lengths: [9, 11] as const,\n examples: [\"131098193\", \"00113918205\"] as const,\n compact,\n format,\n validate,\n sourceUrl: \"https://dgii.gov.do/\",\n generate,\n};\n\nexport default rnc;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;AAgCA,MAAM,cAAc;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAAC;AAE3C,MAAM,WAAW,UACf,MAAM,OAAO,KAAK,EAAE,KAAK;;;;;AAM3B,MAAM,qBAAqB,UAA0B;CACnD,IAAI,MAAM;CACV,KAAK,MAAM,CAAC,GAAG,WAAW,YAAY,QAAQ,GAC5C,OAAO,OAAO,MAAM,EAAE,IAAI;CAE5B,MAAM,YAAY,MAAM;CACxB,OAAO,QAAS,KAAK,aAAa,IAAK,CAAC;AAC1C;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CAEvB,IAAI,EAAE,WAAW,KAAK,EAAE,WAAW,IACjC,OAAO,IACL,kBACA,8CACF;CAGF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,0BACF;CAGF,IAAI,EAAE,WAAW,GAAG;EAClB,MAAM,WAAW,kBAAkB,CAAC;EACpC,IAAI,EAAE,GAAG,EAAE,MAAM,UACf,OAAO,IACL,oBACA,gCACF;CAEJ,OAEE,IAAI,CAAC,aAAa,CAAC,GACjB,OAAO,IACL,oBACA,qCACF;CAIJ,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,GACf,OAAO,GAAG,EAAE,GAAG,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC;CAE/D,OAAO,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE;AACzD;;AAGA,MAAM,iBAAyB;CAC7B,MAAM,UAAU,aAAa,CAAC;CAC9B,OAAO,UAAU,kBAAkB,OAAO;AAC5C;;;;;;AAOA,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CACP,OACA,qCACF;CACA,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,GAAG,EAAE;CACf,UAAU,CAAC,aAAa,aAAa;CACrC;CACA;CACA;CACA,WAAW;CACX;AACF"}
package/dist/ec/ruc.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ValidateResult } from "../types.js";
2
2
 
3
3
  //#region src/ec/ruc.d.ts
4
4
  declare const compact: (value: string) => string;
@@ -7,7 +7,7 @@ declare const format: (value: string) => string;
7
7
  /** Generate a random valid Ecuadorian RUC. */
8
8
  declare const generate: () => string;
9
9
  /** Ecuadorian tax identification number. */
10
- declare const ruc: Validator;
10
+ declare const ruc: CountryValidator<"EC">;
11
11
  //#endregion
12
12
  export { compact, ruc as default, format, generate, validate };
13
13
  //# sourceMappingURL=ruc.d.ts.map
package/dist/ec/ruc.js CHANGED
@@ -3,24 +3,6 @@ import { randomDigits, randomInt } from "../_util/generate.js";
3
3
  import { err } from "../_util/result.js";
4
4
  import { isdigits } from "../_util/strings.js";
5
5
  //#region src/ec/ruc.ts
6
- /**
7
- * RUC (Registro Único de Contribuyentes).
8
- *
9
- * Ecuadorian tax identification number. 13 digits:
10
- * - Digits 1-2: province code (01-24, 30, or 50)
11
- * - Digit 3: type indicator
12
- * - 0-5: natural person (CI + establishment)
13
- * - 6: public entity (or natural person fallback)
14
- * - 9: juridical entity (public checksum first,
15
- * then juridical fallback)
16
- *
17
- * Natural persons use a Luhn-like mod-10 checksum on
18
- * the first 10 digits. Public entities use a mod-11
19
- * checksum on the first 9 digits. Private companies
20
- * use a mod-11 checksum on the first 10 digits.
21
- *
22
- * @see https://www.sri.gob.ec/
23
- */
24
6
  const compact = (value) => clean(value, " -");
25
7
  /** CI mod-10 checksum: weights [2,1,2,1,...], fold
26
8
  * products > 9 by subtracting 9, sum mod 10 == 0. */
@@ -133,6 +115,7 @@ const ruc = {
133
115
  abbreviation: "RUC",
134
116
  aliases: ["RUC", "Registro Único de Contribuyentes"],
135
117
  candidatePattern: "\\d{13}",
118
+ scope: "country",
136
119
  country: "EC",
137
120
  entityType: "any",
138
121
  description: "13-digit tax identification number issued by the SRI",
@@ -1 +1 @@
1
- {"version":3,"file":"ruc.js","names":[],"sources":["../../src/ec/ruc.ts"],"sourcesContent":["/**\n * RUC (Registro Único de Contribuyentes).\n *\n * Ecuadorian tax identification number. 13 digits:\n * - Digits 1-2: province code (01-24, 30, or 50)\n * - Digit 3: type indicator\n * - 0-5: natural person (CI + establishment)\n * - 6: public entity (or natural person fallback)\n * - 9: juridical entity (public checksum first,\n * then juridical fallback)\n *\n * Natural persons use a Luhn-like mod-10 checksum on\n * the first 10 digits. Public entities use a mod-11\n * checksum on the first 9 digits. Private companies\n * use a mod-11 checksum on the first 10 digits.\n *\n * @see https://www.sri.gob.ec/\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\n/** CI mod-10 checksum: weights [2,1,2,1,...], fold\n * products > 9 by subtracting 9, sum mod 10 == 0. */\nconst ciChecksum = (digits: string): number => {\n let sum = 0;\n for (let i = 0; i < digits.length; i++) {\n const weight = i % 2 === 0 ? 2 : 1;\n let product = Number(digits[i]) * weight;\n if (product > 9) product -= 9;\n sum += product;\n }\n return sum % 10;\n};\n\n/** Weighted mod-11 checksum. */\nconst mod11Checksum = (\n digits: string,\n weights: readonly number[],\n): number => {\n let sum = 0;\n for (const [i, weight] of weights.entries()) {\n sum += Number(digits[i]) * weight;\n }\n return sum % 11;\n};\n\nconst PUBLIC_WEIGHTS = [3, 2, 7, 6, 5, 4, 3, 2, 1];\nconst JURIDICAL_WEIGHTS = [4, 3, 2, 7, 6, 5, 4, 3, 2, 1];\n\nconst isValidProvince = (v: string): boolean => {\n const province = v.slice(0, 2);\n return (\n (province >= \"01\" && province <= \"24\") ||\n province === \"30\" ||\n province === \"50\"\n );\n};\n\nconst validateNatural = (\n v: string,\n): ValidateResult | null => {\n if (v.slice(-3) === \"000\") return null;\n if (ciChecksum(v.slice(0, 10)) !== 0) return null;\n return { valid: true, compact: v };\n};\n\nconst validatePublic = (\n v: string,\n): ValidateResult | null => {\n if (v.slice(-4) === \"0000\") return null;\n if (mod11Checksum(v, PUBLIC_WEIGHTS) !== 0) return null;\n return { valid: true, compact: v };\n};\n\nconst validateJuridical = (\n v: string,\n): ValidateResult | null => {\n if (v.slice(-3) === \"000\") return null;\n if (mod11Checksum(v, JURIDICAL_WEIGHTS) !== 0) {\n return null;\n }\n return { valid: true, compact: v };\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 13) {\n return err(\n \"INVALID_LENGTH\",\n \"RUC must be exactly 13 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"RUC must contain only digits\",\n );\n }\n if (!isValidProvince(v)) {\n return err(\n \"INVALID_COMPONENT\",\n \"RUC province code is invalid\",\n );\n }\n\n const typeDigit = Number(v[2]);\n\n if (typeDigit <= 5) {\n // Natural person\n const result = validateNatural(v);\n if (result) return result;\n return err(\n \"INVALID_CHECKSUM\",\n \"RUC check digit does not match\",\n );\n }\n\n if (typeDigit === 6) {\n // Public entity; fall back to natural person\n const pub = validatePublic(v);\n if (pub) return pub;\n const nat = validateNatural(v);\n if (nat) return nat;\n return err(\n \"INVALID_CHECKSUM\",\n \"RUC check digit does not match\",\n );\n }\n\n if (typeDigit === 9) {\n // Juridical RUC; try public checksum first, fall\n // back to juridical (matches python-stdnum).\n const pub = validatePublic(v);\n if (pub) return pub;\n const jur = validateJuridical(v);\n if (jur) return jur;\n return err(\n \"INVALID_CHECKSUM\",\n \"RUC check digit does not match\",\n );\n }\n\n return err(\n \"INVALID_COMPONENT\",\n \"RUC type digit is invalid\",\n );\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid Ecuadorian RUC. */\nconst generate = (): string => {\n for (;;) {\n const province = String(randomInt(1, 24)).padStart(\n 2,\n \"0\",\n );\n const c = province + randomDigits(11);\n if (validate(c).valid) return c;\n }\n};\n\n/** Ecuadorian tax identification number. */\nconst ruc: Validator = {\n name: \"Registro Único de Contribuyentes\",\n localName: \"Registro Único de Contribuyentes\",\n abbreviation: \"RUC\",\n aliases: [\n \"RUC\",\n \"Registro Único de Contribuyentes\",\n ] as const,\n candidatePattern: \"\\\\d{13}\",\n country: \"EC\",\n entityType: \"any\",\n description:\n \"13-digit tax identification number issued by the SRI\",\n sourceUrl: \"https://www.sri.gob.ec/\",\n lengths: [13] as const,\n examples: [\"1792060346001\", \"1790011674001\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default ruc;\nexport { compact, format, validate, generate };\n"],"mappings":"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"}
1
+ {"version":3,"file":"ruc.js","names":[],"sources":["../../src/ec/ruc.ts"],"sourcesContent":["/**\n * RUC (Registro Único de Contribuyentes).\n *\n * Ecuadorian tax identification number. 13 digits:\n * - Digits 1-2: province code (01-24, 30, or 50)\n * - Digit 3: type indicator\n * - 0-5: natural person (CI + establishment)\n * - 6: public entity (or natural person fallback)\n * - 9: juridical entity (public checksum first,\n * then juridical fallback)\n *\n * Natural persons use a Luhn-like mod-10 checksum on\n * the first 10 digits. Public entities use a mod-11\n * checksum on the first 9 digits. Private companies\n * use a mod-11 checksum on the first 10 digits.\n *\n * @see https://www.sri.gob.ec/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\n/** CI mod-10 checksum: weights [2,1,2,1,...], fold\n * products > 9 by subtracting 9, sum mod 10 == 0. */\nconst ciChecksum = (digits: string): number => {\n let sum = 0;\n for (let i = 0; i < digits.length; i++) {\n const weight = i % 2 === 0 ? 2 : 1;\n let product = Number(digits[i]) * weight;\n if (product > 9) product -= 9;\n sum += product;\n }\n return sum % 10;\n};\n\n/** Weighted mod-11 checksum. */\nconst mod11Checksum = (\n digits: string,\n weights: readonly number[],\n): number => {\n let sum = 0;\n for (const [i, weight] of weights.entries()) {\n sum += Number(digits[i]) * weight;\n }\n return sum % 11;\n};\n\nconst PUBLIC_WEIGHTS = [3, 2, 7, 6, 5, 4, 3, 2, 1];\nconst JURIDICAL_WEIGHTS = [4, 3, 2, 7, 6, 5, 4, 3, 2, 1];\n\nconst isValidProvince = (v: string): boolean => {\n const province = v.slice(0, 2);\n return (\n (province >= \"01\" && province <= \"24\") ||\n province === \"30\" ||\n province === \"50\"\n );\n};\n\nconst validateNatural = (\n v: string,\n): ValidateResult | null => {\n if (v.slice(-3) === \"000\") return null;\n if (ciChecksum(v.slice(0, 10)) !== 0) return null;\n return { valid: true, compact: v };\n};\n\nconst validatePublic = (\n v: string,\n): ValidateResult | null => {\n if (v.slice(-4) === \"0000\") return null;\n if (mod11Checksum(v, PUBLIC_WEIGHTS) !== 0) return null;\n return { valid: true, compact: v };\n};\n\nconst validateJuridical = (\n v: string,\n): ValidateResult | null => {\n if (v.slice(-3) === \"000\") return null;\n if (mod11Checksum(v, JURIDICAL_WEIGHTS) !== 0) {\n return null;\n }\n return { valid: true, compact: v };\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 13) {\n return err(\n \"INVALID_LENGTH\",\n \"RUC must be exactly 13 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"RUC must contain only digits\",\n );\n }\n if (!isValidProvince(v)) {\n return err(\n \"INVALID_COMPONENT\",\n \"RUC province code is invalid\",\n );\n }\n\n const typeDigit = Number(v[2]);\n\n if (typeDigit <= 5) {\n // Natural person\n const result = validateNatural(v);\n if (result) return result;\n return err(\n \"INVALID_CHECKSUM\",\n \"RUC check digit does not match\",\n );\n }\n\n if (typeDigit === 6) {\n // Public entity; fall back to natural person\n const pub = validatePublic(v);\n if (pub) return pub;\n const nat = validateNatural(v);\n if (nat) return nat;\n return err(\n \"INVALID_CHECKSUM\",\n \"RUC check digit does not match\",\n );\n }\n\n if (typeDigit === 9) {\n // Juridical RUC; try public checksum first, fall\n // back to juridical (matches python-stdnum).\n const pub = validatePublic(v);\n if (pub) return pub;\n const jur = validateJuridical(v);\n if (jur) return jur;\n return err(\n \"INVALID_CHECKSUM\",\n \"RUC check digit does not match\",\n );\n }\n\n return err(\n \"INVALID_COMPONENT\",\n \"RUC type digit is invalid\",\n );\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid Ecuadorian RUC. */\nconst generate = (): string => {\n for (;;) {\n const province = String(randomInt(1, 24)).padStart(\n 2,\n \"0\",\n );\n const c = province + randomDigits(11);\n if (validate(c).valid) return c;\n }\n};\n\n/** Ecuadorian tax identification number. */\nconst ruc: CountryValidator<\"EC\"> = {\n name: \"Registro Único de Contribuyentes\",\n localName: \"Registro Único de Contribuyentes\",\n abbreviation: \"RUC\",\n aliases: [\n \"RUC\",\n \"Registro Único de Contribuyentes\",\n ] as const,\n candidatePattern: \"\\\\d{13}\",\n scope: \"country\",\n country: \"EC\",\n entityType: \"any\",\n description:\n \"13-digit tax identification number issued by the SRI\",\n sourceUrl: \"https://www.sri.gob.ec/\",\n lengths: [13] as const,\n examples: [\"1792060346001\", \"1790011674001\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default ruc;\nexport { compact, format, validate, generate };\n"],"mappings":"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"}
package/dist/ee/ik.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ParsedPersonId, ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ParsedPersonId, ValidateResult } from "../types.js";
2
2
 
3
3
  //#region src/ee/ik.d.ts
4
4
  declare const compact: (value: string) => string;
@@ -17,7 +17,7 @@ declare const parse: (value: string) => ParsedPersonId | null;
17
17
  /** Generate a random valid Estonian IK. */
18
18
  declare const generate: () => string;
19
19
  /** Estonian Personal Identification Code. */
20
- declare const ik: Validator<ParsedPersonId>;
20
+ declare const ik: CountryValidator<"EE", ParsedPersonId>;
21
21
  //#endregion
22
22
  export { compact, ik as default, format, generate, parse, twoPassCheck, validate };
23
23
  //# sourceMappingURL=ik.d.ts.map
package/dist/ee/ik.js CHANGED
@@ -1,28 +1,10 @@
1
+ import { weightedSum } from "../_checksums/weighted-sum.js";
1
2
  import { clean } from "../_util/clean.js";
3
+ import { isValidDate } from "../_util/date.js";
2
4
  import { randomInt } from "../_util/generate.js";
3
5
  import { err } from "../_util/result.js";
4
6
  import { isdigits } from "../_util/strings.js";
5
- import { weightedSum } from "../_checksums/weighted-sum.js";
6
- import { isValidDate } from "../_util/date.js";
7
7
  //#region src/ee/ik.ts
8
- /**
9
- * Isikukood (IK).
10
- *
11
- * Estonian personal identification code. 11 digits:
12
- * gender/century digit, YYMMDD, 3-digit serial, and
13
- * a check digit computed with two-pass weighted sums.
14
- *
15
- * Canonical sources:
16
- * - Estonian legislation for the personal code format
17
- * - OECD Estonia TIN sheet summarising the same
18
- * first-digit ranges for cross-border tax use
19
- *
20
- * These sources are why we restrict the first digit
21
- * to 1-6 rather than accepting speculative 7/8 forms.
22
- *
23
- * @see https://www.riigiteataja.ee/en/eli/512012015003/consolide
24
- * @see https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Estonia-TIN.pdf
25
- */
26
8
  const WEIGHTS_1 = [
27
9
  1,
28
10
  2,
@@ -123,6 +105,7 @@ const ik = {
123
105
  abbreviation: "IK",
124
106
  aliases: ["isikukood", "IK"],
125
107
  candidatePattern: "[1-6]\\d{10}",
108
+ scope: "country",
126
109
  country: "EE",
127
110
  entityType: "person",
128
111
  sourceUrl: "https://www.riigiteataja.ee/en/eli/512012015003/consolide",
package/dist/ee/ik.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ik.js","names":[],"sources":["../../src/ee/ik.ts"],"sourcesContent":["/**\n * Isikukood (IK).\n *\n * Estonian personal identification code. 11 digits:\n * gender/century digit, YYMMDD, 3-digit serial, and\n * a check digit computed with two-pass weighted sums.\n *\n * Canonical sources:\n * - Estonian legislation for the personal code format\n * - OECD Estonia TIN sheet summarising the same\n * first-digit ranges for cross-border tax use\n *\n * These sources are why we restrict the first digit\n * to 1-6 rather than accepting speculative 7/8 forms.\n *\n * @see https://www.riigiteataja.ee/en/eli/512012015003/consolide\n * @see https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Estonia-TIN.pdf\n */\n\nimport { weightedSum } from \"#checksums/weighted-sum\";\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 WEIGHTS_1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1] as const;\nconst WEIGHTS_2 = [3, 4, 5, 6, 7, 8, 9, 1, 2, 3] as const;\n\nconst centuryMap: Record<number, number> = {\n 1: 1800,\n 2: 1800,\n 3: 1900,\n 4: 1900,\n 5: 2000,\n 6: 2000,\n};\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\n/**\n * Compute the two-pass check digit used by both\n * Estonian IK and Lithuanian Asmens kodas.\n */\nexport const twoPassCheck = (digits: string): number => {\n let remainder = weightedSum(digits, WEIGHTS_1, 11);\n if (remainder !== 10) return remainder;\n remainder = weightedSum(digits, WEIGHTS_2, 11);\n return remainder === 10 ? 0 : remainder;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 11) {\n return err(\n \"INVALID_LENGTH\",\n \"Isikukood must be exactly 11 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Isikukood must contain only digits\",\n );\n }\n\n const g = Number(v[0]);\n // Official Estonian structure uses 1-6:\n // 1-2 = 1800s, 3-4 = 1900s, 5-6 = 2000s.\n if (g < 1 || g > 6) {\n return err(\n \"INVALID_COMPONENT\",\n \"Isikukood gender/century digit is invalid\",\n );\n }\n\n const century = centuryMap[g] ?? 1900;\n const yy = Number(v.slice(1, 3));\n const mm = Number(v.slice(3, 5));\n const dd = Number(v.slice(5, 7));\n const year = century + yy;\n\n if (!isValidDate(year, mm, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Isikukood contains an invalid date\",\n );\n }\n\n const check = twoPassCheck(v.slice(0, 10));\n if (check !== Number(v[10])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Isikukood check digit does not match\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/**\n * Extract birth date and gender from an Isikukood.\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 g = Number(v[0]);\n const century = centuryMap[g] ?? 1900;\n const yy = Number(v.slice(1, 3));\n const mm = Number(v.slice(3, 5));\n const dd = Number(v.slice(5, 7));\n const year = century + yy;\n\n return {\n birthDate: new Date(year, mm - 1, dd),\n gender: g % 2 === 1 ? \"male\" : \"female\",\n };\n};\n\n/** Generate a random valid Estonian IK. */\nconst generate = (): string => {\n for (;;) {\n const g = String(randomInt(3, 6));\n const yy = String(randomInt(0, 99)).padStart(2, \"0\");\n const mm = String(randomInt(1, 12)).padStart(2, \"0\");\n const dd = String(randomInt(1, 28)).padStart(2, \"0\");\n const s = String(randomInt(0, 999)).padStart(3, \"0\");\n const payload = g + yy + mm + dd + s;\n const c = payload + String(twoPassCheck(payload));\n if (validate(c).valid) return c;\n }\n};\n\n/** Estonian Personal Identification Code. */\nconst ik: Validator<ParsedPersonId> = {\n name: \"Estonian Personal ID\",\n localName: \"Isikukood\",\n abbreviation: \"IK\",\n aliases: [\"isikukood\", \"IK\"] as const,\n candidatePattern: \"[1-6]\\\\d{10}\",\n country: \"EE\",\n entityType: \"person\",\n sourceUrl:\n \"https://www.riigiteataja.ee/en/eli/512012015003/consolide\",\n examples: [\"36805280109\"] as const,\n compact,\n format,\n parse,\n validate,\n generate,\n};\n\nexport default ik;\nexport { compact, format, parse, validate, generate };\n"],"mappings":"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"}
1
+ {"version":3,"file":"ik.js","names":[],"sources":["../../src/ee/ik.ts"],"sourcesContent":["/**\n * Isikukood (IK).\n *\n * Estonian personal identification code. 11 digits:\n * gender/century digit, YYMMDD, 3-digit serial, and\n * a check digit computed with two-pass weighted sums.\n *\n * Canonical sources:\n * - Estonian legislation for the personal code format\n * - OECD Estonia TIN sheet summarising the same\n * first-digit ranges for cross-border tax use\n *\n * These sources are why we restrict the first digit\n * to 1-6 rather than accepting speculative 7/8 forms.\n *\n * @see https://www.riigiteataja.ee/en/eli/512012015003/consolide\n * @see https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Estonia-TIN.pdf\n */\n\nimport type {\n ParsedPersonId,\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { weightedSum } from \"#checksums/weighted-sum\";\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 WEIGHTS_1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1] as const;\nconst WEIGHTS_2 = [3, 4, 5, 6, 7, 8, 9, 1, 2, 3] as const;\n\nconst centuryMap: Record<number, number> = {\n 1: 1800,\n 2: 1800,\n 3: 1900,\n 4: 1900,\n 5: 2000,\n 6: 2000,\n};\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\n/**\n * Compute the two-pass check digit used by both\n * Estonian IK and Lithuanian Asmens kodas.\n */\nexport const twoPassCheck = (digits: string): number => {\n let remainder = weightedSum(digits, WEIGHTS_1, 11);\n if (remainder !== 10) return remainder;\n remainder = weightedSum(digits, WEIGHTS_2, 11);\n return remainder === 10 ? 0 : remainder;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 11) {\n return err(\n \"INVALID_LENGTH\",\n \"Isikukood must be exactly 11 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Isikukood must contain only digits\",\n );\n }\n\n const g = Number(v[0]);\n // Official Estonian structure uses 1-6:\n // 1-2 = 1800s, 3-4 = 1900s, 5-6 = 2000s.\n if (g < 1 || g > 6) {\n return err(\n \"INVALID_COMPONENT\",\n \"Isikukood gender/century digit is invalid\",\n );\n }\n\n const century = centuryMap[g] ?? 1900;\n const yy = Number(v.slice(1, 3));\n const mm = Number(v.slice(3, 5));\n const dd = Number(v.slice(5, 7));\n const year = century + yy;\n\n if (!isValidDate(year, mm, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Isikukood contains an invalid date\",\n );\n }\n\n const check = twoPassCheck(v.slice(0, 10));\n if (check !== Number(v[10])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Isikukood check digit does not match\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/**\n * Extract birth date and gender from an Isikukood.\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 g = Number(v[0]);\n const century = centuryMap[g] ?? 1900;\n const yy = Number(v.slice(1, 3));\n const mm = Number(v.slice(3, 5));\n const dd = Number(v.slice(5, 7));\n const year = century + yy;\n\n return {\n birthDate: new Date(year, mm - 1, dd),\n gender: g % 2 === 1 ? \"male\" : \"female\",\n };\n};\n\n/** Generate a random valid Estonian IK. */\nconst generate = (): string => {\n for (;;) {\n const g = String(randomInt(3, 6));\n const yy = String(randomInt(0, 99)).padStart(2, \"0\");\n const mm = String(randomInt(1, 12)).padStart(2, \"0\");\n const dd = String(randomInt(1, 28)).padStart(2, \"0\");\n const s = String(randomInt(0, 999)).padStart(3, \"0\");\n const payload = g + yy + mm + dd + s;\n const c = payload + String(twoPassCheck(payload));\n if (validate(c).valid) return c;\n }\n};\n\n/** Estonian Personal Identification Code. */\nconst ik: CountryValidator<\"EE\", ParsedPersonId> = {\n name: \"Estonian Personal ID\",\n localName: \"Isikukood\",\n abbreviation: \"IK\",\n aliases: [\"isikukood\", \"IK\"] as const,\n candidatePattern: \"[1-6]\\\\d{10}\",\n scope: \"country\",\n country: \"EE\",\n entityType: \"person\",\n sourceUrl:\n \"https://www.riigiteataja.ee/en/eli/512012015003/consolide\",\n examples: [\"36805280109\"] as const,\n compact,\n format,\n parse,\n validate,\n generate,\n};\n\nexport default ik;\nexport { compact, format, parse, validate, generate };\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ValidateResult } from "../types.js";
2
2
 
3
3
  //#region src/ee/registrikood.d.ts
4
4
  declare const compact: (value: string) => string;
@@ -7,7 +7,7 @@ declare const format: (value: string) => string;
7
7
  /** Generate a random valid Estonian Registrikood. */
8
8
  declare const generate: () => string;
9
9
  /** Estonian Company Registration Code. */
10
- declare const registrikood: Validator;
10
+ declare const registrikood: CountryValidator<"EE">;
11
11
  //#endregion
12
12
  export { compact, registrikood as default, format, generate, validate };
13
13
  //# sourceMappingURL=registrikood.d.ts.map
@@ -4,14 +4,6 @@ import { err } from "../_util/result.js";
4
4
  import { isdigits } from "../_util/strings.js";
5
5
  import { twoPassCheck } from "./ik.js";
6
6
  //#region src/ee/registrikood.ts
7
- /**
8
- * Registrikood (Estonian company registration code).
9
- *
10
- * 8 digits. First digit must be 1, 7, 8, or 9.
11
- * Two-pass checksum (same algorithm as EE IK).
12
- *
13
- * @see https://www.rik.ee/
14
- */
15
7
  const VALID_FIRST = new Set([
16
8
  "1",
17
9
  "7",
@@ -49,6 +41,7 @@ const registrikood = {
49
41
  abbreviation: "Registrikood",
50
42
  aliases: ["registrikood"],
51
43
  candidatePattern: "\\d{8}",
44
+ scope: "country",
52
45
  country: "EE",
53
46
  entityType: "company",
54
47
  sourceUrl: "https://www.rik.ee/",
@@ -1 +1 @@
1
- {"version":3,"file":"registrikood.js","names":[],"sources":["../../src/ee/registrikood.ts"],"sourcesContent":["/**\n * Registrikood (Estonian company registration code).\n *\n * 8 digits. First digit must be 1, 7, 8, or 9.\n * Two-pass checksum (same algorithm as EE IK).\n *\n * @see https://www.rik.ee/\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomPick } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\nimport { twoPassCheck } from \"./ik\";\n\nconst VALID_FIRST = new Set([\"1\", \"7\", \"8\", \"9\"]);\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 \"Estonian Registrikood must be 8 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Estonian Registrikood must contain only digits\",\n );\n }\n if (!VALID_FIRST.has(v.charAt(0))) {\n return err(\n \"INVALID_COMPONENT\",\n \"Estonian Registrikood must start with 1, 7, 8, or 9\",\n );\n }\n const check = twoPassCheck(v.slice(0, 7));\n if (check !== Number(v[7])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Estonian Registrikood check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\nconst REGISTRIKOOD_FIRSTS = [1, 7, 8, 9] as const;\n\n/** Generate a random valid Estonian Registrikood. */\nconst generate = (): string => {\n const first = String(randomPick(REGISTRIKOOD_FIRSTS));\n const payload = first + randomDigits(6);\n return payload + String(twoPassCheck(payload));\n};\n\n/** Estonian Company Registration Code. */\nconst registrikood: Validator = {\n name: \"Estonian Company Registration Code\",\n localName: \"Registrikood\",\n abbreviation: \"Registrikood\",\n aliases: [\"registrikood\"] as const,\n candidatePattern: \"\\\\d{8}\",\n country: \"EE\",\n entityType: \"company\",\n sourceUrl: \"https://www.rik.ee/\",\n examples: [\"12345678\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default registrikood;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;AAiBA,MAAM,cAAc,IAAI,IAAI;CAAC;CAAK;CAAK;CAAK;CAAI,CAAC;AAEjD,MAAM,WAAW,UACf,MAAM,OAAO,KAAK;AAEpB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,IACL,kBACA,yCACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,iDACD;AAEH,KAAI,CAAC,YAAY,IAAI,EAAE,OAAO,EAAE,CAAC,CAC/B,QAAO,IACL,qBACA,sDACD;AAGH,KADc,aAAa,EAAE,MAAM,GAAG,EAAE,CAAC,KAC3B,OAAO,EAAE,GAAG,CACxB,QAAO,IACL,oBACA,6CACD;AAEH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B,QAAQ,MAAM;AAExD,MAAM,sBAAsB;CAAC;CAAG;CAAG;CAAG;CAAE;;AAGxC,MAAM,iBAAyB;CAE7B,MAAM,UADQ,OAAO,WAAW,oBAAoB,CAAC,GAC7B,aAAa,EAAE;AACvC,QAAO,UAAU,OAAO,aAAa,QAAQ,CAAC;;;AAIhD,MAAM,eAA0B;CAC9B,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,eAAe;CACzB,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,WAAW;CACtB;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"registrikood.js","names":[],"sources":["../../src/ee/registrikood.ts"],"sourcesContent":["/**\n * Registrikood (Estonian company registration code).\n *\n * 8 digits. First digit must be 1, 7, 8, or 9.\n * Two-pass checksum (same algorithm as EE IK).\n *\n * @see https://www.rik.ee/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\nimport { twoPassCheck } from \"./ik\";\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomPick } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst VALID_FIRST = new Set([\"1\", \"7\", \"8\", \"9\"]);\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 \"Estonian Registrikood must be 8 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Estonian Registrikood must contain only digits\",\n );\n }\n if (!VALID_FIRST.has(v.charAt(0))) {\n return err(\n \"INVALID_COMPONENT\",\n \"Estonian Registrikood must start with 1, 7, 8, or 9\",\n );\n }\n const check = twoPassCheck(v.slice(0, 7));\n if (check !== Number(v[7])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Estonian Registrikood check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\nconst REGISTRIKOOD_FIRSTS = [1, 7, 8, 9] as const;\n\n/** Generate a random valid Estonian Registrikood. */\nconst generate = (): string => {\n const first = String(randomPick(REGISTRIKOOD_FIRSTS));\n const payload = first + randomDigits(6);\n return payload + String(twoPassCheck(payload));\n};\n\n/** Estonian Company Registration Code. */\nconst registrikood: CountryValidator<\"EE\"> = {\n name: \"Estonian Company Registration Code\",\n localName: \"Registrikood\",\n abbreviation: \"Registrikood\",\n aliases: [\"registrikood\"] as const,\n candidatePattern: \"\\\\d{8}\",\n scope: \"country\",\n country: \"EE\",\n entityType: \"company\",\n sourceUrl: \"https://www.rik.ee/\",\n examples: [\"12345678\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default registrikood;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AAoBA,MAAM,cAAc,IAAI,IAAI;CAAC;CAAK;CAAK;CAAK;AAAG,CAAC;AAEhD,MAAM,WAAW,UACf,MAAM,OAAO,IAAI;AAEnB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,GACf,OAAO,IACL,kBACA,wCACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,gDACF;CAEF,IAAI,CAAC,YAAY,IAAI,EAAE,OAAO,CAAC,CAAC,GAC9B,OAAO,IACL,qBACA,qDACF;CAGF,IADc,aAAa,EAAE,MAAM,GAAG,CAAC,CAC/B,MAAM,OAAO,EAAE,EAAE,GACvB,OAAO,IACL,oBACA,4CACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B,QAAQ,KAAK;AAEvD,MAAM,sBAAsB;CAAC;CAAG;CAAG;CAAG;AAAC;;AAGvC,MAAM,iBAAyB;CAE7B,MAAM,UADQ,OAAO,WAAW,mBAAmB,CAC/B,IAAI,aAAa,CAAC;CACtC,OAAO,UAAU,OAAO,aAAa,OAAO,CAAC;AAC/C;;AAGA,MAAM,eAAuC;CAC3C,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,cAAc;CACxB,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,UAAU;CACrB;CACA;CACA;CACA;AACF"}