@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/ni/ruc.js CHANGED
@@ -4,29 +4,6 @@ import { err } from "../_util/result.js";
4
4
  import { isdigits } from "../_util/strings.js";
5
5
  //#region src/ni/ruc.ts
6
6
  /**
7
- * RUC (Registro Único de Contribuyente, Nicaragua
8
- * tax number).
9
- *
10
- * For natural persons the RUC is the cédula de
11
- * identidad: 14 characters structured as
12
- * MMM-DDMMYY-NNNNL where:
13
- * - MMM = municipality code (001–999)
14
- * - DDMMYY = birth date
15
- * - NNNN = sequential number
16
- * - L = check letter (mod 23, ISO 7064)
17
- *
18
- * For legal entities (Personas Jurídicas) the RUC
19
- * starts with "J" followed by 13 digits. No public
20
- * check-digit algorithm is documented for the "J"
21
- * format, so validation is format-only.
22
- *
23
- * The check letter for natural persons uses modulo 23
24
- * with a 23-letter alphabet that excludes I, O, and Z
25
- * to avoid confusion with digits.
26
- *
27
- * @see https://www.dgi.gob.ni/
28
- */
29
- /**
30
7
  * Check letter alphabet (mod 23). Excludes I, O, Z
31
8
  * to prevent transcription errors.
32
9
  */
@@ -96,6 +73,7 @@ const ruc = {
96
73
  abbreviation: "RUC",
97
74
  aliases: ["RUC"],
98
75
  candidatePattern: "[JKME]\\d{13}",
76
+ scope: "country",
99
77
  country: "NI",
100
78
  entityType: "any",
101
79
  description: "Tax identifier issued by Nicaragua's DGI",
@@ -1 +1 @@
1
- {"version":3,"file":"ruc.js","names":[],"sources":["../../src/ni/ruc.ts"],"sourcesContent":["/**\n * RUC (Registro Único de Contribuyente, Nicaragua\n * tax number).\n *\n * For natural persons the RUC is the cédula de\n * identidad: 14 characters structured as\n * MMM-DDMMYY-NNNNL where:\n * - MMM = municipality code (001–999)\n * - DDMMYY = birth date\n * - NNNN = sequential number\n * - L = check letter (mod 23, ISO 7064)\n *\n * For legal entities (Personas Jurídicas) the RUC\n * starts with \"J\" followed by 13 digits. No public\n * check-digit algorithm is documented for the \"J\"\n * format, so validation is format-only.\n *\n * The check letter for natural persons uses modulo 23\n * with a 23-letter alphabet that excludes I, O, and Z\n * to avoid confusion with digits.\n *\n * @see https://www.dgi.gob.ni/\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\n/**\n * Check letter alphabet (mod 23). Excludes I, O, Z\n * to prevent transcription errors.\n */\nconst CHECK_ALPHABET = \"ABCDEFGHJKLMNPQRSTUVWXY\";\n\n/**\n * Compact: strip spaces, hyphens, and uppercase.\n */\nconst compact = (value: string): string =>\n clean(value, \" -\").trim().toUpperCase();\n\n/**\n * Validate a birth date encoded as DDMMYY.\n * Returns true if the date components are plausible.\n */\nconst isValidDate = (ddmmyy: string): boolean => {\n const day = Number(ddmmyy.slice(0, 2));\n const month = Number(ddmmyy.slice(2, 4));\n\n if (month < 1 || month > 12) return false;\n if (day < 1 || day > 31) return false;\n\n return true;\n};\n\n/**\n * Calculate the check letter for a 13-digit body\n * using modulo 23.\n */\nconst calcCheckLetter = (body: string): string => {\n let n = 0n;\n for (const ch of body) {\n n = n * 10n + BigInt(ch);\n }\n const idx = Number(n % 23n);\n // SAFETY: idx is always 0–22 (mod 23), and\n // CHECK_ALPHABET has exactly 23 characters.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return CHECK_ALPHABET[idx]!;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 14) {\n return err(\n \"INVALID_LENGTH\",\n \"Nicaragua RUC must be 14 characters\",\n );\n }\n\n // Legal entity: starts with J + 13 digits\n if (v[0] === \"J\") {\n if (!isdigits(v.slice(1))) {\n return err(\n \"INVALID_FORMAT\",\n \"Nicaragua legal entity RUC must be \" +\n \"J followed by 13 digits\",\n );\n }\n return { valid: true, compact: v };\n }\n\n // Natural person: 13 digits + 1 letter\n const body = v.slice(0, 13);\n // SAFETY: length is validated as exactly 14 above.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const check = v[13]!;\n\n if (!isdigits(body)) {\n return err(\n \"INVALID_FORMAT\",\n \"Nicaragua RUC body must contain only digits\",\n );\n }\n\n if (!CHECK_ALPHABET.includes(check)) {\n return err(\n \"INVALID_FORMAT\",\n \"Nicaragua RUC check letter is invalid\",\n );\n }\n\n // Validate date portion (positions 3–8: DDMMYY)\n const datePart = body.slice(3, 9);\n if (!isValidDate(datePart)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Nicaragua RUC contains an invalid \" + \"birth date\",\n );\n }\n\n // Verify check letter\n const expected = calcCheckLetter(body);\n if (check !== expected) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Nicaragua RUC check letter does not match\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\n/**\n * Format: insert hyphens as MMM-DDMMYY-NNNNL\n * for natural persons. Legal entities are returned\n * in compact form (JNNNNNNNNNNNNN); no documented\n * segmentation exists for the J-prefix format.\n */\nconst format = (value: string): string => {\n const v = compact(value);\n if (v[0] === \"J\") {\n return `J-${v.slice(1)}`;\n }\n return (\n `${v.slice(0, 3)}-${v.slice(3, 9)}` + `-${v.slice(9)}`\n );\n};\n\n/** Generate a random valid Nicaraguan RUC (legal entity). */\nconst generate = (): string => \"J\" + randomDigits(13);\n\n/** Nicaragua tax identification number. */\nconst ruc: Validator = {\n name: \"Tax Identification Number\",\n localName: \"Registro Único de Contribuyente\",\n abbreviation: \"RUC\",\n aliases: [\"RUC\"] as const,\n candidatePattern: \"[JKME]\\\\d{13}\",\n country: \"NI\",\n entityType: \"any\",\n description: \"Tax identifier issued by Nicaragua's DGI\",\n sourceUrl: \"https://www.dgi.gob.ni/\",\n lengths: [14] as const,\n examples: [\"6071904680001F\", \"2811505850012D\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default ruc;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,MAAM,iBAAiB;;;;AAKvB,MAAM,WAAW,UACf,MAAM,OAAO,KAAK,CAAC,MAAM,CAAC,aAAa;;;;;AAMzC,MAAM,eAAe,WAA4B;CAC/C,MAAM,MAAM,OAAO,OAAO,MAAM,GAAG,EAAE,CAAC;CACtC,MAAM,QAAQ,OAAO,OAAO,MAAM,GAAG,EAAE,CAAC;AAExC,KAAI,QAAQ,KAAK,QAAQ,GAAI,QAAO;AACpC,KAAI,MAAM,KAAK,MAAM,GAAI,QAAO;AAEhC,QAAO;;;;;;AAOT,MAAM,mBAAmB,SAAyB;CAChD,IAAI,IAAI;AACR,MAAK,MAAM,MAAM,KACf,KAAI,IAAI,MAAM,OAAO,GAAG;AAM1B,QAAO,eAJK,OAAO,IAAI,IAAI;;AAO7B,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,EAAE,WAAW,GACf,QAAO,IACL,kBACA,sCACD;AAIH,KAAI,EAAE,OAAO,KAAK;AAChB,MAAI,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CACvB,QAAO,IACL,kBACA,6DAED;AAEH,SAAO;GAAE,OAAO;GAAM,SAAS;GAAG;;CAIpC,MAAM,OAAO,EAAE,MAAM,GAAG,GAAG;CAG3B,MAAM,QAAQ,EAAE;AAEhB,KAAI,CAAC,SAAS,KAAK,CACjB,QAAO,IACL,kBACA,8CACD;AAGH,KAAI,CAAC,eAAe,SAAS,MAAM,CACjC,QAAO,IACL,kBACA,wCACD;AAKH,KAAI,CAAC,YADY,KAAK,MAAM,GAAG,EAAE,CACP,CACxB,QAAO,IACL,qBACA,+CACD;AAKH,KAAI,UADa,gBAAgB,KAAK,CAEpC,QAAO,IACL,oBACA,4CACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;;;;;;;AASpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,OAAO,IACX,QAAO,KAAK,EAAE,MAAM,EAAE;AAExB,QACE,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,CAAA,GAAS,EAAE,MAAM,EAAE;;;AAKxD,MAAM,iBAAyB,MAAM,aAAa,GAAG;;AAGrD,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,MAAM;CAChB,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,aAAa;CACb,WAAW;CACX,SAAS,CAAC,GAAG;CACb,UAAU,CAAC,kBAAkB,iBAAiB;CAC9C;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"ruc.js","names":[],"sources":["../../src/ni/ruc.ts"],"sourcesContent":["/**\n * RUC (Registro Único de Contribuyente, Nicaragua\n * tax number).\n *\n * For natural persons the RUC is the cédula de\n * identidad: 14 characters structured as\n * MMM-DDMMYY-NNNNL where:\n * - MMM = municipality code (001–999)\n * - DDMMYY = birth date\n * - NNNN = sequential number\n * - L = check letter (mod 23, ISO 7064)\n *\n * For legal entities (Personas Jurídicas) the RUC\n * starts with \"J\" followed by 13 digits. No public\n * check-digit algorithm is documented for the \"J\"\n * format, so validation is format-only.\n *\n * The check letter for natural persons uses modulo 23\n * with a 23-letter alphabet that excludes I, O, and Z\n * to avoid confusion with digits.\n *\n * @see https://www.dgi.gob.ni/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\n/**\n * Check letter alphabet (mod 23). Excludes I, O, Z\n * to prevent transcription errors.\n */\nconst CHECK_ALPHABET = \"ABCDEFGHJKLMNPQRSTUVWXY\";\n\n/**\n * Compact: strip spaces, hyphens, and uppercase.\n */\nconst compact = (value: string): string =>\n clean(value, \" -\").trim().toUpperCase();\n\n/**\n * Validate a birth date encoded as DDMMYY.\n * Returns true if the date components are plausible.\n */\nconst isValidDate = (ddmmyy: string): boolean => {\n const day = Number(ddmmyy.slice(0, 2));\n const month = Number(ddmmyy.slice(2, 4));\n\n if (month < 1 || month > 12) return false;\n if (day < 1 || day > 31) return false;\n\n return true;\n};\n\n/**\n * Calculate the check letter for a 13-digit body\n * using modulo 23.\n */\nconst calcCheckLetter = (body: string): string => {\n let n = 0n;\n for (const ch of body) {\n n = n * 10n + BigInt(ch);\n }\n const idx = Number(n % 23n);\n // SAFETY: idx is always 0–22 (mod 23), and\n // CHECK_ALPHABET has exactly 23 characters.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return CHECK_ALPHABET[idx]!;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (v.length !== 14) {\n return err(\n \"INVALID_LENGTH\",\n \"Nicaragua RUC must be 14 characters\",\n );\n }\n\n // Legal entity: starts with J + 13 digits\n if (v[0] === \"J\") {\n if (!isdigits(v.slice(1))) {\n return err(\n \"INVALID_FORMAT\",\n \"Nicaragua legal entity RUC must be \" +\n \"J followed by 13 digits\",\n );\n }\n return { valid: true, compact: v };\n }\n\n // Natural person: 13 digits + 1 letter\n const body = v.slice(0, 13);\n // SAFETY: length is validated as exactly 14 above.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const check = v[13]!;\n\n if (!isdigits(body)) {\n return err(\n \"INVALID_FORMAT\",\n \"Nicaragua RUC body must contain only digits\",\n );\n }\n\n if (!CHECK_ALPHABET.includes(check)) {\n return err(\n \"INVALID_FORMAT\",\n \"Nicaragua RUC check letter is invalid\",\n );\n }\n\n // Validate date portion (positions 3–8: DDMMYY)\n const datePart = body.slice(3, 9);\n if (!isValidDate(datePart)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Nicaragua RUC contains an invalid \" + \"birth date\",\n );\n }\n\n // Verify check letter\n const expected = calcCheckLetter(body);\n if (check !== expected) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Nicaragua RUC check letter does not match\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\n/**\n * Format: insert hyphens as MMM-DDMMYY-NNNNL\n * for natural persons. Legal entities are returned\n * in compact form (JNNNNNNNNNNNNN); no documented\n * segmentation exists for the J-prefix format.\n */\nconst format = (value: string): string => {\n const v = compact(value);\n if (v[0] === \"J\") {\n return `J-${v.slice(1)}`;\n }\n return (\n `${v.slice(0, 3)}-${v.slice(3, 9)}` + `-${v.slice(9)}`\n );\n};\n\n/** Generate a random valid Nicaraguan RUC (legal entity). */\nconst generate = (): string => \"J\" + randomDigits(13);\n\n/** Nicaragua tax identification number. */\nconst ruc: CountryValidator<\"NI\"> = {\n name: \"Tax Identification Number\",\n localName: \"Registro Único de Contribuyente\",\n abbreviation: \"RUC\",\n aliases: [\"RUC\"] as const,\n candidatePattern: \"[JKME]\\\\d{13}\",\n scope: \"country\",\n country: \"NI\",\n entityType: \"any\",\n description: \"Tax identifier issued by Nicaragua's DGI\",\n sourceUrl: \"https://www.dgi.gob.ni/\",\n lengths: [14] as const,\n examples: [\"6071904680001F\", \"2811505850012D\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default ruc;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;AAsCA,MAAM,iBAAiB;;;;AAKvB,MAAM,WAAW,UACf,MAAM,OAAO,IAAI,EAAE,KAAK,EAAE,YAAY;;;;;AAMxC,MAAM,eAAe,WAA4B;CAC/C,MAAM,MAAM,OAAO,OAAO,MAAM,GAAG,CAAC,CAAC;CACrC,MAAM,QAAQ,OAAO,OAAO,MAAM,GAAG,CAAC,CAAC;CAEvC,IAAI,QAAQ,KAAK,QAAQ,IAAI,OAAO;CACpC,IAAI,MAAM,KAAK,MAAM,IAAI,OAAO;CAEhC,OAAO;AACT;;;;;AAMA,MAAM,mBAAmB,SAAyB;CAChD,IAAI,IAAI;CACR,KAAK,MAAM,MAAM,MACf,IAAI,IAAI,MAAM,OAAO,EAAE;CAMzB,OAAO,eAJK,OAAO,IAAI,GAIC;AAC1B;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CAEvB,IAAI,EAAE,WAAW,IACf,OAAO,IACL,kBACA,qCACF;CAIF,IAAI,EAAE,OAAO,KAAK;EAChB,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,GACtB,OAAO,IACL,kBACA,4DAEF;EAEF,OAAO;GAAE,OAAO;GAAM,SAAS;EAAE;CACnC;CAGA,MAAM,OAAO,EAAE,MAAM,GAAG,EAAE;CAG1B,MAAM,QAAQ,EAAE;CAEhB,IAAI,CAAC,SAAS,IAAI,GAChB,OAAO,IACL,kBACA,6CACF;CAGF,IAAI,CAAC,eAAe,SAAS,KAAK,GAChC,OAAO,IACL,kBACA,uCACF;CAKF,IAAI,CAAC,YADY,KAAK,MAAM,GAAG,CACP,CAAC,GACvB,OAAO,IACL,qBACA,8CACF;CAKF,IAAI,UADa,gBAAgB,IACZ,GACnB,OAAO,IACL,oBACA,2CACF;CAGF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;;;;;;;AAQA,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,OAAO,KACX,OAAO,KAAK,EAAE,MAAM,CAAC;CAEvB,OACE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAA,GAAU,EAAE,MAAM,CAAC;AAEvD;;AAGA,MAAM,iBAAyB,MAAM,aAAa,EAAE;;AAGpD,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,KAAK;CACf,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,aAAa;CACb,WAAW;CACX,SAAS,CAAC,EAAE;CACZ,UAAU,CAAC,kBAAkB,gBAAgB;CAC7C;CACA;CACA;CACA;AACF"}
package/dist/nl/bsn.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/nl/bsn.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 Dutch BSN. */
8
8
  declare const generate: () => string;
9
9
  /** Dutch Citizen Service Number. */
10
- declare const bsn: Validator;
10
+ declare const bsn: CountryValidator<"NL">;
11
11
  //#endregion
12
12
  export { compact, bsn as default, format, generate, validate };
13
13
  //# sourceMappingURL=bsn.d.ts.map
package/dist/nl/bsn.js CHANGED
@@ -1,18 +1,9 @@
1
+ import { weightedSum } from "../_checksums/weighted-sum.js";
1
2
  import { clean } from "../_util/clean.js";
2
3
  import { randomDigits } from "../_util/generate.js";
3
4
  import { err } from "../_util/result.js";
4
5
  import { isdigits } from "../_util/strings.js";
5
- import { weightedSum } from "../_checksums/weighted-sum.js";
6
6
  //#region src/nl/bsn.ts
7
- /**
8
- * BSN (Burgerservicenummer).
9
- *
10
- * Dutch citizen service number. 9 digits (zero-padded)
11
- * with a weighted checksum where the last digit has
12
- * weight -1.
13
- *
14
- * @see https://www.government.nl/topics/personal-data/citizen-service-number-bsn
15
- */
16
7
  const WEIGHTS = [
17
8
  9,
18
9
  8,
@@ -55,6 +46,7 @@ const bsn = {
55
46
  "sofinummer"
56
47
  ],
57
48
  candidatePattern: "\\d{9}",
49
+ scope: "country",
58
50
  country: "NL",
59
51
  entityType: "person",
60
52
  sourceUrl: "https://www.government.nl/topics/personal-data/citizen-service-number-bsn",
@@ -1 +1 @@
1
- {"version":3,"file":"bsn.js","names":[],"sources":["../../src/nl/bsn.ts"],"sourcesContent":["/**\n * BSN (Burgerservicenummer).\n *\n * Dutch citizen service number. 9 digits (zero-padded)\n * with a weighted checksum where the last digit has\n * weight -1.\n *\n * @see https://www.government.nl/topics/personal-data/citizen-service-number-bsn\n */\n\nimport { weightedSum } from \"#checksums/weighted-sum\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst WEIGHTS = [9, 8, 7, 6, 5, 4, 3, 2, -1] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -.\").padStart(9, \"0\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"BSN must be exactly 9 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"BSN must contain only digits\",\n );\n }\n\n if (Number(v) === 0) {\n return err(\"INVALID_FORMAT\", \"BSN cannot be all zeros\");\n }\n\n const sum = weightedSum(v, WEIGHTS, 11);\n if (sum !== 0) {\n return err(\n \"INVALID_CHECKSUM\",\n \"BSN check does not match\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid Dutch BSN. */\nconst generate = (): string => {\n for (;;) {\n const c = randomDigits(9);\n if (validate(c).valid) return c;\n }\n};\n\n/** Dutch Citizen Service Number. */\nconst bsn: Validator = {\n name: \"Dutch Citizen Service Number\",\n localName: \"Burgerservicenummer\",\n abbreviation: \"BSN\",\n aliases: [\n \"burgerservicenummer\",\n \"BSN\",\n \"sofinummer\",\n ] as const,\n candidatePattern: \"\\\\d{9}\",\n country: \"NL\",\n entityType: \"person\",\n sourceUrl:\n \"https://www.government.nl/topics/personal-data/citizen-service-number-bsn\",\n examples: [\"111222333\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default bsn;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAE5C,MAAM,WAAW,UACf,MAAM,OAAO,MAAM,CAAC,SAAS,GAAG,IAAI;AAEtC,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,IACL,kBACA,+BACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,+BACD;AAGH,KAAI,OAAO,EAAE,KAAK,EAChB,QAAO,IAAI,kBAAkB,0BAA0B;AAIzD,KADY,YAAY,GAAG,SAAS,GAAG,KAC3B,EACV,QAAO,IACL,oBACA,2BACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B,QAAQ,MAAM;;AAGxD,MAAM,iBAAyB;AAC7B,UAAS;EACP,MAAM,IAAI,aAAa,EAAE;AACzB,MAAI,SAAS,EAAE,CAAC,MAAO,QAAO;;;;AAKlC,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;EACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WACE;CACF,UAAU,CAAC,YAAY;CACvB;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"bsn.js","names":[],"sources":["../../src/nl/bsn.ts"],"sourcesContent":["/**\n * BSN (Burgerservicenummer).\n *\n * Dutch citizen service number. 9 digits (zero-padded)\n * with a weighted checksum where the last digit has\n * weight -1.\n *\n * @see https://www.government.nl/topics/personal-data/citizen-service-number-bsn\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { weightedSum } from \"#checksums/weighted-sum\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst WEIGHTS = [9, 8, 7, 6, 5, 4, 3, 2, -1] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -.\").padStart(9, \"0\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"BSN must be exactly 9 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"BSN must contain only digits\",\n );\n }\n\n if (Number(v) === 0) {\n return err(\"INVALID_FORMAT\", \"BSN cannot be all zeros\");\n }\n\n const sum = weightedSum(v, WEIGHTS, 11);\n if (sum !== 0) {\n return err(\n \"INVALID_CHECKSUM\",\n \"BSN check does not match\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid Dutch BSN. */\nconst generate = (): string => {\n for (;;) {\n const c = randomDigits(9);\n if (validate(c).valid) return c;\n }\n};\n\n/** Dutch Citizen Service Number. */\nconst bsn: CountryValidator<\"NL\"> = {\n name: \"Dutch Citizen Service Number\",\n localName: \"Burgerservicenummer\",\n abbreviation: \"BSN\",\n aliases: [\n \"burgerservicenummer\",\n \"BSN\",\n \"sofinummer\",\n ] as const,\n candidatePattern: \"\\\\d{9}\",\n scope: \"country\",\n country: \"NL\",\n entityType: \"person\",\n sourceUrl:\n \"https://www.government.nl/topics/personal-data/citizen-service-number-bsn\",\n examples: [\"111222333\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default bsn;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AAqBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAAE;AAE3C,MAAM,WAAW,UACf,MAAM,OAAO,KAAK,EAAE,SAAS,GAAG,GAAG;AAErC,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,GACf,OAAO,IACL,kBACA,8BACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,8BACF;CAGF,IAAI,OAAO,CAAC,MAAM,GAChB,OAAO,IAAI,kBAAkB,yBAAyB;CAIxD,IADY,YAAY,GAAG,SAAS,EAC9B,MAAM,GACV,OAAO,IACL,oBACA,0BACF;CAGF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B,QAAQ,KAAK;;AAGvD,MAAM,iBAAyB;CAC7B,SAAS;EACP,MAAM,IAAI,aAAa,CAAC;EACxB,IAAI,SAAS,CAAC,EAAE,OAAO,OAAO;CAChC;AACF;;AAGA,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;CACF;CACA,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WACE;CACF,UAAU,CAAC,WAAW;CACtB;CACA;CACA;CACA;AACF"}
package/dist/nl/kvk.d.ts CHANGED
@@ -1,13 +1,20 @@
1
- import { ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ValidateResult } from "../types.js";
2
2
 
3
3
  //#region src/nl/kvk.d.ts
4
4
  /** Generate a random valid Dutch KvK number. */
5
5
  declare const generate: () => string;
6
+ /**
7
+ * KvK-nummer (Dutch Chamber of Commerce number).
8
+ *
9
+ * 8 digits. Format-only validation; no checksum.
10
+ *
11
+ * @see https://www.kvk.nl/
12
+ */
6
13
  declare const compact: (value: string) => string;
7
14
  declare const validate: (value: string) => ValidateResult;
8
15
  declare const format: (value: string) => string;
9
16
  /** Dutch Chamber of Commerce Number. */
10
- declare const kvk: Validator;
17
+ declare const kvk: CountryValidator<"NL">;
11
18
  //#endregion
12
19
  export { compact, kvk as default, format, generate, validate };
13
20
  //# sourceMappingURL=kvk.d.ts.map
package/dist/nl/kvk.js CHANGED
@@ -3,13 +3,6 @@ import { randomDigits } from "../_util/generate.js";
3
3
  import { err } from "../_util/result.js";
4
4
  import { isdigits } from "../_util/strings.js";
5
5
  //#region src/nl/kvk.ts
6
- /**
7
- * KvK-nummer (Dutch Chamber of Commerce number).
8
- *
9
- * 8 digits. Format-only validation; no checksum.
10
- *
11
- * @see https://www.kvk.nl/
12
- */
13
6
  /** Generate a random valid Dutch KvK number. */
14
7
  const generate = () => randomDigits(8);
15
8
  const compact = (value) => clean(value, " -/.");
@@ -30,6 +23,7 @@ const kvk = {
30
23
  abbreviation: "KvK",
31
24
  aliases: ["KVK-nummer", "Kamer van Koophandel"],
32
25
  candidatePattern: "\\d{8}",
26
+ scope: "country",
33
27
  country: "NL",
34
28
  entityType: "company",
35
29
  sourceUrl: "https://www.kvk.nl/",
@@ -1 +1 @@
1
- {"version":3,"file":"kvk.js","names":[],"sources":["../../src/nl/kvk.ts"],"sourcesContent":["/** Generate a random valid Dutch KvK number. */\nconst generate = (): string => randomDigits(8);\n\n/**\n * KvK-nummer (Dutch Chamber of Commerce number).\n *\n * 8 digits. Format-only validation; no checksum.\n *\n * @see https://www.kvk.nl/\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst 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 \"Dutch KvK number must be 8 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Dutch KvK number must contain only digits\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Dutch Chamber of Commerce Number. */\nconst kvk: Validator = {\n name: \"Dutch Chamber of Commerce Number\",\n localName: \"KvK-nummer\",\n abbreviation: \"KvK\",\n aliases: [\"KVK-nummer\", \"Kamer van Koophandel\"] as const,\n candidatePattern: \"\\\\d{8}\",\n country: \"NL\",\n entityType: \"company\",\n sourceUrl: \"https://www.kvk.nl/\",\n examples: [\"12345678\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default kvk;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;AACA,MAAM,iBAAyB,aAAa,EAAE;AAiB9C,MAAM,WAAW,UACf,MAAM,OAAO,OAAO;AAEtB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,IACL,kBACA,oCACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,4CACD;AAEH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B,QAAQ,MAAM;;AAGxD,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,cAAc,uBAAuB;CAC/C,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,WAAW;CACtB;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"kvk.js","names":[],"sources":["../../src/nl/kvk.ts"],"sourcesContent":["/** Generate a random valid Dutch KvK number. */\nconst generate = (): string => randomDigits(8);\n\n/**\n * KvK-nummer (Dutch Chamber of Commerce number).\n *\n * 8 digits. Format-only validation; no checksum.\n *\n * @see https://www.kvk.nl/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst 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 \"Dutch KvK number must be 8 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Dutch KvK number must contain only digits\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Dutch Chamber of Commerce Number. */\nconst kvk: CountryValidator<\"NL\"> = {\n name: \"Dutch Chamber of Commerce Number\",\n localName: \"KvK-nummer\",\n abbreviation: \"KvK\",\n aliases: [\"KVK-nummer\", \"Kamer van Koophandel\"] as const,\n candidatePattern: \"\\\\d{8}\",\n scope: \"country\",\n country: \"NL\",\n entityType: \"company\",\n sourceUrl: \"https://www.kvk.nl/\",\n examples: [\"12345678\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default kvk;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AACA,MAAM,iBAAyB,aAAa,CAAC;AAoB7C,MAAM,WAAW,UACf,MAAM,OAAO,MAAM;AAErB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,GACf,OAAO,IACL,kBACA,mCACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,2CACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B,QAAQ,KAAK;;AAGvD,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,cAAc,sBAAsB;CAC9C,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,UAAU;CACrB;CACA;CACA;CACA;AACF"}
package/dist/nl/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/nl/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 Dutch VAT number. */
8
8
  declare const generate: () => string;
9
9
  /** Dutch VAT Number. */
10
- declare const vat: Validator;
10
+ declare const vat: CountryValidator<"NL">;
11
11
  //#endregion
12
12
  export { compact, vat as default, format, generate, validate };
13
13
  //# sourceMappingURL=vat.d.ts.map
package/dist/nl/vat.js CHANGED
@@ -3,19 +3,6 @@ import { randomDigits } from "../_util/generate.js";
3
3
  import { err } from "../_util/result.js";
4
4
  import { isdigits } from "../_util/strings.js";
5
5
  //#region src/nl/vat.ts
6
- /**
7
- * BTW (Dutch VAT number).
8
- *
9
- * 12 characters: 9 digits + "B" + 2 digits.
10
- *
11
- * The current Dutch VAT identification number
12
- * (btw-id) format is structural: `NL` + 9 digits
13
- * + `B` + 2 digits. The official guidance explicitly
14
- * states that the 9 digits are not derived from BSN
15
- * and the final 2 digits are random.
16
- *
17
- * @see https://business.gov.nl/regulations/using-checking-vat-numbers/
18
- */
19
6
  const compact = (value) => {
20
7
  let v = clean(value, " -/.");
21
8
  if (v.startsWith("NL") || v.startsWith("nl")) v = v.slice(2);
@@ -45,6 +32,7 @@ const vat = {
45
32
  abbreviation: "BTW",
46
33
  aliases: ["BTW-nummer", "BTW-id"],
47
34
  candidatePattern: "NL\\d{9}B\\d{2}",
35
+ scope: "country",
48
36
  country: "NL",
49
37
  entityType: "company",
50
38
  sourceUrl: "https://business.gov.nl/regulations/using-checking-vat-numbers/",
@@ -1 +1 @@
1
- {"version":3,"file":"vat.js","names":[],"sources":["../../src/nl/vat.ts"],"sourcesContent":["/**\n * BTW (Dutch VAT number).\n *\n * 12 characters: 9 digits + \"B\" + 2 digits.\n *\n * The current Dutch VAT identification number\n * (btw-id) format is structural: `NL` + 9 digits\n * + `B` + 2 digits. The official guidance explicitly\n * states that the 9 digits are not derived from BSN\n * and the final 2 digits are random.\n *\n * @see https://business.gov.nl/regulations/using-checking-vat-numbers/\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -/.\");\n if (v.startsWith(\"NL\") || v.startsWith(\"nl\")) {\n v = v.slice(2);\n }\n v = v.toUpperCase();\n // Zero-pad numeric part to 9 digits if B is found\n const bIdx = v.indexOf(\"B\");\n if (bIdx > 0 && bIdx < 9) {\n v = v.slice(0, bIdx).padStart(9, \"0\") + v.slice(bIdx);\n }\n return v;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 12) {\n return err(\n \"INVALID_LENGTH\",\n \"Dutch VAT number must be 12 characters\",\n );\n }\n if (!isdigits(v.slice(0, 9))) {\n return err(\n \"INVALID_FORMAT\",\n \"Dutch VAT number must start with 9 digits\",\n );\n }\n if (v[9] !== \"B\") {\n return err(\n \"INVALID_COMPONENT\",\n \"Dutch VAT number digit 10 must be B\",\n );\n }\n if (!isdigits(v.slice(10, 12))) {\n return err(\n \"INVALID_FORMAT\",\n \"Dutch VAT number must end with 2 digits\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string =>\n `NL${compact(value)}`;\n\n/** Generate a random valid Dutch VAT number. */\nconst generate = (): string =>\n `${randomDigits(9)}B${randomDigits(2)}`;\n\n/** Dutch VAT Number. */\nconst vat: Validator = {\n name: \"Dutch VAT Number\",\n localName: \"BTW-identificatienummer\",\n abbreviation: \"BTW\",\n aliases: [\"BTW-nummer\", \"BTW-id\"] as const,\n candidatePattern: \"NL\\\\d{9}B\\\\d{2}\",\n country: \"NL\",\n entityType: \"company\",\n sourceUrl:\n \"https://business.gov.nl/regulations/using-checking-vat-numbers/\",\n examples: [\"000099998B57\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default vat;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,MAAM,WAAW,UAA0B;CACzC,IAAI,IAAI,MAAM,OAAO,OAAO;AAC5B,KAAI,EAAE,WAAW,KAAK,IAAI,EAAE,WAAW,KAAK,CAC1C,KAAI,EAAE,MAAM,EAAE;AAEhB,KAAI,EAAE,aAAa;CAEnB,MAAM,OAAO,EAAE,QAAQ,IAAI;AAC3B,KAAI,OAAO,KAAK,OAAO,EACrB,KAAI,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,GAAG,IAAI,GAAG,EAAE,MAAM,KAAK;AAEvD,QAAO;;AAGT,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,GACf,QAAO,IACL,kBACA,yCACD;AAEH,KAAI,CAAC,SAAS,EAAE,MAAM,GAAG,EAAE,CAAC,CAC1B,QAAO,IACL,kBACA,4CACD;AAEH,KAAI,EAAE,OAAO,IACX,QAAO,IACL,qBACA,sCACD;AAEH,KAAI,CAAC,SAAS,EAAE,MAAM,IAAI,GAAG,CAAC,CAC5B,QAAO,IACL,kBACA,0CACD;AAEH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UACd,KAAK,QAAQ,MAAM;;AAGrB,MAAM,iBACJ,GAAG,aAAa,EAAE,CAAC,GAAG,aAAa,EAAE;;AAGvC,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,cAAc,SAAS;CACjC,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WACE;CACF,UAAU,CAAC,eAAe;CAC1B;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"vat.js","names":[],"sources":["../../src/nl/vat.ts"],"sourcesContent":["/**\n * BTW (Dutch VAT number).\n *\n * 12 characters: 9 digits + \"B\" + 2 digits.\n *\n * The current Dutch VAT identification number\n * (btw-id) format is structural: `NL` + 9 digits\n * + `B` + 2 digits. The official guidance explicitly\n * states that the 9 digits are not derived from BSN\n * and the final 2 digits are random.\n *\n * @see https://business.gov.nl/regulations/using-checking-vat-numbers/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -/.\");\n if (v.startsWith(\"NL\") || v.startsWith(\"nl\")) {\n v = v.slice(2);\n }\n v = v.toUpperCase();\n // Zero-pad numeric part to 9 digits if B is found\n const bIdx = v.indexOf(\"B\");\n if (bIdx > 0 && bIdx < 9) {\n v = v.slice(0, bIdx).padStart(9, \"0\") + v.slice(bIdx);\n }\n return v;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 12) {\n return err(\n \"INVALID_LENGTH\",\n \"Dutch VAT number must be 12 characters\",\n );\n }\n if (!isdigits(v.slice(0, 9))) {\n return err(\n \"INVALID_FORMAT\",\n \"Dutch VAT number must start with 9 digits\",\n );\n }\n if (v[9] !== \"B\") {\n return err(\n \"INVALID_COMPONENT\",\n \"Dutch VAT number digit 10 must be B\",\n );\n }\n if (!isdigits(v.slice(10, 12))) {\n return err(\n \"INVALID_FORMAT\",\n \"Dutch VAT number must end with 2 digits\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string =>\n `NL${compact(value)}`;\n\n/** Generate a random valid Dutch VAT number. */\nconst generate = (): string =>\n `${randomDigits(9)}B${randomDigits(2)}`;\n\n/** Dutch VAT Number. */\nconst vat: CountryValidator<\"NL\"> = {\n name: \"Dutch VAT Number\",\n localName: \"BTW-identificatienummer\",\n abbreviation: \"BTW\",\n aliases: [\"BTW-nummer\", \"BTW-id\"] as const,\n candidatePattern: \"NL\\\\d{9}B\\\\d{2}\",\n scope: \"country\",\n country: \"NL\",\n entityType: \"company\",\n sourceUrl:\n \"https://business.gov.nl/regulations/using-checking-vat-numbers/\",\n examples: [\"000099998B57\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default vat;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;AAwBA,MAAM,WAAW,UAA0B;CACzC,IAAI,IAAI,MAAM,OAAO,MAAM;CAC3B,IAAI,EAAE,WAAW,IAAI,KAAK,EAAE,WAAW,IAAI,GACzC,IAAI,EAAE,MAAM,CAAC;CAEf,IAAI,EAAE,YAAY;CAElB,MAAM,OAAO,EAAE,QAAQ,GAAG;CAC1B,IAAI,OAAO,KAAK,OAAO,GACrB,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,GAAG,GAAG,IAAI,EAAE,MAAM,IAAI;CAEtD,OAAO;AACT;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,IACf,OAAO,IACL,kBACA,wCACF;CAEF,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,CAAC,CAAC,GACzB,OAAO,IACL,kBACA,2CACF;CAEF,IAAI,EAAE,OAAO,KACX,OAAO,IACL,qBACA,qCACF;CAEF,IAAI,CAAC,SAAS,EAAE,MAAM,IAAI,EAAE,CAAC,GAC3B,OAAO,IACL,kBACA,yCACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UACd,KAAK,QAAQ,KAAK;;AAGpB,MAAM,iBACJ,GAAG,aAAa,CAAC,EAAE,GAAG,aAAa,CAAC;;AAGtC,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,cAAc,QAAQ;CAChC,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WACE;CACF,UAAU,CAAC,cAAc;CACzB;CACA;CACA;CACA;AACF"}
@@ -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/no/fodselsnummer.d.ts
4
4
  declare const compact: (value: string) => string;
@@ -13,7 +13,7 @@ declare const parse: (value: string) => ParsedPersonId | null;
13
13
  /** Generate a random valid Norwegian birth number. */
14
14
  declare const generate: () => string;
15
15
  /** Norwegian Birth Number. */
16
- declare const fodselsnummer: Validator<ParsedPersonId>;
16
+ declare const fodselsnummer: CountryValidator<"NO", ParsedPersonId>;
17
17
  //#endregion
18
18
  export { compact, fodselsnummer as default, format, generate, parse, validate };
19
19
  //# sourceMappingURL=fodselsnummer.d.ts.map
@@ -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/no/fodselsnummer.ts
7
- /**
8
- * Fødselsnummer (Norwegian birth number).
9
- *
10
- * 11 digits: DDMMYY + 3-digit individual number + 2
11
- * check digits. Supports D-numbers (day + 40) and
12
- * H-numbers (month + 40).
13
- *
14
- * @see https://www.skatteetaten.no/
15
- */
16
7
  const WEIGHTS_D1 = [
17
8
  3,
18
9
  7,
@@ -119,6 +110,7 @@ const fodselsnummer = {
119
110
  abbreviation: "Fødselsnr",
120
111
  aliases: ["fødselsnummer", "personnummer"],
121
112
  candidatePattern: "\\d{11}",
113
+ scope: "country",
122
114
  country: "NO",
123
115
  entityType: "person",
124
116
  sourceUrl: "https://www.skatteetaten.no/",
@@ -1 +1 @@
1
- {"version":3,"file":"fodselsnummer.js","names":[],"sources":["../../src/no/fodselsnummer.ts"],"sourcesContent":["/**\n * Fødselsnummer (Norwegian birth number).\n *\n * 11 digits: DDMMYY + 3-digit individual number + 2\n * check digits. Supports D-numbers (day + 40) and\n * H-numbers (month + 40).\n *\n * @see https://www.skatteetaten.no/\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 WEIGHTS_D1 = [3, 7, 6, 1, 8, 9, 4, 5, 2] as const;\nconst WEIGHTS_D2 = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst getCentury = (\n yy: number,\n individual: number,\n): number | undefined => {\n if (individual >= 0 && individual <= 499) return 1900;\n if (individual >= 500 && individual <= 749 && yy >= 54) {\n return 1800;\n }\n if (individual >= 500 && individual <= 999 && yy < 40) {\n return 2000;\n }\n if (individual >= 900 && individual <= 999 && yy >= 40) {\n return 1900;\n }\n return undefined;\n};\n\nconst checkDigit = (\n v: string,\n weights: readonly number[],\n): number | undefined => {\n let sum = 0;\n for (let i = 0; i < weights.length; i++) {\n sum += Number(v.charAt(i)) * (weights[i] ?? 0);\n }\n const remainder = (11 - (sum % 11)) % 11;\n if (remainder === 10) return undefined;\n return 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 \"Norwegian birth number must be 11 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Norwegian birth number must contain only digits\",\n );\n }\n\n // Check digits\n const d1 = checkDigit(v, WEIGHTS_D1);\n if (d1 === undefined || d1 !== Number(v[9])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Norwegian birth number check digit 1 mismatch\",\n );\n }\n const d2 = checkDigit(v, WEIGHTS_D2);\n if (d2 === undefined || d2 !== Number(v[10])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Norwegian birth number check digit 2 mismatch\",\n );\n }\n\n // Parse date components\n let dd = Number(v.slice(0, 2));\n let mm = Number(v.slice(2, 4));\n const yy = Number(v.slice(4, 6));\n const individual = Number(v.slice(6, 9));\n\n // D-number: day > 40\n if (dd > 40) dd -= 40;\n // H-number: month > 40\n if (mm > 40) mm -= 40;\n\n const century = getCentury(yy, individual);\n if (century === undefined) {\n return err(\n \"INVALID_COMPONENT\",\n \"Norwegian birth number has invalid individual/century combination\",\n );\n }\n\n const year = century + yy;\n if (!isValidDate(year, mm, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Norwegian birth number 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 \"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 Norwegian\n * birth number. Returns null if the value is not\n * 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 let dd = Number(v.slice(0, 2));\n let mm = Number(v.slice(2, 4));\n const yy = Number(v.slice(4, 6));\n const individual = Number(v.slice(6, 9));\n\n if (dd > 40) dd -= 40;\n if (mm > 40) mm -= 40;\n\n const century = getCentury(yy, individual);\n if (century === undefined) return null;\n\n const year = century + yy;\n\n return {\n birthDate: new Date(year, mm - 1, dd),\n gender: individual % 2 === 0 ? \"female\" : \"male\",\n };\n};\n\n/** Generate a random valid Norwegian birth number. */\nconst generate = (): string => {\n for (;;) {\n const dd = String(randomInt(1, 28)).padStart(2, \"0\");\n const mm = String(randomInt(1, 12)).padStart(2, \"0\");\n const yy = String(randomInt(50, 99)).padStart(2, \"0\");\n const ind = String(randomInt(0, 499)).padStart(3, \"0\");\n const c = dd + mm + yy + ind + randomDigits(2);\n if (validate(c).valid) return c;\n }\n};\n\n/** Norwegian Birth Number. */\nconst fodselsnummer: Validator<ParsedPersonId> = {\n name: \"Norwegian Birth Number\",\n localName: \"Fødselsnummer\",\n abbreviation: \"Fødselsnr\",\n aliases: [\"fødselsnummer\", \"personnummer\"] as const,\n candidatePattern: \"\\\\d{11}\",\n country: \"NO\",\n entityType: \"person\",\n sourceUrl: \"https://www.skatteetaten.no/\",\n examples: [\"15108695088\"] as const,\n compact,\n format,\n parse,\n validate,\n generate,\n};\n\nexport default fodselsnummer;\nexport { compact, format, parse, validate, generate };\n"],"mappings":"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"}
1
+ {"version":3,"file":"fodselsnummer.js","names":[],"sources":["../../src/no/fodselsnummer.ts"],"sourcesContent":["/**\n * Fødselsnummer (Norwegian birth number).\n *\n * 11 digits: DDMMYY + 3-digit individual number + 2\n * check digits. Supports D-numbers (day + 40) and\n * H-numbers (month + 40).\n *\n * @see https://www.skatteetaten.no/\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 WEIGHTS_D1 = [3, 7, 6, 1, 8, 9, 4, 5, 2] as const;\nconst WEIGHTS_D2 = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst getCentury = (\n yy: number,\n individual: number,\n): number | undefined => {\n if (individual >= 0 && individual <= 499) return 1900;\n if (individual >= 500 && individual <= 749 && yy >= 54) {\n return 1800;\n }\n if (individual >= 500 && individual <= 999 && yy < 40) {\n return 2000;\n }\n if (individual >= 900 && individual <= 999 && yy >= 40) {\n return 1900;\n }\n return undefined;\n};\n\nconst checkDigit = (\n v: string,\n weights: readonly number[],\n): number | undefined => {\n let sum = 0;\n for (let i = 0; i < weights.length; i++) {\n sum += Number(v.charAt(i)) * (weights[i] ?? 0);\n }\n const remainder = (11 - (sum % 11)) % 11;\n if (remainder === 10) return undefined;\n return 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 \"Norwegian birth number must be 11 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Norwegian birth number must contain only digits\",\n );\n }\n\n // Check digits\n const d1 = checkDigit(v, WEIGHTS_D1);\n if (d1 === undefined || d1 !== Number(v[9])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Norwegian birth number check digit 1 mismatch\",\n );\n }\n const d2 = checkDigit(v, WEIGHTS_D2);\n if (d2 === undefined || d2 !== Number(v[10])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Norwegian birth number check digit 2 mismatch\",\n );\n }\n\n // Parse date components\n let dd = Number(v.slice(0, 2));\n let mm = Number(v.slice(2, 4));\n const yy = Number(v.slice(4, 6));\n const individual = Number(v.slice(6, 9));\n\n // D-number: day > 40\n if (dd > 40) dd -= 40;\n // H-number: month > 40\n if (mm > 40) mm -= 40;\n\n const century = getCentury(yy, individual);\n if (century === undefined) {\n return err(\n \"INVALID_COMPONENT\",\n \"Norwegian birth number has invalid individual/century combination\",\n );\n }\n\n const year = century + yy;\n if (!isValidDate(year, mm, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Norwegian birth number 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 \"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 Norwegian\n * birth number. Returns null if the value is not\n * 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 let dd = Number(v.slice(0, 2));\n let mm = Number(v.slice(2, 4));\n const yy = Number(v.slice(4, 6));\n const individual = Number(v.slice(6, 9));\n\n if (dd > 40) dd -= 40;\n if (mm > 40) mm -= 40;\n\n const century = getCentury(yy, individual);\n if (century === undefined) return null;\n\n const year = century + yy;\n\n return {\n birthDate: new Date(year, mm - 1, dd),\n gender: individual % 2 === 0 ? \"female\" : \"male\",\n };\n};\n\n/** Generate a random valid Norwegian birth number. */\nconst generate = (): string => {\n for (;;) {\n const dd = String(randomInt(1, 28)).padStart(2, \"0\");\n const mm = String(randomInt(1, 12)).padStart(2, \"0\");\n const yy = String(randomInt(50, 99)).padStart(2, \"0\");\n const ind = String(randomInt(0, 499)).padStart(3, \"0\");\n const c = dd + mm + yy + ind + randomDigits(2);\n if (validate(c).valid) return c;\n }\n};\n\n/** Norwegian Birth Number. */\nconst fodselsnummer: CountryValidator<\n \"NO\",\n ParsedPersonId\n> = {\n name: \"Norwegian Birth Number\",\n localName: \"Fødselsnummer\",\n abbreviation: \"Fødselsnr\",\n aliases: [\"fødselsnummer\", \"personnummer\"] as const,\n candidatePattern: \"\\\\d{11}\",\n scope: \"country\",\n country: \"NO\",\n entityType: \"person\",\n sourceUrl: \"https://www.skatteetaten.no/\",\n examples: [\"15108695088\"] as const,\n compact,\n format,\n parse,\n validate,\n generate,\n};\n\nexport default fodselsnummer;\nexport { compact, format, parse, validate, generate };\n"],"mappings":";;;;;;AAsBA,MAAM,aAAa;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAAC;AAC7C,MAAM,aAAa;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAAC;AAEhD,MAAM,WAAW,UACf,MAAM,OAAO,IAAI;AAEnB,MAAM,cACJ,IACA,eACuB;CACvB,IAAI,cAAc,KAAK,cAAc,KAAK,OAAO;CACjD,IAAI,cAAc,OAAO,cAAc,OAAO,MAAM,IAClD,OAAO;CAET,IAAI,cAAc,OAAO,cAAc,OAAO,KAAK,IACjD,OAAO;CAET,IAAI,cAAc,OAAO,cAAc,OAAO,MAAM,IAClD,OAAO;AAGX;AAEA,MAAM,cACJ,GACA,YACuB;CACvB,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAClC,OAAO,OAAO,EAAE,OAAO,CAAC,CAAC,KAAK,QAAQ,MAAM;CAE9C,MAAM,aAAa,KAAM,MAAM,MAAO;CACtC,IAAI,cAAc,IAAI,OAAO,KAAA;CAC7B,OAAO;AACT;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,IACf,OAAO,IACL,kBACA,0CACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,iDACF;CAIF,MAAM,KAAK,WAAW,GAAG,UAAU;CACnC,IAAI,OAAO,KAAA,KAAa,OAAO,OAAO,EAAE,EAAE,GACxC,OAAO,IACL,oBACA,+CACF;CAEF,MAAM,KAAK,WAAW,GAAG,UAAU;CACnC,IAAI,OAAO,KAAA,KAAa,OAAO,OAAO,EAAE,GAAG,GACzC,OAAO,IACL,oBACA,+CACF;CAIF,IAAI,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC7B,IAAI,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC7B,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC/B,MAAM,aAAa,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAGvC,IAAI,KAAK,IAAI,MAAM;CAEnB,IAAI,KAAK,IAAI,MAAM;CAEnB,MAAM,UAAU,WAAW,IAAI,UAAU;CACzC,IAAI,YAAY,KAAA,GACd,OAAO,IACL,qBACA,mEACF;CAGF,MAAM,OAAO,UAAU;CACvB,IAAI,CAAC,YAAY,MAAM,IAAI,EAAE,GAC3B,OAAO,IACL,qBACA,iDACF;CAIF,IAAI,IAAI,KAAK,MAAM,KAAK,GAAG,EAAE,oBAAI,IAAI,KAAK,GACxC,OAAO,IACL,qBACA,6BACF;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;;;;;;AAOA,MAAM,SAAS,UAAyC;CACtD,MAAM,SAAS,SAAS,KAAK;CAC7B,IAAI,CAAC,OAAO,OAAO,OAAO;CAE1B,MAAM,IAAI,OAAO;CACjB,IAAI,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC7B,IAAI,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC7B,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC/B,MAAM,aAAa,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAEvC,IAAI,KAAK,IAAI,MAAM;CACnB,IAAI,KAAK,IAAI,MAAM;CAEnB,MAAM,UAAU,WAAW,IAAI,UAAU;CACzC,IAAI,YAAY,KAAA,GAAW,OAAO;CAElC,MAAM,OAAO,UAAU;CAEvB,OAAO;EACL,WAAW,IAAI,KAAK,MAAM,KAAK,GAAG,EAAE;EACpC,QAAQ,aAAa,MAAM,IAAI,WAAW;CAC5C;AACF;;AAGA,MAAM,iBAAyB;CAC7B,SAAS;EACP,MAAM,KAAK,OAAO,UAAU,GAAG,EAAE,CAAC,EAAE,SAAS,GAAG,GAAG;EACnD,MAAM,KAAK,OAAO,UAAU,GAAG,EAAE,CAAC,EAAE,SAAS,GAAG,GAAG;EACnD,MAAM,KAAK,OAAO,UAAU,IAAI,EAAE,CAAC,EAAE,SAAS,GAAG,GAAG;EACpD,MAAM,MAAM,OAAO,UAAU,GAAG,GAAG,CAAC,EAAE,SAAS,GAAG,GAAG;EACrD,MAAM,IAAI,KAAK,KAAK,KAAK,MAAM,aAAa,CAAC;EAC7C,IAAI,SAAS,CAAC,EAAE,OAAO,OAAO;CAChC;AACF;;AAGA,MAAM,gBAGF;CACF,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,iBAAiB,cAAc;CACzC,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,aAAa;CACxB;CACA;CACA;CACA;CACA;AACF"}
package/dist/no/mva.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/no/mva.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 Norwegian VAT number. */
8
8
  declare const generate: () => string;
9
9
  /** Norwegian VAT Number. */
10
- declare const mva: Validator;
10
+ declare const mva: CountryValidator<"NO">;
11
11
  //#endregion
12
12
  export { compact, mva as default, format, generate, validate };
13
13
  //# sourceMappingURL=mva.d.ts.map
package/dist/no/mva.js CHANGED
@@ -2,14 +2,6 @@ import { clean } from "../_util/clean.js";
2
2
  import { err } from "../_util/result.js";
3
3
  import { generate as generate$1, validate as validate$1 } from "./orgnr.js";
4
4
  //#region src/no/mva.ts
5
- /**
6
- * MVA (Merverdiavgift, Norwegian VAT number).
7
- *
8
- * Format: optional "NO" prefix + 9 digits + "MVA" suffix.
9
- * The 9-digit part is validated as an Organisasjonsnummer.
10
- *
11
- * @see https://www.skatteetaten.no/
12
- */
13
5
  const compact = (value) => {
14
6
  let v = clean(value, " -").toUpperCase();
15
7
  if (v.startsWith("NO")) v = v.slice(2);
@@ -39,6 +31,7 @@ const mva = {
39
31
  abbreviation: "MVA",
40
32
  aliases: ["MVA-nummer", "organisasjonsnummer"],
41
33
  candidatePattern: "NO\\d{9}MVA",
34
+ scope: "country",
42
35
  country: "NO",
43
36
  entityType: "company",
44
37
  sourceUrl: "https://www.skatteetaten.no/",
@@ -1 +1 @@
1
- {"version":3,"file":"mva.js","names":["validateOrgnr","generateOrgnr"],"sources":["../../src/no/mva.ts"],"sourcesContent":["/**\n * MVA (Merverdiavgift, Norwegian VAT number).\n *\n * Format: optional \"NO\" prefix + 9 digits + \"MVA\" suffix.\n * The 9-digit part is validated as an Organisasjonsnummer.\n *\n * @see https://www.skatteetaten.no/\n */\n\nimport { clean } from \"#util/clean\";\nimport { err } from \"#util/result\";\n\nimport type { ValidateResult, Validator } from \"../types\";\nimport {\n validate as validateOrgnr,\n generate as generateOrgnr,\n} from \"./orgnr\";\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -\").toUpperCase();\n if (v.startsWith(\"NO\")) {\n v = v.slice(2);\n }\n return v;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (!v.endsWith(\"MVA\")) {\n return err(\n \"INVALID_FORMAT\",\n \"Norwegian VAT must end with MVA\",\n );\n }\n\n const digits = v.slice(0, -3);\n const orgnrResult = validateOrgnr(digits);\n if (!orgnrResult.valid) {\n return orgnrResult;\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n const digits = v.endsWith(\"MVA\") ? v.slice(0, -3) : v;\n return `NO ${digits.slice(0, 3)} ${digits.slice(3, 6)} ${digits.slice(6)} MVA`;\n};\n\n/** Generate a random valid Norwegian VAT number. */\nconst generate = (): string => generateOrgnr() + \"MVA\";\n\n/** Norwegian VAT Number. */\nconst mva: Validator = {\n name: \"Norwegian VAT Number\",\n localName: \"Merverdiavgift\",\n abbreviation: \"MVA\",\n aliases: [\"MVA-nummer\", \"organisasjonsnummer\"] as const,\n candidatePattern: \"NO\\\\d{9}MVA\",\n country: \"NO\",\n entityType: \"company\",\n sourceUrl: \"https://www.skatteetaten.no/\",\n examples: [\"995525828MVA\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default mva;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;AAkBA,MAAM,WAAW,UAA0B;CACzC,IAAI,IAAI,MAAM,OAAO,KAAK,CAAC,aAAa;AACxC,KAAI,EAAE,WAAW,KAAK,CACpB,KAAI,EAAE,MAAM,EAAE;AAEhB,QAAO;;AAGT,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AAExB,KAAI,CAAC,EAAE,SAAS,MAAM,CACpB,QAAO,IACL,kBACA,kCACD;CAIH,MAAM,cAAcA,WADL,EAAE,MAAM,GAAG,GAAG,CACY;AACzC,KAAI,CAAC,YAAY,MACf,QAAO;AAGT,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;CACxB,MAAM,SAAS,EAAE,SAAS,MAAM,GAAG,EAAE,MAAM,GAAG,GAAG,GAAG;AACpD,QAAO,MAAM,OAAO,MAAM,GAAG,EAAE,CAAC,GAAG,OAAO,MAAM,GAAG,EAAE,CAAC,GAAG,OAAO,MAAM,EAAE,CAAC;;;AAI3E,MAAM,iBAAyBC,YAAe,GAAG;;AAGjD,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,cAAc,sBAAsB;CAC9C,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,eAAe;CAC1B;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"mva.js","names":["validateOrgnr","generateOrgnr"],"sources":["../../src/no/mva.ts"],"sourcesContent":["/**\n * MVA (Merverdiavgift, Norwegian VAT number).\n *\n * Format: optional \"NO\" prefix + 9 digits + \"MVA\" suffix.\n * The 9-digit part is validated as an Organisasjonsnummer.\n *\n * @see https://www.skatteetaten.no/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\nimport {\n validate as validateOrgnr,\n generate as generateOrgnr,\n} from \"./orgnr\";\n\nimport { clean } from \"#util/clean\";\nimport { err } from \"#util/result\";\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -\").toUpperCase();\n if (v.startsWith(\"NO\")) {\n v = v.slice(2);\n }\n return v;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (!v.endsWith(\"MVA\")) {\n return err(\n \"INVALID_FORMAT\",\n \"Norwegian VAT must end with MVA\",\n );\n }\n\n const digits = v.slice(0, -3);\n const orgnrResult = validateOrgnr(digits);\n if (!orgnrResult.valid) {\n return orgnrResult;\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n const digits = v.endsWith(\"MVA\") ? v.slice(0, -3) : v;\n return `NO ${digits.slice(0, 3)} ${digits.slice(3, 6)} ${digits.slice(6)} MVA`;\n};\n\n/** Generate a random valid Norwegian VAT number. */\nconst generate = (): string => generateOrgnr() + \"MVA\";\n\n/** Norwegian VAT Number. */\nconst mva: CountryValidator<\"NO\"> = {\n name: \"Norwegian VAT Number\",\n localName: \"Merverdiavgift\",\n abbreviation: \"MVA\",\n aliases: [\"MVA-nummer\", \"organisasjonsnummer\"] as const,\n candidatePattern: \"NO\\\\d{9}MVA\",\n scope: \"country\",\n country: \"NO\",\n entityType: \"company\",\n sourceUrl: \"https://www.skatteetaten.no/\",\n examples: [\"995525828MVA\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default mva;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;AAqBA,MAAM,WAAW,UAA0B;CACzC,IAAI,IAAI,MAAM,OAAO,IAAI,EAAE,YAAY;CACvC,IAAI,EAAE,WAAW,IAAI,GACnB,IAAI,EAAE,MAAM,CAAC;CAEf,OAAO;AACT;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CAEvB,IAAI,CAAC,EAAE,SAAS,KAAK,GACnB,OAAO,IACL,kBACA,iCACF;CAIF,MAAM,cAAcA,WADL,EAAE,MAAM,GAAG,EACa,CAAC;CACxC,IAAI,CAAC,YAAY,OACf,OAAO;CAGT,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,KAAK;CACvB,MAAM,SAAS,EAAE,SAAS,KAAK,IAAI,EAAE,MAAM,GAAG,EAAE,IAAI;CACpD,OAAO,MAAM,OAAO,MAAM,GAAG,CAAC,EAAE,GAAG,OAAO,MAAM,GAAG,CAAC,EAAE,GAAG,OAAO,MAAM,CAAC,EAAE;AAC3E;;AAGA,MAAM,iBAAyBC,WAAc,IAAI;;AAGjD,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,cAAc,qBAAqB;CAC7C,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,cAAc;CACzB;CACA;CACA;CACA;AACF"}
@@ -1,4 +1,4 @@
1
- import { ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ValidateResult } from "../types.js";
2
2
 
3
3
  //#region src/no/orgnr.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 Norwegian org number. */
8
8
  declare const generate: () => string;
9
9
  /** Norwegian Organization Number. */
10
- declare const orgnr: Validator;
10
+ declare const orgnr: CountryValidator<"NO">;
11
11
  //#endregion
12
12
  export { compact, orgnr as default, format, generate, validate };
13
13
  //# sourceMappingURL=orgnr.d.ts.map
package/dist/no/orgnr.js CHANGED
@@ -1,16 +1,9 @@
1
+ import { weightedSum } from "../_checksums/weighted-sum.js";
1
2
  import { clean } from "../_util/clean.js";
2
3
  import { randomDigits } from "../_util/generate.js";
3
4
  import { err } from "../_util/result.js";
4
5
  import { isdigits } from "../_util/strings.js";
5
- import { weightedSum } from "../_checksums/weighted-sum.js";
6
6
  //#region src/no/orgnr.ts
7
- /**
8
- * Organisasjonsnummer (Norwegian organization number).
9
- *
10
- * 9 digits. Weights [3,2,7,6,5,4,3,2,1], sum % 11 === 0.
11
- *
12
- * @see https://www.brreg.no/
13
- */
14
7
  const WEIGHTS = [
15
8
  3,
16
9
  2,
@@ -51,6 +44,7 @@ const orgnr = {
51
44
  abbreviation: "Orgnr",
52
45
  aliases: ["organisasjonsnummer", "org.nr"],
53
46
  candidatePattern: "\\d{9}",
47
+ scope: "country",
54
48
  country: "NO",
55
49
  entityType: "company",
56
50
  sourceUrl: "https://www.brreg.no/",
@@ -1 +1 @@
1
- {"version":3,"file":"orgnr.js","names":[],"sources":["../../src/no/orgnr.ts"],"sourcesContent":["/**\n * Organisasjonsnummer (Norwegian organization number).\n *\n * 9 digits. Weights [3,2,7,6,5,4,3,2,1], sum % 11 === 0.\n *\n * @see https://www.brreg.no/\n */\n\nimport { weightedSum } from \"#checksums/weighted-sum\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst WEIGHTS = [3, 2, 7, 6, 5, 4, 3, 2, 1] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"Norwegian org number must be 9 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Norwegian org number must contain only digits\",\n );\n }\n\n const sum = weightedSum(v, WEIGHTS, 11);\n if (sum !== 0) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Norwegian org number check digit mismatch\",\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, 3)} ${v.slice(3, 6)} ${v.slice(6)}`;\n};\n\n/** Generate a random valid Norwegian org number. */\nconst generate = (): string => {\n for (;;) {\n const c = randomDigits(9);\n if (validate(c).valid) return c;\n }\n};\n\n/** Norwegian Organization Number. */\nconst orgnr: Validator = {\n name: \"Norwegian Organization Number\",\n localName: \"Organisasjonsnummer\",\n abbreviation: \"Orgnr\",\n aliases: [\"organisasjonsnummer\", \"org.nr\"] as const,\n candidatePattern: \"\\\\d{9}\",\n country: \"NO\",\n entityType: \"company\",\n sourceUrl: \"https://www.brreg.no/\",\n examples: [\"923609016\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default orgnr;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;AAgBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAE3C,MAAM,WAAW,UACf,MAAM,OAAO,KAAK;AAEpB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,IACL,kBACA,wCACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,gDACD;AAIH,KADY,YAAY,GAAG,SAAS,GAAG,KAC3B,EACV,QAAO,IACL,oBACA,4CACD;AAGH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;AACxB,QAAO,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE;;;AAIxD,MAAM,iBAAyB;AAC7B,UAAS;EACP,MAAM,IAAI,aAAa,EAAE;AACzB,MAAI,SAAS,EAAE,CAAC,MAAO,QAAO;;;;AAKlC,MAAM,QAAmB;CACvB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,uBAAuB,SAAS;CAC1C,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,YAAY;CACvB;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"orgnr.js","names":[],"sources":["../../src/no/orgnr.ts"],"sourcesContent":["/**\n * Organisasjonsnummer (Norwegian organization number).\n *\n * 9 digits. Weights [3,2,7,6,5,4,3,2,1], sum % 11 === 0.\n *\n * @see https://www.brreg.no/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { weightedSum } from \"#checksums/weighted-sum\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst WEIGHTS = [3, 2, 7, 6, 5, 4, 3, 2, 1] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"Norwegian org number must be 9 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Norwegian org number must contain only digits\",\n );\n }\n\n const sum = weightedSum(v, WEIGHTS, 11);\n if (sum !== 0) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Norwegian org number check digit mismatch\",\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, 3)} ${v.slice(3, 6)} ${v.slice(6)}`;\n};\n\n/** Generate a random valid Norwegian org number. */\nconst generate = (): string => {\n for (;;) {\n const c = randomDigits(9);\n if (validate(c).valid) return c;\n }\n};\n\n/** Norwegian Organization Number. */\nconst orgnr: CountryValidator<\"NO\"> = {\n name: \"Norwegian Organization Number\",\n localName: \"Organisasjonsnummer\",\n abbreviation: \"Orgnr\",\n aliases: [\"organisasjonsnummer\", \"org.nr\"] as const,\n candidatePattern: \"\\\\d{9}\",\n scope: \"country\",\n country: \"NO\",\n entityType: \"company\",\n sourceUrl: \"https://www.brreg.no/\",\n examples: [\"923609016\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default orgnr;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AAmBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAAC;AAE1C,MAAM,WAAW,UACf,MAAM,OAAO,IAAI;AAEnB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,GACf,OAAO,IACL,kBACA,uCACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,+CACF;CAIF,IADY,YAAY,GAAG,SAAS,EAC9B,MAAM,GACV,OAAO,IACL,oBACA,2CACF;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,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC;AACvD;;AAGA,MAAM,iBAAyB;CAC7B,SAAS;EACP,MAAM,IAAI,aAAa,CAAC;EACxB,IAAI,SAAS,CAAC,EAAE,OAAO,OAAO;CAChC;AACF;;AAGA,MAAM,QAAgC;CACpC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,uBAAuB,QAAQ;CACzC,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,WAAW;CACtB;CACA;CACA;CACA;AACF"}
package/dist/nz/ird.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/nz/ird.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 NZ IRD number. */
8
8
  declare const generate: () => string;
9
9
  /** New Zealand IRD Number. */
10
- declare const ird: Validator;
10
+ declare const ird: CountryValidator<"NZ">;
11
11
  //#endregion
12
12
  export { compact, ird as default, format, generate, validate };
13
13
  //# sourceMappingURL=ird.d.ts.map
package/dist/nz/ird.js CHANGED
@@ -3,16 +3,6 @@ import { randomDigits } from "../_util/generate.js";
3
3
  import { err } from "../_util/result.js";
4
4
  import { isdigits } from "../_util/strings.js";
5
5
  //#region src/nz/ird.ts
6
- /**
7
- * IRD number (New Zealand Inland Revenue Department
8
- * number, Te Tari Take).
9
- *
10
- * 8 or 9 digit number with a weighted checksum.
11
- * Uses primary weights, falling back to secondary
12
- * weights if the primary check yields 10.
13
- *
14
- * @see https://www.ird.govt.nz/
15
- */
16
6
  const PRIMARY_WEIGHTS = [
17
7
  3,
18
8
  2,
@@ -63,7 +53,7 @@ const validate = (value) => {
63
53
  if (num < 1e7 || num >= 15e7) return err("INVALID_COMPONENT", "IRD number out of valid range");
64
54
  const expected = calcCheckDigit(v.slice(0, -1));
65
55
  if (expected === null) return err("INVALID_COMPONENT", "IRD number cannot have a valid check digit");
66
- if (expected !== Number(v[v.length - 1])) return err("INVALID_CHECKSUM", "IRD check digit does not match");
56
+ if (expected !== Number(v.at(-1))) return err("INVALID_CHECKSUM", "IRD check digit does not match");
67
57
  return {
68
58
  valid: true,
69
59
  compact: v
@@ -88,6 +78,7 @@ const ird = {
88
78
  abbreviation: "IRD",
89
79
  aliases: ["IRD number", "tax number NZ"],
90
80
  candidatePattern: "\\d{8,9}",
81
+ scope: "country",
91
82
  country: "NZ",
92
83
  entityType: "any",
93
84
  compact,
@@ -1 +1 @@
1
- {"version":3,"file":"ird.js","names":[],"sources":["../../src/nz/ird.ts"],"sourcesContent":["/**\n * IRD number (New Zealand Inland Revenue Department\n * number, Te Tari Take).\n *\n * 8 or 9 digit number with a weighted checksum.\n * Uses primary weights, falling back to secondary\n * weights if the primary check yields 10.\n *\n * @see https://www.ird.govt.nz/\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst PRIMARY_WEIGHTS = [3, 2, 7, 6, 5, 4, 3, 2] as const;\n\nconst SECONDARY_WEIGHTS = [7, 4, 3, 2, 5, 2, 7, 6] as const;\n\n/**\n * Calculate the check digit for an IRD number.\n * The input should be the number without the check\n * digit, zero-padded to 8 digits.\n */\nconst calcCheckDigit = (payload: string): number | null => {\n const padded = payload.padStart(8, \"0\");\n let sum = 0;\n for (const [i, weight] of PRIMARY_WEIGHTS.entries()) {\n sum += weight * Number(padded[i]);\n }\n let remainder = ((-sum % 11) + 11) % 11;\n if (remainder !== 10) return remainder;\n\n sum = 0;\n for (const [i, weight] of SECONDARY_WEIGHTS.entries()) {\n sum += weight * Number(padded[i]);\n }\n remainder = ((-sum % 11) + 11) % 11;\n if (remainder === 10) return null;\n return remainder;\n};\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -\").toUpperCase();\n if (v.startsWith(\"NZ\")) {\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 && v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"IRD number must be 8 or 9 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"IRD number must contain only digits\",\n );\n }\n const num = Number(v);\n if (num < 10_000_000 || num >= 150_000_000) {\n return err(\n \"INVALID_COMPONENT\",\n \"IRD number out of valid range\",\n );\n }\n const payload = v.slice(0, -1);\n const expected = calcCheckDigit(payload);\n if (expected === null) {\n return err(\n \"INVALID_COMPONENT\",\n \"IRD number cannot have a valid check digit\",\n );\n }\n if (expected !== Number(v[v.length - 1])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"IRD check digit does not match\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n const last6 = v.slice(-6);\n const prefix = v.slice(0, -6);\n return `${prefix}-${last6.slice(0, 3)}-${last6.slice(3)}`;\n};\n\n/** Generate a random valid NZ IRD number. */\nconst generate = (): string => {\n for (;;) {\n const c = randomDigits(9);\n if (validate(c).valid) return c;\n }\n};\n\n/** New Zealand IRD Number. */\nconst ird: Validator = {\n name: \"IRD Number\",\n localName: \"IRD Number\",\n abbreviation: \"IRD\",\n aliases: [\"IRD number\", \"tax number NZ\"] as const,\n candidatePattern: \"\\\\d{8,9}\",\n country: \"NZ\",\n entityType: \"any\",\n compact,\n format,\n validate,\n description:\n \"New Zealand Inland Revenue Department number\",\n sourceUrl: \"https://www.ird.govt.nz/\",\n lengths: [8, 9] as const,\n examples: [\"49091850\", \"136410132\"] as const,\n generate,\n};\n\nexport default ird;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,MAAM,kBAAkB;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAEhD,MAAM,oBAAoB;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;;;;;;AAOlD,MAAM,kBAAkB,YAAmC;CACzD,MAAM,SAAS,QAAQ,SAAS,GAAG,IAAI;CACvC,IAAI,MAAM;AACV,MAAK,MAAM,CAAC,GAAG,WAAW,gBAAgB,SAAS,CACjD,QAAO,SAAS,OAAO,OAAO,GAAG;CAEnC,IAAI,aAAc,CAAC,MAAM,KAAM,MAAM;AACrC,KAAI,cAAc,GAAI,QAAO;AAE7B,OAAM;AACN,MAAK,MAAM,CAAC,GAAG,WAAW,kBAAkB,SAAS,CACnD,QAAO,SAAS,OAAO,OAAO,GAAG;AAEnC,cAAc,CAAC,MAAM,KAAM,MAAM;AACjC,KAAI,cAAc,GAAI,QAAO;AAC7B,QAAO;;AAGT,MAAM,WAAW,UAA0B;CACzC,IAAI,IAAI,MAAM,OAAO,KAAK,CAAC,aAAa;AACxC,KAAI,EAAE,WAAW,KAAK,CACpB,KAAI,EAAE,MAAM,EAAE;AAEhB,QAAO;;AAGT,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,KAAK,EAAE,WAAW,EACjC,QAAO,IACL,kBACA,mCACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,sCACD;CAEH,MAAM,MAAM,OAAO,EAAE;AACrB,KAAI,MAAM,OAAc,OAAO,KAC7B,QAAO,IACL,qBACA,gCACD;CAGH,MAAM,WAAW,eADD,EAAE,MAAM,GAAG,GAAG,CACU;AACxC,KAAI,aAAa,KACf,QAAO,IACL,qBACA,6CACD;AAEH,KAAI,aAAa,OAAO,EAAE,EAAE,SAAS,GAAG,CACtC,QAAO,IACL,oBACA,iCACD;AAEH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;CACxB,MAAM,QAAQ,EAAE,MAAM,GAAG;AAEzB,QAAO,GADQ,EAAE,MAAM,GAAG,GAAG,CACZ,GAAG,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,MAAM,MAAM,EAAE;;;AAIzD,MAAM,iBAAyB;AAC7B,UAAS;EACP,MAAM,IAAI,aAAa,EAAE;AACzB,MAAI,SAAS,EAAE,CAAC,MAAO,QAAO;;;;AAKlC,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,cAAc,gBAAgB;CACxC,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ;CACA;CACA;CACA,aACE;CACF,WAAW;CACX,SAAS,CAAC,GAAG,EAAE;CACf,UAAU,CAAC,YAAY,YAAY;CACnC;CACD"}
1
+ {"version":3,"file":"ird.js","names":[],"sources":["../../src/nz/ird.ts"],"sourcesContent":["/**\n * IRD number (New Zealand Inland Revenue Department\n * number, Te Tari Take).\n *\n * 8 or 9 digit number with a weighted checksum.\n * Uses primary weights, falling back to secondary\n * weights if the primary check yields 10.\n *\n * @see https://www.ird.govt.nz/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst PRIMARY_WEIGHTS = [3, 2, 7, 6, 5, 4, 3, 2] as const;\n\nconst SECONDARY_WEIGHTS = [7, 4, 3, 2, 5, 2, 7, 6] as const;\n\n/**\n * Calculate the check digit for an IRD number.\n * The input should be the number without the check\n * digit, zero-padded to 8 digits.\n */\nconst calcCheckDigit = (payload: string): number | null => {\n const padded = payload.padStart(8, \"0\");\n let sum = 0;\n for (const [i, weight] of PRIMARY_WEIGHTS.entries()) {\n sum += weight * Number(padded[i]);\n }\n let remainder = ((-sum % 11) + 11) % 11;\n if (remainder !== 10) return remainder;\n\n sum = 0;\n for (const [i, weight] of SECONDARY_WEIGHTS.entries()) {\n sum += weight * Number(padded[i]);\n }\n remainder = ((-sum % 11) + 11) % 11;\n if (remainder === 10) return null;\n return remainder;\n};\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -\").toUpperCase();\n if (v.startsWith(\"NZ\")) {\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 && v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"IRD number must be 8 or 9 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"IRD number must contain only digits\",\n );\n }\n const num = Number(v);\n if (num < 10_000_000 || num >= 150_000_000) {\n return err(\n \"INVALID_COMPONENT\",\n \"IRD number out of valid range\",\n );\n }\n const payload = v.slice(0, -1);\n const expected = calcCheckDigit(payload);\n if (expected === null) {\n return err(\n \"INVALID_COMPONENT\",\n \"IRD number cannot have a valid check digit\",\n );\n }\n if (expected !== Number(v.at(-1))) {\n return err(\n \"INVALID_CHECKSUM\",\n \"IRD check digit does not match\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n const last6 = v.slice(-6);\n const prefix = v.slice(0, -6);\n return `${prefix}-${last6.slice(0, 3)}-${last6.slice(3)}`;\n};\n\n/** Generate a random valid NZ IRD number. */\nconst generate = (): string => {\n for (;;) {\n const c = randomDigits(9);\n if (validate(c).valid) return c;\n }\n};\n\n/** New Zealand IRD Number. */\nconst ird: CountryValidator<\"NZ\"> = {\n name: \"IRD Number\",\n localName: \"IRD Number\",\n abbreviation: \"IRD\",\n aliases: [\"IRD number\", \"tax number NZ\"] as const,\n candidatePattern: \"\\\\d{8,9}\",\n scope: \"country\",\n country: \"NZ\",\n entityType: \"any\",\n compact,\n format,\n validate,\n description:\n \"New Zealand Inland Revenue Department number\",\n sourceUrl: \"https://www.ird.govt.nz/\",\n lengths: [8, 9] as const,\n examples: [\"49091850\", \"136410132\"] as const,\n generate,\n};\n\nexport default ird;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;AAqBA,MAAM,kBAAkB;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAAC;AAE/C,MAAM,oBAAoB;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAAC;;;;;;AAOjD,MAAM,kBAAkB,YAAmC;CACzD,MAAM,SAAS,QAAQ,SAAS,GAAG,GAAG;CACtC,IAAI,MAAM;CACV,KAAK,MAAM,CAAC,GAAG,WAAW,gBAAgB,QAAQ,GAChD,OAAO,SAAS,OAAO,OAAO,EAAE;CAElC,IAAI,aAAc,CAAC,MAAM,KAAM,MAAM;CACrC,IAAI,cAAc,IAAI,OAAO;CAE7B,MAAM;CACN,KAAK,MAAM,CAAC,GAAG,WAAW,kBAAkB,QAAQ,GAClD,OAAO,SAAS,OAAO,OAAO,EAAE;CAElC,aAAc,CAAC,MAAM,KAAM,MAAM;CACjC,IAAI,cAAc,IAAI,OAAO;CAC7B,OAAO;AACT;AAEA,MAAM,WAAW,UAA0B;CACzC,IAAI,IAAI,MAAM,OAAO,IAAI,EAAE,YAAY;CACvC,IAAI,EAAE,WAAW,IAAI,GACnB,IAAI,EAAE,MAAM,CAAC;CAEf,OAAO;AACT;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,KAAK,EAAE,WAAW,GACjC,OAAO,IACL,kBACA,kCACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,qCACF;CAEF,MAAM,MAAM,OAAO,CAAC;CACpB,IAAI,MAAM,OAAc,OAAO,MAC7B,OAAO,IACL,qBACA,+BACF;CAGF,MAAM,WAAW,eADD,EAAE,MAAM,GAAG,EACW,CAAC;CACvC,IAAI,aAAa,MACf,OAAO,IACL,qBACA,4CACF;CAEF,IAAI,aAAa,OAAO,EAAE,GAAG,EAAE,CAAC,GAC9B,OAAO,IACL,oBACA,gCACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,KAAK;CACvB,MAAM,QAAQ,EAAE,MAAM,EAAE;CAExB,OAAO,GADQ,EAAE,MAAM,GAAG,EACX,EAAE,GAAG,MAAM,MAAM,GAAG,CAAC,EAAE,GAAG,MAAM,MAAM,CAAC;AACxD;;AAGA,MAAM,iBAAyB;CAC7B,SAAS;EACP,MAAM,IAAI,aAAa,CAAC;EACxB,IAAI,SAAS,CAAC,EAAE,OAAO,OAAO;CAChC;AACF;;AAGA,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,cAAc,eAAe;CACvC,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ;CACA;CACA;CACA,aACE;CACF,WAAW;CACX,SAAS,CAAC,GAAG,CAAC;CACd,UAAU,CAAC,YAAY,WAAW;CAClC;AACF"}
package/dist/pa/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/pa/ruc.d.ts
4
4
  /**
@@ -16,7 +16,7 @@ declare const format: (value: string) => string;
16
16
  /** Generate a random valid Panama RUC (natural person). */
17
17
  declare const generate: () => string;
18
18
  /** Panama tax identification number. */
19
- declare const ruc: Validator;
19
+ declare const ruc: CountryValidator<"PA">;
20
20
  //#endregion
21
21
  export { compact, ruc as default, format, generate, validate };
22
22
  //# sourceMappingURL=ruc.d.ts.map