@stll/stdnum 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (704) hide show
  1. package/dist/_checksums/luhn.js.map +1 -1
  2. package/dist/_checksums/mod1110.js +1 -1
  3. package/dist/_checksums/mod1110.js.map +1 -1
  4. package/dist/_checksums/mod112.js.map +1 -1
  5. package/dist/_checksums/mod97.js.map +1 -1
  6. package/dist/_checksums/verhoeff.js.map +1 -1
  7. package/dist/_checksums/weighted-sum.js.map +1 -1
  8. package/dist/_util/arabic.js.map +1 -1
  9. package/dist/_util/clean.js.map +1 -1
  10. package/dist/_util/date.js.map +1 -1
  11. package/dist/_util/generate.js.map +1 -1
  12. package/dist/_util/result.js.map +1 -1
  13. package/dist/_util/strings.js.map +1 -1
  14. package/dist/ad/nrt.d.ts +16 -2
  15. package/dist/ad/nrt.js +1 -14
  16. package/dist/ad/nrt.js.map +1 -1
  17. package/dist/ae/eid.d.ts +2 -2
  18. package/dist/ae/eid.js +2 -12
  19. package/dist/ae/eid.js.map +1 -1
  20. package/dist/ai/tin.d.ts +20 -2
  21. package/dist/ai/tin.js +1 -18
  22. package/dist/ai/tin.js.map +1 -1
  23. package/dist/al/nipt.d.ts +13 -2
  24. package/dist/al/nipt.js +1 -11
  25. package/dist/al/nipt.js.map +1 -1
  26. package/dist/am/tin.d.ts +16 -2
  27. package/dist/am/tin.js +1 -14
  28. package/dist/am/tin.js.map +1 -1
  29. package/dist/ar/cbu.d.ts +2 -2
  30. package/dist/ar/cbu.js +1 -9
  31. package/dist/ar/cbu.js.map +1 -1
  32. package/dist/ar/cuit.d.ts +2 -2
  33. package/dist/ar/cuit.js +1 -17
  34. package/dist/ar/cuit.js.map +1 -1
  35. package/dist/ar/dni.d.ts +11 -2
  36. package/dist/ar/dni.js +1 -9
  37. package/dist/ar/dni.js.map +1 -1
  38. package/dist/at/businessid.d.ts +10 -2
  39. package/dist/at/businessid.js +1 -8
  40. package/dist/at/businessid.js.map +1 -1
  41. package/dist/at/tin.d.ts +2 -2
  42. package/dist/at/tin.js +1 -11
  43. package/dist/at/tin.js.map +1 -1
  44. package/dist/at/uid.d.ts +2 -2
  45. package/dist/at/uid.js +2 -10
  46. package/dist/at/uid.js.map +1 -1
  47. package/dist/at/vnr.d.ts +2 -2
  48. package/dist/at/vnr.js +4 -14
  49. package/dist/at/vnr.js.map +1 -1
  50. package/dist/au/abn.d.ts +2 -2
  51. package/dist/au/abn.js +1 -10
  52. package/dist/au/abn.js.map +1 -1
  53. package/dist/au/acn.d.ts +2 -2
  54. package/dist/au/acn.js +1 -10
  55. package/dist/au/acn.js.map +1 -1
  56. package/dist/au/tfn.d.ts +2 -2
  57. package/dist/au/tfn.js +1 -10
  58. package/dist/au/tfn.js.map +1 -1
  59. package/dist/az/voen.d.ts +2 -2
  60. package/dist/az/voen.js +1 -14
  61. package/dist/az/voen.js.map +1 -1
  62. package/dist/ba/jmbg.d.ts +2 -2
  63. package/dist/ba/jmbg.js +3 -11
  64. package/dist/ba/jmbg.js.map +1 -1
  65. package/dist/bd/nid.d.ts +23 -2
  66. package/dist/bd/nid.js +1 -21
  67. package/dist/bd/nid.js.map +1 -1
  68. package/dist/be/bis.d.ts +2 -2
  69. package/dist/be/bis.js +1 -11
  70. package/dist/be/bis.js.map +1 -1
  71. package/dist/be/nn.d.ts +2 -2
  72. package/dist/be/nn.js +1 -11
  73. package/dist/be/nn.js.map +1 -1
  74. package/dist/be/vat.d.ts +2 -2
  75. package/dist/be/vat.js +1 -9
  76. package/dist/be/vat.js.map +1 -1
  77. package/dist/bg/egn.d.ts +2 -2
  78. package/dist/bg/egn.js +3 -18
  79. package/dist/bg/egn.js.map +1 -1
  80. package/dist/bg/pnf.d.ts +2 -2
  81. package/dist/bg/pnf.js +1 -8
  82. package/dist/bg/pnf.js.map +1 -1
  83. package/dist/bg/vat.d.ts +2 -2
  84. package/dist/bg/vat.js +3 -9
  85. package/dist/bg/vat.js.map +1 -1
  86. package/dist/bh/cpr.d.ts +2 -2
  87. package/dist/bh/cpr.js +1 -17
  88. package/dist/bh/cpr.js.map +1 -1
  89. package/dist/bic.d.ts +13 -2
  90. package/dist/bic.js +1 -11
  91. package/dist/bic.js.map +1 -1
  92. package/dist/br/cnpj.d.ts +2 -2
  93. package/dist/br/cnpj.js +1 -20
  94. package/dist/br/cnpj.js.map +1 -1
  95. package/dist/br/cpf.d.ts +2 -2
  96. package/dist/br/cpf.js +1 -14
  97. package/dist/br/cpf.js.map +1 -1
  98. package/dist/by/unp.d.ts +2 -2
  99. package/dist/by/unp.js +3 -14
  100. package/dist/by/unp.js.map +1 -1
  101. package/dist/bz/tin.d.ts +2 -2
  102. package/dist/bz/tin.js +1 -26
  103. package/dist/bz/tin.js.map +1 -1
  104. package/dist/ca/bn.d.ts +2 -2
  105. package/dist/ca/bn.js +2 -10
  106. package/dist/ca/bn.js.map +1 -1
  107. package/dist/ca/sin.d.ts +2 -2
  108. package/dist/ca/sin.js +2 -10
  109. package/dist/ca/sin.js.map +1 -1
  110. package/dist/ch/ssn.d.ts +2 -2
  111. package/dist/ch/ssn.js +1 -9
  112. package/dist/ch/ssn.js.map +1 -1
  113. package/dist/ch/uid.d.ts +2 -2
  114. package/dist/ch/uid.js +1 -9
  115. package/dist/ch/uid.js.map +1 -1
  116. package/dist/ch/vat.d.ts +2 -2
  117. package/dist/ch/vat.js +1 -9
  118. package/dist/ch/vat.js.map +1 -1
  119. package/dist/cl/rut.d.ts +2 -2
  120. package/dist/cl/rut.js +1 -14
  121. package/dist/cl/rut.js.map +1 -1
  122. package/dist/cn/ric.d.ts +2 -2
  123. package/dist/cn/ric.js +3 -14
  124. package/dist/cn/ric.js.map +1 -1
  125. package/dist/cn/uscc.d.ts +2 -2
  126. package/dist/cn/uscc.js +1 -10
  127. package/dist/cn/uscc.js.map +1 -1
  128. package/dist/co/nit.d.ts +2 -2
  129. package/dist/co/nit.js +2 -12
  130. package/dist/co/nit.js.map +1 -1
  131. package/dist/cr/cpf.d.ts +18 -2
  132. package/dist/cr/cpf.js +1 -16
  133. package/dist/cr/cpf.js.map +1 -1
  134. package/dist/creditcard.d.ts +2 -2
  135. package/dist/creditcard.js +5 -14
  136. package/dist/creditcard.js.map +1 -1
  137. package/dist/cu/ni.d.ts +2 -2
  138. package/dist/cu/ni.js +2 -17
  139. package/dist/cu/ni.js.map +1 -1
  140. package/dist/cy/vat.d.ts +2 -2
  141. package/dist/cy/vat.js +1 -8
  142. package/dist/cy/vat.js.map +1 -1
  143. package/dist/cz/dic.d.ts +2 -2
  144. package/dist/cz/dic.js +7 -13
  145. package/dist/cz/dic.js.map +1 -1
  146. package/dist/cz/ico.d.ts +2 -2
  147. package/dist/cz/ico.js +2 -10
  148. package/dist/cz/ico.js.map +1 -1
  149. package/dist/cz/rc.d.ts +2 -2
  150. package/dist/cz/rc.js +2 -26
  151. package/dist/cz/rc.js.map +1 -1
  152. package/dist/de/handelsreg.d.ts +19 -2
  153. package/dist/de/handelsreg.js +1 -17
  154. package/dist/de/handelsreg.js.map +1 -1
  155. package/dist/de/idnr.d.ts +2 -2
  156. package/dist/de/idnr.js +2 -12
  157. package/dist/de/idnr.js.map +1 -1
  158. package/dist/de/stnr.d.ts +17 -2
  159. package/dist/de/stnr.js +1 -15
  160. package/dist/de/stnr.js.map +1 -1
  161. package/dist/de/svnr.d.ts +2 -2
  162. package/dist/de/svnr.js +2 -11
  163. package/dist/de/svnr.js.map +1 -1
  164. package/dist/de/vat.d.ts +2 -2
  165. package/dist/de/vat.js +2 -11
  166. package/dist/de/vat.js.map +1 -1
  167. package/dist/dk/cpr.d.ts +2 -2
  168. package/dist/dk/cpr.js +2 -10
  169. package/dist/dk/cpr.js.map +1 -1
  170. package/dist/dk/cvr.d.ts +2 -2
  171. package/dist/dk/cvr.js +2 -15
  172. package/dist/dk/cvr.js.map +1 -1
  173. package/dist/dk/vat.d.ts +2 -2
  174. package/dist/dk/vat.js +3 -13
  175. package/dist/dk/vat.js.map +1 -1
  176. package/dist/do/rnc.d.ts +2 -2
  177. package/dist/do/rnc.js +2 -16
  178. package/dist/do/rnc.js.map +1 -1
  179. package/dist/ec/ruc.d.ts +2 -2
  180. package/dist/ec/ruc.js +1 -18
  181. package/dist/ec/ruc.js.map +1 -1
  182. package/dist/ee/ik.d.ts +2 -2
  183. package/dist/ee/ik.js +3 -20
  184. package/dist/ee/ik.js.map +1 -1
  185. package/dist/ee/registrikood.d.ts +2 -2
  186. package/dist/ee/registrikood.js +1 -8
  187. package/dist/ee/registrikood.js.map +1 -1
  188. package/dist/ee/vat.d.ts +2 -2
  189. package/dist/ee/vat.js +2 -10
  190. package/dist/ee/vat.js.map +1 -1
  191. package/dist/eg/tn.d.ts +11 -2
  192. package/dist/eg/tn.js +1 -9
  193. package/dist/eg/tn.js.map +1 -1
  194. package/dist/es/cif.d.ts +2 -2
  195. package/dist/es/cif.js +1 -10
  196. package/dist/es/cif.js.map +1 -1
  197. package/dist/es/dni.d.ts +2 -2
  198. package/dist/es/dni.js +1 -9
  199. package/dist/es/dni.js.map +1 -1
  200. package/dist/es/nie.d.ts +2 -2
  201. package/dist/es/nie.js +1 -9
  202. package/dist/es/nie.js.map +1 -1
  203. package/dist/es/nss.d.ts +2 -2
  204. package/dist/es/nss.js +1 -16
  205. package/dist/es/nss.js.map +1 -1
  206. package/dist/es/vat.d.ts +2 -2
  207. package/dist/es/vat.js +5 -10
  208. package/dist/es/vat.js.map +1 -1
  209. package/dist/eu/vat.d.ts +2 -2
  210. package/dist/eu/vat.js +1 -0
  211. package/dist/eu/vat.js.map +1 -1
  212. package/dist/fi/hetu.d.ts +2 -2
  213. package/dist/fi/hetu.js +2 -10
  214. package/dist/fi/hetu.js.map +1 -1
  215. package/dist/fi/vat.d.ts +2 -2
  216. package/dist/fi/vat.js +3 -10
  217. package/dist/fi/vat.js.map +1 -1
  218. package/dist/fi/ytunnus.d.ts +2 -2
  219. package/dist/fi/ytunnus.js +2 -10
  220. package/dist/fi/ytunnus.js.map +1 -1
  221. package/dist/fr/nif.d.ts +2 -2
  222. package/dist/fr/nif.js +1 -9
  223. package/dist/fr/nif.js.map +1 -1
  224. package/dist/fr/nir.d.ts +2 -2
  225. package/dist/fr/nir.js +2 -14
  226. package/dist/fr/nir.js.map +1 -1
  227. package/dist/fr/siren.d.ts +2 -2
  228. package/dist/fr/siren.js +2 -10
  229. package/dist/fr/siren.js.map +1 -1
  230. package/dist/fr/siret.d.ts +2 -2
  231. package/dist/fr/siret.js +2 -11
  232. package/dist/fr/siret.js.map +1 -1
  233. package/dist/fr/tva.d.ts +2 -2
  234. package/dist/fr/tva.js +2 -12
  235. package/dist/fr/tva.js.map +1 -1
  236. package/dist/gb/nino.d.ts +12 -2
  237. package/dist/gb/nino.js +1 -10
  238. package/dist/gb/nino.js.map +1 -1
  239. package/dist/gb/sedol.d.ts +2 -2
  240. package/dist/gb/sedol.js +1 -11
  241. package/dist/gb/sedol.js.map +1 -1
  242. package/dist/gb/utr.d.ts +2 -2
  243. package/dist/gb/utr.js +2 -10
  244. package/dist/gb/utr.js.map +1 -1
  245. package/dist/gb/vat.d.ts +2 -2
  246. package/dist/gb/vat.js +2 -11
  247. package/dist/gb/vat.js.map +1 -1
  248. package/dist/ge/pin.d.ts +14 -2
  249. package/dist/ge/pin.js +1 -12
  250. package/dist/ge/pin.js.map +1 -1
  251. package/dist/gh/tin.d.ts +2 -2
  252. package/dist/gh/tin.js +1 -15
  253. package/dist/gh/tin.js.map +1 -1
  254. package/dist/gr/amka.d.ts +2 -2
  255. package/dist/gr/amka.js +3 -11
  256. package/dist/gr/amka.js.map +1 -1
  257. package/dist/gr/vat.d.ts +2 -2
  258. package/dist/gr/vat.js +1 -10
  259. package/dist/gr/vat.js.map +1 -1
  260. package/dist/gt/nit.d.ts +2 -2
  261. package/dist/gt/nit.js +1 -12
  262. package/dist/gt/nit.js.map +1 -1
  263. package/dist/hk/hkid.d.ts +2 -2
  264. package/dist/hk/hkid.js +1 -10
  265. package/dist/hk/hkid.js.map +1 -1
  266. package/dist/hr/vat.d.ts +2 -2
  267. package/dist/hr/vat.js +2 -9
  268. package/dist/hr/vat.js.map +1 -1
  269. package/dist/hu/vat.d.ts +2 -2
  270. package/dist/hu/vat.js +3 -10
  271. package/dist/hu/vat.js.map +1 -1
  272. package/dist/iban.d.ts +2 -2
  273. package/dist/iban.js +2 -8
  274. package/dist/iban.js.map +1 -1
  275. package/dist/id/npwp.d.ts +2 -2
  276. package/dist/id/npwp.js +3 -13
  277. package/dist/id/npwp.js.map +1 -1
  278. package/dist/ie/pps.d.ts +2 -2
  279. package/dist/ie/pps.js +1 -10
  280. package/dist/ie/pps.js.map +1 -1
  281. package/dist/ie/vat.d.ts +2 -2
  282. package/dist/ie/vat.js +1 -9
  283. package/dist/ie/vat.js.map +1 -1
  284. package/dist/il/idnr.d.ts +2 -2
  285. package/dist/il/idnr.js +2 -9
  286. package/dist/il/idnr.js.map +1 -1
  287. package/dist/in/aadhaar.d.ts +2 -2
  288. package/dist/in/aadhaar.js +2 -12
  289. package/dist/in/aadhaar.js.map +1 -1
  290. package/dist/in/gstin.d.ts +2 -2
  291. package/dist/in/gstin.js +1 -10
  292. package/dist/in/gstin.js.map +1 -1
  293. package/dist/in/pan.d.ts +15 -2
  294. package/dist/in/pan.js +1 -13
  295. package/dist/in/pan.js.map +1 -1
  296. package/dist/index.d.ts +2 -2
  297. package/dist/index.js +6 -6
  298. package/dist/iq/nid.d.ts +16 -2
  299. package/dist/iq/nid.js +2 -15
  300. package/dist/iq/nid.js.map +1 -1
  301. package/dist/ir/nid.d.ts +2 -2
  302. package/dist/ir/nid.js +2 -24
  303. package/dist/ir/nid.js.map +1 -1
  304. package/dist/is/kennitala.d.ts +2 -2
  305. package/dist/is/kennitala.js +2 -13
  306. package/dist/is/kennitala.js.map +1 -1
  307. package/dist/is/vsk.d.ts +9 -2
  308. package/dist/is/vsk.js +1 -7
  309. package/dist/is/vsk.js.map +1 -1
  310. package/dist/isin.d.ts +2 -2
  311. package/dist/isin.js +2 -12
  312. package/dist/isin.js.map +1 -1
  313. package/dist/it/codicefiscale.d.ts +2 -2
  314. package/dist/it/codicefiscale.js +1 -21
  315. package/dist/it/codicefiscale.js.map +1 -1
  316. package/dist/it/iva.d.ts +2 -2
  317. package/dist/it/iva.js +2 -9
  318. package/dist/it/iva.js.map +1 -1
  319. package/dist/jp/cn.d.ts +2 -2
  320. package/dist/jp/cn.js +1 -9
  321. package/dist/jp/cn.js.map +1 -1
  322. package/dist/jp/mynumber.d.ts +2 -2
  323. package/dist/jp/mynumber.js +1 -10
  324. package/dist/jp/mynumber.js.map +1 -1
  325. package/dist/kr/brn.d.ts +11 -2
  326. package/dist/kr/brn.js +1 -9
  327. package/dist/kr/brn.js.map +1 -1
  328. package/dist/kr/rrn.d.ts +2 -2
  329. package/dist/kr/rrn.js +2 -11
  330. package/dist/kr/rrn.js.map +1 -1
  331. package/dist/kw/civil.d.ts +2 -2
  332. package/dist/kw/civil.js +2 -14
  333. package/dist/kw/civil.js.map +1 -1
  334. package/dist/kz/iin.d.ts +2 -2
  335. package/dist/kz/iin.js +3 -18
  336. package/dist/kz/iin.js.map +1 -1
  337. package/dist/lei.d.ts +2 -2
  338. package/dist/lei.js +2 -11
  339. package/dist/lei.js.map +1 -1
  340. package/dist/li/peid.d.ts +11 -2
  341. package/dist/li/peid.js +1 -9
  342. package/dist/li/peid.js.map +1 -1
  343. package/dist/lk/nic.d.ts +2 -2
  344. package/dist/lk/nic.js +2 -14
  345. package/dist/lk/nic.js.map +1 -1
  346. package/dist/lt/asmens.d.ts +2 -2
  347. package/dist/lt/asmens.js +2 -1
  348. package/dist/lt/asmens.js.map +1 -1
  349. package/dist/lt/vat.d.ts +2 -2
  350. package/dist/lt/vat.js +2 -10
  351. package/dist/lt/vat.js.map +1 -1
  352. package/dist/lu/vat.d.ts +2 -2
  353. package/dist/lu/vat.js +2 -8
  354. package/dist/lu/vat.js.map +1 -1
  355. package/dist/luhn.d.ts +2 -2
  356. package/dist/luhn.js +2 -9
  357. package/dist/luhn.js.map +1 -1
  358. package/dist/lv/vat.d.ts +2 -2
  359. package/dist/lv/vat.js +2 -28
  360. package/dist/lv/vat.js.map +1 -1
  361. package/dist/ma/ice.d.ts +2 -2
  362. package/dist/ma/ice.js +2 -11
  363. package/dist/ma/ice.js.map +1 -1
  364. package/dist/mc/tva.d.ts +2 -2
  365. package/dist/mc/tva.js +1 -0
  366. package/dist/mc/tva.js.map +1 -1
  367. package/dist/md/idno.d.ts +2 -2
  368. package/dist/md/idno.js +1 -10
  369. package/dist/md/idno.js.map +1 -1
  370. package/dist/me/pib.d.ts +2 -2
  371. package/dist/me/pib.js +2 -10
  372. package/dist/me/pib.js.map +1 -1
  373. package/dist/mk/edb.d.ts +2 -2
  374. package/dist/mk/edb.js +2 -11
  375. package/dist/mk/edb.js.map +1 -1
  376. package/dist/mt/vat.d.ts +2 -2
  377. package/dist/mt/vat.js +3 -10
  378. package/dist/mt/vat.js.map +1 -1
  379. package/dist/mu/brn.d.ts +23 -2
  380. package/dist/mu/brn.js +1 -21
  381. package/dist/mu/brn.js.map +1 -1
  382. package/dist/mx/clabe.d.ts +2 -2
  383. package/dist/mx/clabe.js +1 -14
  384. package/dist/mx/clabe.js.map +1 -1
  385. package/dist/mx/curp.d.ts +2 -2
  386. package/dist/mx/curp.js +3 -17
  387. package/dist/mx/curp.js.map +1 -1
  388. package/dist/mx/rfc.d.ts +2 -2
  389. package/dist/mx/rfc.js +3 -19
  390. package/dist/mx/rfc.js.map +1 -1
  391. package/dist/my/nric.d.ts +2 -2
  392. package/dist/my/nric.js +2 -14
  393. package/dist/my/nric.js.map +1 -1
  394. package/dist/ng/nin.d.ts +13 -2
  395. package/dist/ng/nin.js +1 -11
  396. package/dist/ng/nin.js.map +1 -1
  397. package/dist/ni/ruc.d.ts +2 -2
  398. package/dist/ni/ruc.js +1 -23
  399. package/dist/ni/ruc.js.map +1 -1
  400. package/dist/nl/bsn.d.ts +2 -2
  401. package/dist/nl/bsn.js +2 -10
  402. package/dist/nl/bsn.js.map +1 -1
  403. package/dist/nl/kvk.d.ts +9 -2
  404. package/dist/nl/kvk.js +1 -7
  405. package/dist/nl/kvk.js.map +1 -1
  406. package/dist/nl/vat.d.ts +2 -2
  407. package/dist/nl/vat.js +1 -13
  408. package/dist/nl/vat.js.map +1 -1
  409. package/dist/no/fodselsnummer.d.ts +2 -2
  410. package/dist/no/fodselsnummer.js +2 -10
  411. package/dist/no/fodselsnummer.js.map +1 -1
  412. package/dist/no/mva.d.ts +2 -2
  413. package/dist/no/mva.js +1 -8
  414. package/dist/no/mva.js.map +1 -1
  415. package/dist/no/orgnr.d.ts +2 -2
  416. package/dist/no/orgnr.js +2 -8
  417. package/dist/no/orgnr.js.map +1 -1
  418. package/dist/nz/ird.d.ts +2 -2
  419. package/dist/nz/ird.js +2 -11
  420. package/dist/nz/ird.js.map +1 -1
  421. package/dist/pa/ruc.d.ts +2 -2
  422. package/dist/pa/ruc.js +1 -18
  423. package/dist/pa/ruc.js.map +1 -1
  424. package/dist/patterns.d.ts +8 -7
  425. package/dist/patterns.js +3 -5
  426. package/dist/patterns.js.map +1 -1
  427. package/dist/pe/ruc.d.ts +2 -2
  428. package/dist/pe/ruc.js +1 -15
  429. package/dist/pe/ruc.js.map +1 -1
  430. package/dist/ph/philid.d.ts +14 -2
  431. package/dist/ph/philid.js +1 -12
  432. package/dist/ph/philid.js.map +1 -1
  433. package/dist/pk/cnic.d.ts +14 -2
  434. package/dist/pk/cnic.js +1 -12
  435. package/dist/pk/cnic.js.map +1 -1
  436. package/dist/pl/nip.d.ts +2 -2
  437. package/dist/pl/nip.js +2 -10
  438. package/dist/pl/nip.js.map +1 -1
  439. package/dist/pl/pesel.d.ts +2 -2
  440. package/dist/pl/pesel.js +3 -13
  441. package/dist/pl/pesel.js.map +1 -1
  442. package/dist/pl/regon.d.ts +2 -2
  443. package/dist/pl/regon.js +2 -11
  444. package/dist/pl/regon.js.map +1 -1
  445. package/dist/pt/cc.d.ts +2 -2
  446. package/dist/pt/cc.js +1 -9
  447. package/dist/pt/cc.js.map +1 -1
  448. package/dist/pt/vat.d.ts +2 -2
  449. package/dist/pt/vat.js +3 -11
  450. package/dist/pt/vat.js.map +1 -1
  451. package/dist/ro/cnp.d.ts +2 -2
  452. package/dist/ro/cnp.js +4 -14
  453. package/dist/ro/cnp.js.map +1 -1
  454. package/dist/ro/vat.d.ts +2 -2
  455. package/dist/ro/vat.js +13 -11
  456. package/dist/ro/vat.js.map +1 -1
  457. package/dist/rs/pib.d.ts +2 -2
  458. package/dist/rs/pib.js +1 -9
  459. package/dist/rs/pib.js.map +1 -1
  460. package/dist/ru/inn.d.ts +2 -2
  461. package/dist/ru/inn.js +1 -11
  462. package/dist/ru/inn.js.map +1 -1
  463. package/dist/se/orgnr.d.ts +2 -2
  464. package/dist/se/orgnr.js +2 -9
  465. package/dist/se/orgnr.js.map +1 -1
  466. package/dist/se/personnummer.d.ts +2 -2
  467. package/dist/se/personnummer.js +7 -15
  468. package/dist/se/personnummer.js.map +1 -1
  469. package/dist/se/vat.d.ts +2 -2
  470. package/dist/se/vat.js +3 -10
  471. package/dist/se/vat.js.map +1 -1
  472. package/dist/sg/uen.d.ts +2 -2
  473. package/dist/sg/uen.js +1 -15
  474. package/dist/sg/uen.js.map +1 -1
  475. package/dist/si/emso.d.ts +2 -2
  476. package/dist/si/emso.js +3 -18
  477. package/dist/si/emso.js.map +1 -1
  478. package/dist/si/vat.d.ts +2 -2
  479. package/dist/si/vat.js +3 -12
  480. package/dist/si/vat.js.map +1 -1
  481. package/dist/sk/dic.d.ts +2 -2
  482. package/dist/sk/dic.js +1 -0
  483. package/dist/sk/dic.js.map +1 -1
  484. package/dist/sk/ico.d.ts +2 -2
  485. package/dist/sk/ico.js +1 -0
  486. package/dist/sk/ico.js.map +1 -1
  487. package/dist/sk/rc.d.ts +2 -2
  488. package/dist/sk/rc.js +1 -0
  489. package/dist/sk/rc.js.map +1 -1
  490. package/dist/th/tin.d.ts +2 -2
  491. package/dist/th/tin.js +1 -11
  492. package/dist/th/tin.js.map +1 -1
  493. package/dist/tr/tckimlik.d.ts +2 -2
  494. package/dist/tr/tckimlik.js +1 -20
  495. package/dist/tr/tckimlik.js.map +1 -1
  496. package/dist/tr/vkn.d.ts +2 -2
  497. package/dist/tr/vkn.js +1 -20
  498. package/dist/tr/vkn.js.map +1 -1
  499. package/dist/tw/ubn.d.ts +2 -2
  500. package/dist/tw/ubn.js +1 -11
  501. package/dist/tw/ubn.js.map +1 -1
  502. package/dist/types.d.ts +26 -4
  503. package/dist/ua/edrpou.d.ts +2 -2
  504. package/dist/ua/edrpou.js +1 -11
  505. package/dist/ua/edrpou.js.map +1 -1
  506. package/dist/us/ein.d.ts +12 -2
  507. package/dist/us/ein.js +1 -10
  508. package/dist/us/ein.js.map +1 -1
  509. package/dist/us/itin.d.ts +13 -2
  510. package/dist/us/itin.js +1 -11
  511. package/dist/us/itin.js.map +1 -1
  512. package/dist/us/rtn.d.ts +2 -2
  513. package/dist/us/rtn.js +3 -18
  514. package/dist/us/rtn.js.map +1 -1
  515. package/dist/us/ssn.d.ts +13 -2
  516. package/dist/us/ssn.js +1 -11
  517. package/dist/us/ssn.js.map +1 -1
  518. package/dist/uy/rut.d.ts +2 -2
  519. package/dist/uy/rut.js +1 -14
  520. package/dist/uy/rut.js.map +1 -1
  521. package/dist/ve/rif.d.ts +2 -2
  522. package/dist/ve/rif.js +2 -15
  523. package/dist/ve/rif.js.map +1 -1
  524. package/dist/vn/mst.d.ts +2 -2
  525. package/dist/vn/mst.js +1 -12
  526. package/dist/vn/mst.js.map +1 -1
  527. package/dist/za/idnr.d.ts +2 -2
  528. package/dist/za/idnr.js +3 -16
  529. package/dist/za/idnr.js.map +1 -1
  530. package/package.json +22 -12
  531. package/src/_checksums/mod1110.ts +1 -1
  532. package/src/ad/nrt.ts +7 -3
  533. package/src/ae/eid.ts +7 -3
  534. package/src/ai/tin.ts +7 -3
  535. package/src/al/nipt.ts +7 -3
  536. package/src/am/tin.ts +7 -3
  537. package/src/ar/cbu.ts +7 -3
  538. package/src/ar/cuit.ts +7 -3
  539. package/src/ar/dni.ts +7 -3
  540. package/src/at/businessid.ts +7 -3
  541. package/src/at/tin.ts +7 -3
  542. package/src/at/uid.ts +7 -3
  543. package/src/at/vnr.ts +37 -9
  544. package/src/au/abn.ts +7 -3
  545. package/src/au/acn.ts +7 -3
  546. package/src/au/tfn.ts +7 -3
  547. package/src/az/voen.ts +7 -3
  548. package/src/ba/jmbg.ts +8 -7
  549. package/src/bd/nid.ts +7 -3
  550. package/src/be/bis.ts +8 -4
  551. package/src/be/nn.ts +7 -3
  552. package/src/be/vat.ts +7 -3
  553. package/src/bg/egn.ts +8 -7
  554. package/src/bg/pnf.ts +7 -3
  555. package/src/bg/vat.ts +8 -3
  556. package/src/bh/cpr.ts +7 -3
  557. package/src/bic.ts +7 -3
  558. package/src/br/cnpj.ts +7 -3
  559. package/src/br/cpf.ts +7 -3
  560. package/src/by/unp.ts +10 -5
  561. package/src/bz/tin.ts +7 -3
  562. package/src/ca/bn.ts +7 -3
  563. package/src/ca/sin.ts +7 -3
  564. package/src/ch/ssn.ts +7 -3
  565. package/src/ch/uid.ts +7 -3
  566. package/src/ch/vat.ts +9 -5
  567. package/src/cl/rut.ts +7 -3
  568. package/src/cn/ric.ts +8 -7
  569. package/src/cn/uscc.ts +7 -3
  570. package/src/co/nit.ts +8 -4
  571. package/src/cr/cpf.ts +7 -3
  572. package/src/creditcard.ts +10 -6
  573. package/src/cu/ni.ts +8 -7
  574. package/src/cy/vat.ts +7 -3
  575. package/src/cz/dic.ts +9 -4
  576. package/src/cz/ico.ts +7 -3
  577. package/src/cz/rc.ts +8 -7
  578. package/src/de/handelsreg.ts +7 -3
  579. package/src/de/idnr.ts +7 -3
  580. package/src/de/stnr.ts +7 -3
  581. package/src/de/svnr.ts +7 -3
  582. package/src/de/vat.ts +7 -3
  583. package/src/dk/cpr.ts +8 -7
  584. package/src/dk/cvr.ts +7 -3
  585. package/src/dk/vat.ts +8 -3
  586. package/src/do/rnc.ts +7 -3
  587. package/src/ec/ruc.ts +7 -3
  588. package/src/ee/ik.ts +8 -7
  589. package/src/ee/registrikood.ts +8 -4
  590. package/src/ee/vat.ts +7 -3
  591. package/src/eg/tn.ts +7 -3
  592. package/src/es/cif.ts +8 -4
  593. package/src/es/dni.ts +7 -3
  594. package/src/es/nie.ts +8 -4
  595. package/src/es/nss.ts +7 -3
  596. package/src/es/vat.ts +13 -5
  597. package/src/eu/vat.ts +10 -6
  598. package/src/fi/hetu.ts +8 -7
  599. package/src/fi/vat.ts +8 -3
  600. package/src/fi/ytunnus.ts +7 -3
  601. package/src/fr/nif.ts +7 -3
  602. package/src/fr/nir.ts +8 -7
  603. package/src/fr/siren.ts +7 -3
  604. package/src/fr/siret.ts +7 -3
  605. package/src/fr/tva.ts +7 -3
  606. package/src/gb/nino.ts +7 -3
  607. package/src/gb/sedol.ts +7 -3
  608. package/src/gb/utr.ts +7 -3
  609. package/src/gb/vat.ts +7 -3
  610. package/src/ge/pin.ts +7 -3
  611. package/src/gh/tin.ts +7 -3
  612. package/src/gr/amka.ts +7 -3
  613. package/src/gr/vat.ts +7 -3
  614. package/src/gt/nit.ts +7 -3
  615. package/src/hk/hkid.ts +7 -3
  616. package/src/hr/vat.ts +7 -3
  617. package/src/hu/vat.ts +8 -3
  618. package/src/iban.ts +7 -3
  619. package/src/id/npwp.ts +7 -3
  620. package/src/ie/pps.ts +7 -3
  621. package/src/ie/vat.ts +7 -3
  622. package/src/il/idnr.ts +7 -3
  623. package/src/in/aadhaar.ts +7 -3
  624. package/src/in/gstin.ts +7 -3
  625. package/src/in/pan.ts +7 -3
  626. package/src/index.ts +3 -0
  627. package/src/iq/nid.ts +7 -3
  628. package/src/ir/nid.ts +7 -3
  629. package/src/is/kennitala.ts +7 -3
  630. package/src/is/vsk.ts +7 -3
  631. package/src/isin.ts +7 -3
  632. package/src/it/codicefiscale.ts +11 -7
  633. package/src/it/iva.ts +7 -3
  634. package/src/jp/cn.ts +7 -3
  635. package/src/jp/mynumber.ts +7 -3
  636. package/src/kr/brn.ts +7 -3
  637. package/src/kr/rrn.ts +8 -7
  638. package/src/kw/civil.ts +8 -7
  639. package/src/kz/iin.ts +8 -8
  640. package/src/lei.ts +7 -3
  641. package/src/li/peid.ts +7 -3
  642. package/src/lk/nic.ts +8 -7
  643. package/src/lt/asmens.ts +8 -4
  644. package/src/lt/vat.ts +8 -3
  645. package/src/lu/vat.ts +8 -3
  646. package/src/luhn.ts +7 -3
  647. package/src/lv/vat.ts +7 -3
  648. package/src/ma/ice.ts +7 -3
  649. package/src/mc/tva.ts +9 -5
  650. package/src/md/idno.ts +7 -3
  651. package/src/me/pib.ts +7 -3
  652. package/src/mk/edb.ts +7 -3
  653. package/src/mt/vat.ts +8 -3
  654. package/src/mu/brn.ts +7 -3
  655. package/src/mx/clabe.ts +7 -3
  656. package/src/mx/curp.ts +9 -8
  657. package/src/mx/rfc.ts +8 -4
  658. package/src/my/nric.ts +8 -7
  659. package/src/ng/nin.ts +7 -3
  660. package/src/ni/ruc.ts +7 -3
  661. package/src/nl/bsn.ts +7 -3
  662. package/src/nl/kvk.ts +7 -3
  663. package/src/nl/vat.ts +7 -3
  664. package/src/no/fodselsnummer.ts +11 -7
  665. package/src/no/mva.ts +9 -5
  666. package/src/no/orgnr.ts +7 -3
  667. package/src/nz/ird.ts +8 -4
  668. package/src/pa/ruc.ts +7 -3
  669. package/src/patterns.ts +49 -18
  670. package/src/pe/ruc.ts +7 -3
  671. package/src/ph/philid.ts +7 -3
  672. package/src/pk/cnic.ts +7 -3
  673. package/src/pl/nip.ts +7 -3
  674. package/src/pl/pesel.ts +8 -7
  675. package/src/pl/regon.ts +7 -3
  676. package/src/pt/cc.ts +7 -3
  677. package/src/pt/vat.ts +8 -3
  678. package/src/ro/cnp.ts +15 -8
  679. package/src/ro/vat.ts +8 -3
  680. package/src/rs/pib.ts +7 -3
  681. package/src/ru/inn.ts +7 -3
  682. package/src/se/orgnr.ts +7 -3
  683. package/src/se/personnummer.ts +35 -33
  684. package/src/se/vat.ts +8 -3
  685. package/src/sg/uen.ts +7 -3
  686. package/src/si/emso.ts +8 -7
  687. package/src/si/vat.ts +8 -3
  688. package/src/sk/dic.ts +8 -4
  689. package/src/sk/ico.ts +3 -2
  690. package/src/sk/rc.ts +6 -2
  691. package/src/th/tin.ts +7 -3
  692. package/src/tr/tckimlik.ts +7 -3
  693. package/src/tr/vkn.ts +7 -3
  694. package/src/tw/ubn.ts +7 -3
  695. package/src/types.ts +34 -3
  696. package/src/ua/edrpou.ts +7 -3
  697. package/src/us/ein.ts +7 -3
  698. package/src/us/itin.ts +7 -3
  699. package/src/us/rtn.ts +16 -8
  700. package/src/us/ssn.ts +7 -3
  701. package/src/uy/rut.ts +7 -3
  702. package/src/ve/rif.ts +8 -6
  703. package/src/vn/mst.ts +7 -3
  704. package/src/za/idnr.ts +8 -7
package/dist/cz/ico.js CHANGED
@@ -1,18 +1,9 @@
1
+ import { weightedSum } from "../_checksums/weighted-sum.js";
1
2
  import { clean } from "../_util/clean.js";
2
3
  import { randomDigits } from "../_util/generate.js";
3
4
  import { err } from "../_util/result.js";
4
5
  import { isdigits } from "../_util/strings.js";
5
- import { weightedSum } from "../_checksums/weighted-sum.js";
6
6
  //#region src/cz/ico.ts
7
- /**
8
- * IČO (Identifikační číslo osoby).
9
- *
10
- * Czech company identification number. 8 digits
11
- * with a weighted checksum. Assigned by the Czech
12
- * Statistical Office.
13
- *
14
- * @see https://www.czso.cz/
15
- */
16
7
  const WEIGHTS = [
17
8
  8,
18
9
  7,
@@ -53,6 +44,7 @@ const ico = {
53
44
  "identifikační číslo"
54
45
  ],
55
46
  candidatePattern: "\\d{8}",
47
+ scope: "country",
56
48
  country: "CZ",
57
49
  entityType: "company",
58
50
  description: "8-digit company ID assigned by the Czech Statistical Office",
@@ -1 +1 @@
1
- {"version":3,"file":"ico.js","names":[],"sources":["../../src/cz/ico.ts"],"sourcesContent":["/**\n * IČO (Identifikační číslo osoby).\n *\n * Czech company identification number. 8 digits\n * with a weighted checksum. Assigned by the Czech\n * Statistical Office.\n *\n * @see https://www.czso.cz/\n */\n\nimport { weightedSum } from \"#checksums/weighted-sum\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst WEIGHTS = [8, 7, 6, 5, 4, 3, 2] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 8) {\n return err(\n \"INVALID_LENGTH\",\n \"IČO must be exactly 8 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"IČO must contain only digits\",\n );\n }\n const sum = weightedSum(v.slice(0, 7), WEIGHTS, 11);\n const v11 = (11 - sum) % 11;\n const check = v11 === 0 ? 1 : v11 % 10;\n if (check !== Number(v[7])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"IČO check digit does not match\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid ICO. */\nconst generate = (): string => {\n const payload = randomDigits(7);\n const sum = weightedSum(payload, WEIGHTS, 11);\n const v11 = (11 - sum) % 11;\n const check = v11 === 0 ? 1 : v11 % 10;\n return `${payload}${String(check)}`;\n};\n\n/** Czech Company Identification Number. */\nconst ico: Validator = {\n name: \"Czech Company ID\",\n localName: \"Identifikační číslo osoby\",\n abbreviation: \"IČO\",\n aliases: [\"IČO\", \"IČ\", \"identifikační číslo\"] as const,\n candidatePattern: \"\\\\d{8}\",\n country: \"CZ\",\n entityType: \"company\",\n description:\n \"8-digit company ID assigned by the Czech Statistical Office\",\n sourceUrl: \"https://www.czso.cz/\",\n lengths: [8] as const,\n examples: [\"25123891\", \"27074358\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default ico;\nexport { compact, format, generate, validate };\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE;AAErC,MAAM,WAAW,UACf,MAAM,OAAO,KAAK;AAEpB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,IACL,kBACA,+BACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,+BACD;CAGH,MAAM,OAAO,KADD,YAAY,EAAE,MAAM,GAAG,EAAE,EAAE,SAAS,GAAG,IAC1B;AAEzB,MADc,QAAQ,IAAI,IAAI,MAAM,QACtB,OAAO,EAAE,GAAG,CACxB,QAAO,IACL,oBACA,iCACD;AAEH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B,QAAQ,MAAM;;AAGxD,MAAM,iBAAyB;CAC7B,MAAM,UAAU,aAAa,EAAE;CAE/B,MAAM,OAAO,KADD,YAAY,SAAS,SAAS,GAAG,IACpB;CACzB,MAAM,QAAQ,QAAQ,IAAI,IAAI,MAAM;AACpC,QAAO,GAAG,UAAU,OAAO,MAAM;;;AAInC,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EAAC;EAAO;EAAM;EAAsB;CAC7C,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,aACE;CACF,WAAW;CACX,SAAS,CAAC,EAAE;CACZ,UAAU,CAAC,YAAY,WAAW;CAClC;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"ico.js","names":[],"sources":["../../src/cz/ico.ts"],"sourcesContent":["/**\n * IČO (Identifikační číslo osoby).\n *\n * Czech company identification number. 8 digits\n * with a weighted checksum. Assigned by the Czech\n * Statistical Office.\n *\n * @see https://www.czso.cz/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { weightedSum } from \"#checksums/weighted-sum\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst WEIGHTS = [8, 7, 6, 5, 4, 3, 2] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 8) {\n return err(\n \"INVALID_LENGTH\",\n \"IČO must be exactly 8 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"IČO must contain only digits\",\n );\n }\n const sum = weightedSum(v.slice(0, 7), WEIGHTS, 11);\n const v11 = (11 - sum) % 11;\n const check = v11 === 0 ? 1 : v11 % 10;\n if (check !== Number(v[7])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"IČO check digit does not match\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid ICO. */\nconst generate = (): string => {\n const payload = randomDigits(7);\n const sum = weightedSum(payload, WEIGHTS, 11);\n const v11 = (11 - sum) % 11;\n const check = v11 === 0 ? 1 : v11 % 10;\n return `${payload}${String(check)}`;\n};\n\n/** Czech Company Identification Number. */\nconst ico: CountryValidator<\"CZ\"> = {\n name: \"Czech Company ID\",\n localName: \"Identifikační číslo osoby\",\n abbreviation: \"IČO\",\n aliases: [\"IČO\", \"IČ\", \"identifikační číslo\"] as const,\n candidatePattern: \"\\\\d{8}\",\n scope: \"country\",\n country: \"CZ\",\n entityType: \"company\",\n description:\n \"8-digit company ID assigned by the Czech Statistical Office\",\n sourceUrl: \"https://www.czso.cz/\",\n lengths: [8] as const,\n examples: [\"25123891\", \"27074358\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default ico;\nexport { compact, format, generate, validate };\n"],"mappings":";;;;;;AAqBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAAC;AAEpC,MAAM,WAAW,UACf,MAAM,OAAO,IAAI;AAEnB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,GACf,OAAO,IACL,kBACA,8BACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,8BACF;CAGF,MAAM,OAAO,KADD,YAAY,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,EAC5B,KAAK;CAEzB,KADc,QAAQ,IAAI,IAAI,MAAM,QACtB,OAAO,EAAE,EAAE,GACvB,OAAO,IACL,oBACA,gCACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B,QAAQ,KAAK;;AAGvD,MAAM,iBAAyB;CAC7B,MAAM,UAAU,aAAa,CAAC;CAE9B,MAAM,OAAO,KADD,YAAY,SAAS,SAAS,EACtB,KAAK;CACzB,MAAM,QAAQ,QAAQ,IAAI,IAAI,MAAM;CACpC,OAAO,GAAG,UAAU,OAAO,KAAK;AAClC;;AAGA,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EAAC;EAAO;EAAM;CAAqB;CAC5C,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,aACE;CACF,WAAW;CACX,SAAS,CAAC,CAAC;CACX,UAAU,CAAC,YAAY,UAAU;CACjC;CACA;CACA;CACA;AACF"}
package/dist/cz/rc.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ParsedPersonId, ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ParsedPersonId, ValidateResult } from "../types.js";
2
2
 
3
3
  //#region src/cz/rc.d.ts
4
4
  declare const compact: (value: string) => string;
@@ -15,7 +15,7 @@ declare const parse: (value: string) => ParsedPersonId | null;
15
15
  */
16
16
  declare const generate: () => string;
17
17
  /** Czech/Slovak Birth Number. */
18
- declare const rc: Validator<ParsedPersonId>;
18
+ declare const rc: CountryValidator<"CZ", ParsedPersonId>;
19
19
  //#endregion
20
20
  export { compact, rc as default, format, generate, parse, validate };
21
21
  //# sourceMappingURL=rc.d.ts.map
package/dist/cz/rc.js CHANGED
@@ -1,34 +1,9 @@
1
1
  import { clean } from "../_util/clean.js";
2
+ import { isValidDate } from "../_util/date.js";
2
3
  import { randomInt } from "../_util/generate.js";
3
4
  import { err } from "../_util/result.js";
4
5
  import { isdigits } from "../_util/strings.js";
5
- import { isValidDate } from "../_util/date.js";
6
6
  //#region src/cz/rc.ts
7
- /**
8
- * RČ (Rodné číslo).
9
- *
10
- * Czech and Slovak national identifier (birth
11
- * number). 9 or 10 digits encoding date of birth
12
- * and gender. 10-digit numbers (post-1954) must
13
- * be divisible by 11.
14
- *
15
- * Women have 50 added to the month. For modern
16
- * 10-digit numbers, an additional +20 offset may
17
- * be used when the daily serial range is exhausted
18
- * (+70 for women).
19
- *
20
- * Canonical source:
21
- * - Czech Ministry of the Interior guidance on rodne
22
- * cislo, with the modern overflow-month rules
23
- *
24
- * We use this to keep the 9-digit historical form
25
- * valid while rejecting modern +20/+70 month offsets
26
- * on 9-digit numbers. Those overflow offsets are a
27
- * modern rule for 10-digit values.
28
- *
29
- * @see https://www.mvcr.cz/mvcren/docDetail.aspx?docid=21975362&doctype=ART
30
- * @see Law 133/2000 Sb.
31
- */
32
7
  const compact = (value) => clean(value, " /");
33
8
  const decodeMonth = (rawMonth, year, length) => {
34
9
  const candidates = length === 10 && year >= 2004 ? [
@@ -123,6 +98,7 @@ const rc = {
123
98
  "birth number"
124
99
  ],
125
100
  candidatePattern: "\\d{6}/\\d{3,4}",
101
+ scope: "country",
126
102
  country: "CZ",
127
103
  entityType: "person",
128
104
  description: "Czech/Slovak national identifier encoding birth date and gender",
package/dist/cz/rc.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"rc.js","names":[],"sources":["../../src/cz/rc.ts"],"sourcesContent":["/**\n * RČ (Rodné číslo).\n *\n * Czech and Slovak national identifier (birth\n * number). 9 or 10 digits encoding date of birth\n * and gender. 10-digit numbers (post-1954) must\n * be divisible by 11.\n *\n * Women have 50 added to the month. For modern\n * 10-digit numbers, an additional +20 offset may\n * be used when the daily serial range is exhausted\n * (+70 for women).\n *\n * Canonical source:\n * - Czech Ministry of the Interior guidance on rodne\n * cislo, with the modern overflow-month rules\n *\n * We use this to keep the 9-digit historical form\n * valid while rejecting modern +20/+70 month offsets\n * on 9-digit numbers. Those overflow offsets are a\n * modern rule for 10-digit values.\n *\n * @see https://www.mvcr.cz/mvcren/docDetail.aspx?docid=21975362&doctype=ART\n * @see Law 133/2000 Sb.\n */\n\nimport { clean } from \"#util/clean\";\nimport { isValidDate } from \"#util/date\";\nimport { randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type {\n ParsedPersonId,\n ValidateResult,\n Validator,\n} from \"../types\";\n\nconst compact = (value: string): string =>\n clean(value, \" /\");\n\nconst decodeMonth = (\n rawMonth: number,\n year: number,\n length: number,\n): number | null => {\n const candidates =\n length === 10 && year >= 2004\n ? [0, 50, 20, 70]\n : [0, 50];\n for (const offset of candidates) {\n const month = rawMonth - offset;\n if (month >= 1 && month <= 12) {\n return month;\n }\n }\n return null;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 9 && v.length !== 10) {\n return err(\n \"INVALID_LENGTH\",\n \"Birth number must be 9 or 10 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Birth number must contain only digits\",\n );\n }\n\n const yy = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const dd = Number(v.slice(4, 6));\n\n // Resolve full year\n let year = yy + 1900;\n if (v.length === 9) {\n // 9-digit: pre-1954 only\n if (year >= 1980) year -= 100;\n if (year > 1953) {\n return err(\n \"INVALID_COMPONENT\",\n \"9-digit birth numbers are pre-1954 only\",\n );\n }\n } else {\n // 10-digit: if year < 1954, it's 2000s\n if (year < 1954) year += 100;\n }\n\n const month = decodeMonth(mm, year, v.length);\n if (month === null) {\n return err(\n \"INVALID_COMPONENT\",\n \"Birth number contains an invalid month\",\n );\n }\n\n if (dd < 1 || dd > 31) {\n return err(\n \"INVALID_COMPONENT\",\n \"Birth number contains an invalid day\",\n );\n }\n\n // Validate the actual date\n if (!isValidDate(year, month, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Birth number contains an invalid date\",\n );\n }\n\n // 10-digit: check digit is first 9 digits\n // mod 11 mod 10\n if (v.length === 10) {\n const front = Number(v.slice(0, 9));\n const check = (front % 11) % 10;\n if (String(check) !== v[9]) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Birth number is not divisible by 11\",\n );\n }\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n return `${v.slice(0, 6)}/${v.slice(6)}`;\n};\n\n/**\n * Extract birth date and gender from a birth number.\n * Returns null if the value is not valid.\n */\nconst parse = (value: string): ParsedPersonId | null => {\n const result = validate(value);\n if (!result.valid) return null;\n\n const v = result.compact;\n const yy = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const dd = Number(v.slice(4, 6));\n\n const gender = mm >= 50 ? \"female\" : \"male\";\n let year = yy + 1900;\n if (v.length === 10 && year < 1954) year += 100;\n if (v.length === 9 && year >= 1980) year -= 100;\n\n const month = decodeMonth(mm, year, v.length);\n if (month === null) {\n return null;\n }\n\n return {\n birthDate: new Date(year, month - 1, dd),\n gender,\n };\n};\n\n/**\n * Generate a random valid 10-digit birth number.\n * Uses a random date between 1954 and 2024.\n */\nconst generate = (): string => {\n const year = randomInt(1954, 2024);\n const month = randomInt(1, 12);\n const day = randomInt(1, 28);\n const isFemale = Math.random() < 0.5;\n const mm = isFemale ? month + 50 : month;\n\n const yy = String(year % 100).padStart(2, \"0\");\n const mmStr = String(mm).padStart(2, \"0\");\n const dd = String(day).padStart(2, \"0\");\n\n const datePart = `${yy}${mmStr}${dd}`;\n for (let seq = 0; seq < 1000; seq++) {\n const seqStr = String(seq).padStart(3, \"0\");\n const front = `${datePart}${seqStr}`;\n const num = Number(front);\n const check = (num % 11) % 10;\n const result = `${front}${String(check)}`;\n if (validate(result).valid) {\n return result;\n }\n }\n\n throw new Error(\"Failed to generate valid birth number\");\n};\n\n/** Czech/Slovak Birth Number. */\nconst rc: Validator<ParsedPersonId> = {\n name: \"Czech Birth Number\",\n localName: \"Rodné číslo\",\n abbreviation: \"RČ\",\n aliases: [\"rodné číslo\", \"RČ\", \"birth number\"] as const,\n candidatePattern: \"\\\\d{6}/\\\\d{3,4}\",\n country: \"CZ\",\n entityType: \"person\",\n description:\n \"Czech/Slovak national identifier encoding birth date and gender\",\n sourceUrl:\n \"https://www.mvcr.cz/mvcren/docDetail.aspx?docid=21975362&doctype=ART\",\n lengths: [9, 10] as const,\n examples: [\"7103192745\"] as const,\n compact,\n format,\n parse,\n validate,\n generate,\n};\n\nexport default rc;\nexport { compact, format, generate, parse, validate };\n"],"mappings":"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"}
1
+ {"version":3,"file":"rc.js","names":[],"sources":["../../src/cz/rc.ts"],"sourcesContent":["/**\n * RČ (Rodné číslo).\n *\n * Czech and Slovak national identifier (birth\n * number). 9 or 10 digits encoding date of birth\n * and gender. 10-digit numbers (post-1954) must\n * be divisible by 11.\n *\n * Women have 50 added to the month. For modern\n * 10-digit numbers, an additional +20 offset may\n * be used when the daily serial range is exhausted\n * (+70 for women).\n *\n * Canonical source:\n * - Czech Ministry of the Interior guidance on rodne\n * cislo, with the modern overflow-month rules\n *\n * We use this to keep the 9-digit historical form\n * valid while rejecting modern +20/+70 month offsets\n * on 9-digit numbers. Those overflow offsets are a\n * modern rule for 10-digit values.\n *\n * @see https://www.mvcr.cz/mvcren/docDetail.aspx?docid=21975362&doctype=ART\n * @see Law 133/2000 Sb.\n */\n\nimport type {\n ParsedPersonId,\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport { isValidDate } from \"#util/date\";\nimport { randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst compact = (value: string): string =>\n clean(value, \" /\");\n\nconst decodeMonth = (\n rawMonth: number,\n year: number,\n length: number,\n): number | null => {\n const candidates =\n length === 10 && year >= 2004\n ? [0, 50, 20, 70]\n : [0, 50];\n for (const offset of candidates) {\n const month = rawMonth - offset;\n if (month >= 1 && month <= 12) {\n return month;\n }\n }\n return null;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 9 && v.length !== 10) {\n return err(\n \"INVALID_LENGTH\",\n \"Birth number must be 9 or 10 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Birth number must contain only digits\",\n );\n }\n\n const yy = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const dd = Number(v.slice(4, 6));\n\n // Resolve full year\n let year = yy + 1900;\n if (v.length === 9) {\n // 9-digit: pre-1954 only\n if (year >= 1980) year -= 100;\n if (year > 1953) {\n return err(\n \"INVALID_COMPONENT\",\n \"9-digit birth numbers are pre-1954 only\",\n );\n }\n } else {\n // 10-digit: if year < 1954, it's 2000s\n if (year < 1954) year += 100;\n }\n\n const month = decodeMonth(mm, year, v.length);\n if (month === null) {\n return err(\n \"INVALID_COMPONENT\",\n \"Birth number contains an invalid month\",\n );\n }\n\n if (dd < 1 || dd > 31) {\n return err(\n \"INVALID_COMPONENT\",\n \"Birth number contains an invalid day\",\n );\n }\n\n // Validate the actual date\n if (!isValidDate(year, month, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Birth number contains an invalid date\",\n );\n }\n\n // 10-digit: check digit is first 9 digits\n // mod 11 mod 10\n if (v.length === 10) {\n const front = Number(v.slice(0, 9));\n const check = (front % 11) % 10;\n if (String(check) !== v[9]) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Birth number is not divisible by 11\",\n );\n }\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n return `${v.slice(0, 6)}/${v.slice(6)}`;\n};\n\n/**\n * Extract birth date and gender from a birth number.\n * Returns null if the value is not valid.\n */\nconst parse = (value: string): ParsedPersonId | null => {\n const result = validate(value);\n if (!result.valid) return null;\n\n const v = result.compact;\n const yy = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const dd = Number(v.slice(4, 6));\n\n const gender = mm >= 50 ? \"female\" : \"male\";\n let year = yy + 1900;\n if (v.length === 10 && year < 1954) year += 100;\n if (v.length === 9 && year >= 1980) year -= 100;\n\n const month = decodeMonth(mm, year, v.length);\n if (month === null) {\n return null;\n }\n\n return {\n birthDate: new Date(year, month - 1, dd),\n gender,\n };\n};\n\n/**\n * Generate a random valid 10-digit birth number.\n * Uses a random date between 1954 and 2024.\n */\nconst generate = (): string => {\n const year = randomInt(1954, 2024);\n const month = randomInt(1, 12);\n const day = randomInt(1, 28);\n const isFemale = Math.random() < 0.5;\n const mm = isFemale ? month + 50 : month;\n\n const yy = String(year % 100).padStart(2, \"0\");\n const mmStr = String(mm).padStart(2, \"0\");\n const dd = String(day).padStart(2, \"0\");\n\n const datePart = `${yy}${mmStr}${dd}`;\n for (let seq = 0; seq < 1000; seq++) {\n const seqStr = String(seq).padStart(3, \"0\");\n const front = `${datePart}${seqStr}`;\n const num = Number(front);\n const check = (num % 11) % 10;\n const result = `${front}${String(check)}`;\n if (validate(result).valid) {\n return result;\n }\n }\n\n throw new Error(\"Failed to generate valid birth number\");\n};\n\n/** Czech/Slovak Birth Number. */\nconst rc: CountryValidator<\"CZ\", ParsedPersonId> = {\n name: \"Czech Birth Number\",\n localName: \"Rodné číslo\",\n abbreviation: \"RČ\",\n aliases: [\"rodné číslo\", \"RČ\", \"birth number\"] as const,\n candidatePattern: \"\\\\d{6}/\\\\d{3,4}\",\n scope: \"country\",\n country: \"CZ\",\n entityType: \"person\",\n description:\n \"Czech/Slovak national identifier encoding birth date and gender\",\n sourceUrl:\n \"https://www.mvcr.cz/mvcren/docDetail.aspx?docid=21975362&doctype=ART\",\n lengths: [9, 10] as const,\n examples: [\"7103192745\"] as const,\n compact,\n format,\n parse,\n validate,\n generate,\n};\n\nexport default rc;\nexport { compact, format, generate, parse, validate };\n"],"mappings":"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"}
@@ -1,8 +1,25 @@
1
- import { ValidateResult, Validator } from "../types.js";
1
+ import { CountryValidator, ValidateResult } from "../types.js";
2
2
 
3
3
  //#region src/de/handelsreg.d.ts
4
4
  /** Generate a random valid Handelsregisternummer. */
5
5
  declare const generate: () => string;
6
+ /**
7
+ * Handelsregisternummer (German Company Register Number).
8
+ *
9
+ * German commercial register number assigned by the
10
+ * local court (Amtsgericht). Format: register type
11
+ * (HRA, HRB, GnR, PR, VR) + number.
12
+ *
13
+ * HRA = Handelsregister Abteilung A (partnerships,
14
+ * sole proprietors). HRB = Abteilung B (corporations).
15
+ * GnR = Genossenschaftsregister.
16
+ * PR = Partnerschaftsregister.
17
+ * VR = Vereinsregister.
18
+ *
19
+ * No check digit; validation is structural only.
20
+ *
21
+ * @see https://de.wikipedia.org/wiki/Handelsregister_(Deutschland)
22
+ */
6
23
  /**
7
24
  * Strip separators and normalize to canonical form.
8
25
  * Accepts "HRB 12345", "HRB12345", "hrb 12345".
@@ -11,7 +28,7 @@ declare const compact: (value: string) => string;
11
28
  declare const validate: (value: string) => ValidateResult;
12
29
  declare const format: (value: string) => string;
13
30
  /** German Company Register Number. */
14
- declare const handelsreg: Validator;
31
+ declare const handelsreg: CountryValidator<"DE">;
15
32
  //#endregion
16
33
  export { compact, handelsreg as default, format, generate, validate };
17
34
  //# sourceMappingURL=handelsreg.d.ts.map
@@ -2,23 +2,6 @@ import { clean } from "../_util/clean.js";
2
2
  import { randomDigits, randomPick } from "../_util/generate.js";
3
3
  import { err } from "../_util/result.js";
4
4
  //#region src/de/handelsreg.ts
5
- /**
6
- * Handelsregisternummer (German Company Register Number).
7
- *
8
- * German commercial register number assigned by the
9
- * local court (Amtsgericht). Format: register type
10
- * (HRA, HRB, GnR, PR, VR) + number.
11
- *
12
- * HRA = Handelsregister Abteilung A (partnerships,
13
- * sole proprietors). HRB = Abteilung B (corporations).
14
- * GnR = Genossenschaftsregister.
15
- * PR = Partnerschaftsregister.
16
- * VR = Vereinsregister.
17
- *
18
- * No check digit; validation is structural only.
19
- *
20
- * @see https://de.wikipedia.org/wiki/Handelsregister_(Deutschland)
21
- */
22
5
  const GENERATE_TYPES = [
23
6
  "HRA",
24
7
  "HRB",
@@ -71,6 +54,7 @@ const handelsreg = {
71
54
  "HRA"
72
55
  ],
73
56
  candidatePattern: "(?:HRA|HRB|GnR|PR|VR)\\s*\\d{1,7}",
57
+ scope: "country",
74
58
  country: "DE",
75
59
  entityType: "company",
76
60
  sourceUrl: "https://de.wikipedia.org/wiki/Handelsregister_(Deutschland)",
@@ -1 +1 @@
1
- {"version":3,"file":"handelsreg.js","names":[],"sources":["../../src/de/handelsreg.ts"],"sourcesContent":["const GENERATE_TYPES = [\n \"HRA\",\n \"HRB\",\n \"GNR\",\n \"PR\",\n \"VR\",\n] as const;\n\n/** Generate a random valid Handelsregisternummer. */\nconst generate = (): string => {\n const type = randomPick(GENERATE_TYPES);\n const number = randomDigits(5);\n return `${type} ${number}`;\n};\n\n/**\n * Handelsregisternummer (German Company Register Number).\n *\n * German commercial register number assigned by the\n * local court (Amtsgericht). Format: register type\n * (HRA, HRB, GnR, PR, VR) + number.\n *\n * HRA = Handelsregister Abteilung A (partnerships,\n * sole proprietors). HRB = Abteilung B (corporations).\n * GnR = Genossenschaftsregister.\n * PR = Partnerschaftsregister.\n * VR = Vereinsregister.\n *\n * No check digit; validation is structural only.\n *\n * @see https://de.wikipedia.org/wiki/Handelsregister_(Deutschland)\n */\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomPick } from \"#util/generate\";\nimport { err } from \"#util/result\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst REGISTER_TYPES = new Set([\n \"HRA\",\n \"HRB\",\n \"GNR\",\n \"PR\",\n \"VR\",\n]);\n\n/**\n * Strip separators and normalize to canonical form.\n * Accepts \"HRB 12345\", \"HRB12345\", \"hrb 12345\".\n */\nconst compact = (value: string): string => {\n const v = clean(value, \" -.\").trim().toUpperCase();\n const match = v.match(/^(HRA|HRB|GNR|PR|VR)(\\d{1,7})$/);\n if (!match) return v;\n return `${match[1]} ${match[2]}`;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = clean(value, \" -.\").trim().toUpperCase();\n\n const match = v.match(/^([A-Z]{2,3})(\\d{1,7})$/);\n if (!match) {\n return err(\n \"INVALID_FORMAT\",\n \"Handelsregisternummer must be a register type \" +\n \"(HRA, HRB, GnR, PR, VR) followed by \" +\n \"1-7 digits\",\n );\n }\n\n // SAFETY: both capture groups are required, so a\n // successful match always populates [1] and [2].\n // eslint-disable-next-line no-non-null-assertion\n const type = match[1]!;\n // eslint-disable-next-line no-non-null-assertion\n const number = match[2]!;\n\n if (!REGISTER_TYPES.has(type)) {\n return err(\n \"INVALID_COMPONENT\",\n `Unrecognised register type \"${type}\"`,\n );\n }\n\n return {\n valid: true,\n compact: `${type} ${number}`,\n };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** German Company Register Number. */\nconst handelsreg: Validator = {\n name: \"German Company Register Number\",\n localName: \"Handelsregisternummer\",\n abbreviation: \"HReg\",\n aliases: [\n \"Handelsregisternummer\",\n \"Handelsregister\",\n \"HRB\",\n \"HRA\",\n ] as const,\n candidatePattern: \"(?:HRA|HRB|GnR|PR|VR)\\\\s*\\\\d{1,7}\",\n country: \"DE\",\n entityType: \"company\",\n sourceUrl:\n \"https://de.wikipedia.org/wiki/Handelsregister_(Deutschland)\",\n examples: [\"HRB 12345\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default handelsreg;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA,MAAM,iBAAiB;CACrB;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAM,iBAAyB;AAG7B,QAAO,GAFM,WAAW,eAAe,CAExB,GADA,aAAa,EAAE;;AA4BhC,MAAM,iBAAiB,IAAI,IAAI;CAC7B;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;AAMF,MAAM,WAAW,UAA0B;CACzC,MAAM,IAAI,MAAM,OAAO,MAAM,CAAC,MAAM,CAAC,aAAa;CAClD,MAAM,QAAQ,EAAE,MAAM,iCAAiC;AACvD,KAAI,CAAC,MAAO,QAAO;AACnB,QAAO,GAAG,MAAM,GAAG,GAAG,MAAM;;AAG9B,MAAM,YAAY,UAAkC;CAGlD,MAAM,QAFI,MAAM,OAAO,MAAM,CAAC,MAAM,CAAC,aAAa,CAElC,MAAM,0BAA0B;AAChD,KAAI,CAAC,MACH,QAAO,IACL,kBACA,+FAGD;CAMH,MAAM,OAAO,MAAM;CAEnB,MAAM,SAAS,MAAM;AAErB,KAAI,CAAC,eAAe,IAAI,KAAK,CAC3B,QAAO,IACL,qBACA,+BAA+B,KAAK,GACrC;AAGH,QAAO;EACL,OAAO;EACP,SAAS,GAAG,KAAK,GAAG;EACrB;;AAGH,MAAM,UAAU,UAA0B,QAAQ,MAAM;;AAGxD,MAAM,aAAwB;CAC5B,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;EACA;EACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WACE;CACF,UAAU,CAAC,YAAY;CACvB;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"handelsreg.js","names":[],"sources":["../../src/de/handelsreg.ts"],"sourcesContent":["const GENERATE_TYPES = [\n \"HRA\",\n \"HRB\",\n \"GNR\",\n \"PR\",\n \"VR\",\n] as const;\n\n/** Generate a random valid Handelsregisternummer. */\nconst generate = (): string => {\n const type = randomPick(GENERATE_TYPES);\n const number = randomDigits(5);\n return `${type} ${number}`;\n};\n\n/**\n * Handelsregisternummer (German Company Register Number).\n *\n * German commercial register number assigned by the\n * local court (Amtsgericht). Format: register type\n * (HRA, HRB, GnR, PR, VR) + number.\n *\n * HRA = Handelsregister Abteilung A (partnerships,\n * sole proprietors). HRB = Abteilung B (corporations).\n * GnR = Genossenschaftsregister.\n * PR = Partnerschaftsregister.\n * VR = Vereinsregister.\n *\n * No check digit; validation is structural only.\n *\n * @see https://de.wikipedia.org/wiki/Handelsregister_(Deutschland)\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomPick } from \"#util/generate\";\nimport { err } from \"#util/result\";\n\nconst REGISTER_TYPES = new Set([\n \"HRA\",\n \"HRB\",\n \"GNR\",\n \"PR\",\n \"VR\",\n]);\n\n/**\n * Strip separators and normalize to canonical form.\n * Accepts \"HRB 12345\", \"HRB12345\", \"hrb 12345\".\n */\nconst compact = (value: string): string => {\n const v = clean(value, \" -.\").trim().toUpperCase();\n const match = v.match(/^(HRA|HRB|GNR|PR|VR)(\\d{1,7})$/);\n if (!match) return v;\n return `${match[1]} ${match[2]}`;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = clean(value, \" -.\").trim().toUpperCase();\n\n const match = v.match(/^([A-Z]{2,3})(\\d{1,7})$/);\n if (!match) {\n return err(\n \"INVALID_FORMAT\",\n \"Handelsregisternummer must be a register type \" +\n \"(HRA, HRB, GnR, PR, VR) followed by \" +\n \"1-7 digits\",\n );\n }\n\n // SAFETY: both capture groups are required, so a\n // successful match always populates [1] and [2].\n // eslint-disable-next-line no-non-null-assertion\n const type = match[1]!;\n // eslint-disable-next-line no-non-null-assertion\n const number = match[2]!;\n\n if (!REGISTER_TYPES.has(type)) {\n return err(\n \"INVALID_COMPONENT\",\n `Unrecognised register type \"${type}\"`,\n );\n }\n\n return {\n valid: true,\n compact: `${type} ${number}`,\n };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** German Company Register Number. */\nconst handelsreg: CountryValidator<\"DE\"> = {\n name: \"German Company Register Number\",\n localName: \"Handelsregisternummer\",\n abbreviation: \"HReg\",\n aliases: [\n \"Handelsregisternummer\",\n \"Handelsregister\",\n \"HRB\",\n \"HRA\",\n ] as const,\n candidatePattern: \"(?:HRA|HRB|GnR|PR|VR)\\\\s*\\\\d{1,7}\",\n scope: \"country\",\n country: \"DE\",\n entityType: \"company\",\n sourceUrl:\n \"https://de.wikipedia.org/wiki/Handelsregister_(Deutschland)\",\n examples: [\"HRB 12345\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default handelsreg;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;AAAA,MAAM,iBAAiB;CACrB;CACA;CACA;CACA;CACA;AACF;;AAGA,MAAM,iBAAyB;CAG7B,OAAO,GAFM,WAAW,cAEX,EAAE,GADA,aAAa,CACL;AACzB;AA6BA,MAAM,iBAAiB,IAAI,IAAI;CAC7B;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;AAMD,MAAM,WAAW,UAA0B;CACzC,MAAM,IAAI,MAAM,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY;CACjD,MAAM,QAAQ,EAAE,MAAM,gCAAgC;CACtD,IAAI,CAAC,OAAO,OAAO;CACnB,OAAO,GAAG,MAAM,GAAG,GAAG,MAAM;AAC9B;AAEA,MAAM,YAAY,UAAkC;CAGlD,MAAM,QAFI,MAAM,OAAO,KAAK,EAAE,KAAK,EAAE,YAEvB,EAAE,MAAM,yBAAyB;CAC/C,IAAI,CAAC,OACH,OAAO,IACL,kBACA,8FAGF;CAMF,MAAM,OAAO,MAAM;CAEnB,MAAM,SAAS,MAAM;CAErB,IAAI,CAAC,eAAe,IAAI,IAAI,GAC1B,OAAO,IACL,qBACA,+BAA+B,KAAK,EACtC;CAGF,OAAO;EACL,OAAO;EACP,SAAS,GAAG,KAAK,GAAG;CACtB;AACF;AAEA,MAAM,UAAU,UAA0B,QAAQ,KAAK;;AAGvD,MAAM,aAAqC;CACzC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;EACA;CACF;CACA,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WACE;CACF,UAAU,CAAC,WAAW;CACtB;CACA;CACA;CACA;AACF"}
package/dist/de/idnr.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/de/idnr.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 German IdNr. */
8
8
  declare const generate: () => string;
9
9
  /** German Personal Tax ID. */
10
- declare const idnr: Validator;
10
+ declare const idnr: CountryValidator<"DE">;
11
11
  //#endregion
12
12
  export { compact, idnr as default, format, generate, validate };
13
13
  //# sourceMappingURL=idnr.d.ts.map
package/dist/de/idnr.js CHANGED
@@ -1,20 +1,9 @@
1
+ import { mod1110checkDigit, mod1110validate } from "../_checksums/mod1110.js";
1
2
  import { clean } from "../_util/clean.js";
2
3
  import { randomInt } from "../_util/generate.js";
3
4
  import { err } from "../_util/result.js";
4
5
  import { isdigits } from "../_util/strings.js";
5
- import { mod1110checkDigit, mod1110validate } from "../_checksums/mod1110.js";
6
6
  //#region src/de/idnr.ts
7
- /**
8
- * IdNr (Steuerliche Identifikationsnummer).
9
- *
10
- * German personal tax identification number.
11
- * 11 digits; the last digit is a check digit
12
- * (ISO 7064 Mod 11,10). Exactly one digit
13
- * appears twice or three times; the rest are
14
- * unique. The first digit cannot be 0.
15
- *
16
- * @see https://www.bzst.de/DE/Privatpersonen/SteuerlicheIdentifikationsnummer/steuerlicheidentifikationsnummer_node.html
17
- */
18
7
  const compact = (value) => clean(value, " -/");
19
8
  /**
20
9
  * Validate digit distribution: in the first 10
@@ -87,6 +76,7 @@ const idnr = {
87
76
  "Steuer-ID"
88
77
  ],
89
78
  candidatePattern: "\\d{2}\\s?\\d{3}\\s?\\d{3}\\s?\\d{3}",
79
+ scope: "country",
90
80
  country: "DE",
91
81
  entityType: "person",
92
82
  sourceUrl: "https://www.bzst.de/DE/Privatpersonen/SteuerlicheIdentifikationsnummer/steuerlicheidentifikationsnummer_node.html",
@@ -1 +1 @@
1
- {"version":3,"file":"idnr.js","names":[],"sources":["../../src/de/idnr.ts"],"sourcesContent":["/**\n * IdNr (Steuerliche Identifikationsnummer).\n *\n * German personal tax identification number.\n * 11 digits; the last digit is a check digit\n * (ISO 7064 Mod 11,10). Exactly one digit\n * appears twice or three times; the rest are\n * unique. The first digit cannot be 0.\n *\n * @see https://www.bzst.de/DE/Privatpersonen/SteuerlicheIdentifikationsnummer/steuerlicheidentifikationsnummer_node.html\n */\n\nimport {\n mod1110validate,\n mod1110checkDigit,\n} from \"#checksums/mod1110\";\nimport { clean } from \"#util/clean\";\nimport { randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst compact = (value: string): string =>\n clean(value, \" -/\");\n\n/**\n * Validate digit distribution: in the first 10\n * digits, exactly one digit appears 2 or 3\n * times; all others appear exactly once.\n */\nconst validDistribution = (value: string): boolean => {\n const counts = Array.from<number>({ length: 10 }).fill(0);\n for (let i = 0; i < 10; i++) {\n const idx = Number(value.charAt(i));\n const prev = counts[idx];\n if (prev !== undefined) counts[idx] = prev + 1;\n }\n let doubles = 0;\n let triples = 0;\n for (const c of counts) {\n if (c === 2) doubles++;\n if (c === 3) triples++;\n if (c > 3) return false;\n }\n // Exactly one digit repeated (2 or 3 times)\n return (\n (doubles === 1 && triples === 0) ||\n (doubles === 0 && triples === 1)\n );\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 11) {\n return err(\n \"INVALID_LENGTH\",\n \"German IdNr must be 11 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"German IdNr must contain only digits\",\n );\n }\n if (v[0] === \"0\") {\n return err(\n \"INVALID_COMPONENT\",\n \"German IdNr cannot start with 0\",\n );\n }\n if (!validDistribution(v)) {\n return err(\n \"INVALID_COMPONENT\",\n \"German IdNr digit distribution invalid\",\n );\n }\n if (!mod1110validate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"German IdNr check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n return `${v.slice(0, 2)} ${v.slice(2, 5)} ${v.slice(5, 8)} ${v.slice(8)}`;\n};\n\n/** Generate a random valid German IdNr. */\nconst generate = (): string => {\n for (;;) {\n const repeated = randomInt(0, 9);\n const times = Math.random() < 0.8 ? 2 : 3;\n const pool: number[] = [];\n for (let d = 0; d < 10; d++) {\n const count = d === repeated ? times : 1;\n for (let t = 0; t < count; t++) pool.push(d);\n }\n while (pool.length < 10) pool.push(randomInt(0, 9));\n for (let i = pool.length - 1; i > 0; i--) {\n const j = randomInt(0, i);\n // SAFETY: i and j are valid indices of `pool`\n // (i > 0, j ∈ [0, i]).\n // eslint-disable-next-line no-non-null-assertion\n [pool[i], pool[j]] = [pool[j]!, pool[i]!];\n }\n if (pool[0] === 0) continue;\n const payload = pool.slice(0, 10).join(\"\");\n if (!validDistribution(payload)) continue;\n const check = mod1110checkDigit(payload);\n const c = payload + String(check);\n if (validate(c).valid) return c;\n }\n};\n\n/** German Personal Tax ID. */\nconst idnr: Validator = {\n name: \"German Tax ID\",\n localName: \"Steuerliche Identifikationsnummer\",\n abbreviation: \"IdNr\",\n aliases: [\n \"Steuerliche Identifikationsnummer\",\n \"IdNr\",\n \"Steuer-ID\",\n ] as const,\n candidatePattern: \"\\\\d{2}\\\\s?\\\\d{3}\\\\s?\\\\d{3}\\\\s?\\\\d{3}\",\n country: \"DE\",\n entityType: \"person\",\n sourceUrl:\n \"https://www.bzst.de/DE/Privatpersonen/SteuerlicheIdentifikationsnummer/steuerlicheidentifikationsnummer_node.html\",\n examples: [\"36574261809\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default idnr;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;;;;;;;;;;;AAuBA,MAAM,WAAW,UACf,MAAM,OAAO,MAAM;;;;;;AAOrB,MAAM,qBAAqB,UAA2B;CACpD,MAAM,SAAS,MAAM,KAAa,EAAE,QAAQ,IAAI,CAAC,CAAC,KAAK,EAAE;AACzD,MAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;EAC3B,MAAM,MAAM,OAAO,MAAM,OAAO,EAAE,CAAC;EACnC,MAAM,OAAO,OAAO;AACpB,MAAI,SAAS,KAAA,EAAW,QAAO,OAAO,OAAO;;CAE/C,IAAI,UAAU;CACd,IAAI,UAAU;AACd,MAAK,MAAM,KAAK,QAAQ;AACtB,MAAI,MAAM,EAAG;AACb,MAAI,MAAM,EAAG;AACb,MAAI,IAAI,EAAG,QAAO;;AAGpB,QACG,YAAY,KAAK,YAAY,KAC7B,YAAY,KAAK,YAAY;;AAIlC,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,GACf,QAAO,IACL,kBACA,gCACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,uCACD;AAEH,KAAI,EAAE,OAAO,IACX,QAAO,IACL,qBACA,kCACD;AAEH,KAAI,CAAC,kBAAkB,EAAE,CACvB,QAAO,IACL,qBACA,yCACD;AAEH,KAAI,CAAC,gBAAgB,EAAE,CACrB,QAAO,IACL,oBACA,mCACD;AAEH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,MAAM;AACxB,QAAO,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE;;;AAIzE,MAAM,iBAAyB;AAC7B,UAAS;EACP,MAAM,WAAW,UAAU,GAAG,EAAE;EAChC,MAAM,QAAQ,KAAK,QAAQ,GAAG,KAAM,IAAI;EACxC,MAAM,OAAiB,EAAE;AACzB,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;GAC3B,MAAM,QAAQ,MAAM,WAAW,QAAQ;AACvC,QAAK,IAAI,IAAI,GAAG,IAAI,OAAO,IAAK,MAAK,KAAK,EAAE;;AAE9C,SAAO,KAAK,SAAS,GAAI,MAAK,KAAK,UAAU,GAAG,EAAE,CAAC;AACnD,OAAK,IAAI,IAAI,KAAK,SAAS,GAAG,IAAI,GAAG,KAAK;GACxC,MAAM,IAAI,UAAU,GAAG,EAAE;AAIzB,IAAC,KAAK,IAAI,KAAK,MAAM,CAAC,KAAK,IAAK,KAAK,GAAI;;AAE3C,MAAI,KAAK,OAAO,EAAG;EACnB,MAAM,UAAU,KAAK,MAAM,GAAG,GAAG,CAAC,KAAK,GAAG;AAC1C,MAAI,CAAC,kBAAkB,QAAQ,CAAE;EACjC,MAAM,QAAQ,kBAAkB,QAAQ;EACxC,MAAM,IAAI,UAAU,OAAO,MAAM;AACjC,MAAI,SAAS,EAAE,CAAC,MAAO,QAAO;;;;AAKlC,MAAM,OAAkB;CACtB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;EACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,WACE;CACF,UAAU,CAAC,cAAc;CACzB;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"idnr.js","names":[],"sources":["../../src/de/idnr.ts"],"sourcesContent":["/**\n * IdNr (Steuerliche Identifikationsnummer).\n *\n * German personal tax identification number.\n * 11 digits; the last digit is a check digit\n * (ISO 7064 Mod 11,10). Exactly one digit\n * appears twice or three times; the rest are\n * unique. The first digit cannot be 0.\n *\n * @see https://www.bzst.de/DE/Privatpersonen/SteuerlicheIdentifikationsnummer/steuerlicheidentifikationsnummer_node.html\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport {\n mod1110validate,\n mod1110checkDigit,\n} from \"#checksums/mod1110\";\nimport { clean } from \"#util/clean\";\nimport { randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst compact = (value: string): string =>\n clean(value, \" -/\");\n\n/**\n * Validate digit distribution: in the first 10\n * digits, exactly one digit appears 2 or 3\n * times; all others appear exactly once.\n */\nconst validDistribution = (value: string): boolean => {\n const counts = Array.from<number>({ length: 10 }).fill(0);\n for (let i = 0; i < 10; i++) {\n const idx = Number(value.charAt(i));\n const prev = counts[idx];\n if (prev !== undefined) counts[idx] = prev + 1;\n }\n let doubles = 0;\n let triples = 0;\n for (const c of counts) {\n if (c === 2) doubles++;\n if (c === 3) triples++;\n if (c > 3) return false;\n }\n // Exactly one digit repeated (2 or 3 times)\n return (\n (doubles === 1 && triples === 0) ||\n (doubles === 0 && triples === 1)\n );\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 11) {\n return err(\n \"INVALID_LENGTH\",\n \"German IdNr must be 11 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"German IdNr must contain only digits\",\n );\n }\n if (v[0] === \"0\") {\n return err(\n \"INVALID_COMPONENT\",\n \"German IdNr cannot start with 0\",\n );\n }\n if (!validDistribution(v)) {\n return err(\n \"INVALID_COMPONENT\",\n \"German IdNr digit distribution invalid\",\n );\n }\n if (!mod1110validate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"German IdNr check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n return `${v.slice(0, 2)} ${v.slice(2, 5)} ${v.slice(5, 8)} ${v.slice(8)}`;\n};\n\n/** Generate a random valid German IdNr. */\nconst generate = (): string => {\n for (;;) {\n const repeated = randomInt(0, 9);\n const times = Math.random() < 0.8 ? 2 : 3;\n const pool: number[] = [];\n for (let d = 0; d < 10; d++) {\n const count = d === repeated ? times : 1;\n for (let t = 0; t < count; t++) pool.push(d);\n }\n while (pool.length < 10) pool.push(randomInt(0, 9));\n for (let i = pool.length - 1; i > 0; i--) {\n const j = randomInt(0, i);\n // SAFETY: i and j are valid indices of `pool`\n // (i > 0, j ∈ [0, i]).\n // eslint-disable-next-line no-non-null-assertion\n [pool[i], pool[j]] = [pool[j]!, pool[i]!];\n }\n if (pool[0] === 0) continue;\n const payload = pool.slice(0, 10).join(\"\");\n if (!validDistribution(payload)) continue;\n const check = mod1110checkDigit(payload);\n const c = payload + String(check);\n if (validate(c).valid) return c;\n }\n};\n\n/** German Personal Tax ID. */\nconst idnr: CountryValidator<\"DE\"> = {\n name: \"German Tax ID\",\n localName: \"Steuerliche Identifikationsnummer\",\n abbreviation: \"IdNr\",\n aliases: [\n \"Steuerliche Identifikationsnummer\",\n \"IdNr\",\n \"Steuer-ID\",\n ] as const,\n candidatePattern: \"\\\\d{2}\\\\s?\\\\d{3}\\\\s?\\\\d{3}\\\\s?\\\\d{3}\",\n scope: \"country\",\n country: \"DE\",\n entityType: \"person\",\n sourceUrl:\n \"https://www.bzst.de/DE/Privatpersonen/SteuerlicheIdentifikationsnummer/steuerlicheidentifikationsnummer_node.html\",\n examples: [\"36574261809\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default idnr;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AA0BA,MAAM,WAAW,UACf,MAAM,OAAO,KAAK;;;;;;AAOpB,MAAM,qBAAqB,UAA2B;CACpD,MAAM,SAAS,MAAM,KAAa,EAAE,QAAQ,GAAG,CAAC,EAAE,KAAK,CAAC;CACxD,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;EAC3B,MAAM,MAAM,OAAO,MAAM,OAAO,CAAC,CAAC;EAClC,MAAM,OAAO,OAAO;EACpB,IAAI,SAAS,KAAA,GAAW,OAAO,OAAO,OAAO;CAC/C;CACA,IAAI,UAAU;CACd,IAAI,UAAU;CACd,KAAK,MAAM,KAAK,QAAQ;EACtB,IAAI,MAAM,GAAG;EACb,IAAI,MAAM,GAAG;EACb,IAAI,IAAI,GAAG,OAAO;CACpB;CAEA,OACG,YAAY,KAAK,YAAY,KAC7B,YAAY,KAAK,YAAY;AAElC;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,IACf,OAAO,IACL,kBACA,+BACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,sCACF;CAEF,IAAI,EAAE,OAAO,KACX,OAAO,IACL,qBACA,iCACF;CAEF,IAAI,CAAC,kBAAkB,CAAC,GACtB,OAAO,IACL,qBACA,wCACF;CAEF,IAAI,CAAC,gBAAgB,CAAC,GACpB,OAAO,IACL,oBACA,kCACF;CAEF,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,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC;AACxE;;AAGA,MAAM,iBAAyB;CAC7B,SAAS;EACP,MAAM,WAAW,UAAU,GAAG,CAAC;EAC/B,MAAM,QAAQ,KAAK,OAAO,IAAI,KAAM,IAAI;EACxC,MAAM,OAAiB,CAAC;EACxB,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;GAC3B,MAAM,QAAQ,MAAM,WAAW,QAAQ;GACvC,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK,KAAK,KAAK,CAAC;EAC7C;EACA,OAAO,KAAK,SAAS,IAAI,KAAK,KAAK,UAAU,GAAG,CAAC,CAAC;EAClD,KAAK,IAAI,IAAI,KAAK,SAAS,GAAG,IAAI,GAAG,KAAK;GACxC,MAAM,IAAI,UAAU,GAAG,CAAC;GAIxB,CAAC,KAAK,IAAI,KAAK,MAAM,CAAC,KAAK,IAAK,KAAK,EAAG;EAC1C;EACA,IAAI,KAAK,OAAO,GAAG;EACnB,MAAM,UAAU,KAAK,MAAM,GAAG,EAAE,EAAE,KAAK,EAAE;EACzC,IAAI,CAAC,kBAAkB,OAAO,GAAG;EACjC,MAAM,QAAQ,kBAAkB,OAAO;EACvC,MAAM,IAAI,UAAU,OAAO,KAAK;EAChC,IAAI,SAAS,CAAC,EAAE,OAAO,OAAO;CAChC;AACF;;AAGA,MAAM,OAA+B;CACnC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;CACF;CACA,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WACE;CACF,UAAU,CAAC,aAAa;CACxB;CACA;CACA;CACA;AACF"}
package/dist/de/stnr.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/de/stnr.d.ts
4
4
  /**
@@ -6,6 +6,21 @@ import { ValidateResult, Validator } from "../types.js";
6
6
  * Uses Berlin regional format (FFBBBUUUUP, 10 digits).
7
7
  */
8
8
  declare const generate: () => string;
9
+ /**
10
+ * StNr (Steuernummer).
11
+ *
12
+ * German tax number assigned by the local tax office.
13
+ * Regional format: 10 or 11 digits. Unified federal
14
+ * format: 13 digits (prefixed with a 2–4 digit BUFA
15
+ * code). Structure varies by federal state.
16
+ *
17
+ * The number encodes: BUFA (Bundesfinanzamtsnummer),
18
+ * district code, serial number, and check digit. No
19
+ * algorithmic check digit validation is standardised
20
+ * across all states; validation is format-only.
21
+ *
22
+ * @see https://de.wikipedia.org/wiki/Steuernummer
23
+ */
9
24
  declare const compact: (value: string) => string;
10
25
  declare const validate: (value: string) => ValidateResult;
11
26
  /**
@@ -15,7 +30,7 @@ declare const validate: (value: string) => ValidateResult;
15
30
  */
16
31
  declare const format: (value: string) => string;
17
32
  /** German Tax Number (Steuernummer). */
18
- declare const stnr: Validator;
33
+ declare const stnr: CountryValidator<"DE">;
19
34
  //#endregion
20
35
  export { compact, stnr as default, format, generate, validate };
21
36
  //# sourceMappingURL=stnr.d.ts.map
package/dist/de/stnr.js CHANGED
@@ -4,21 +4,6 @@ import { err } from "../_util/result.js";
4
4
  import { isdigits } from "../_util/strings.js";
5
5
  //#region src/de/stnr.ts
6
6
  /**
7
- * StNr (Steuernummer).
8
- *
9
- * German tax number assigned by the local tax office.
10
- * Regional format: 10 or 11 digits. Unified federal
11
- * format: 13 digits (prefixed with a 2–4 digit BUFA
12
- * code). Structure varies by federal state.
13
- *
14
- * The number encodes: BUFA (Bundesfinanzamtsnummer),
15
- * district code, serial number, and check digit. No
16
- * algorithmic check digit validation is standardised
17
- * across all states; validation is format-only.
18
- *
19
- * @see https://de.wikipedia.org/wiki/Steuernummer
20
- */
21
- /**
22
7
  * Generate a random valid Steuernummer.
23
8
  * Uses Berlin regional format (FFBBBUUUUP, 10 digits).
24
9
  */
@@ -123,6 +108,7 @@ const stnr = {
123
108
  abbreviation: "StNr",
124
109
  aliases: ["Steuernummer", "St.Nr."],
125
110
  candidatePattern: "\\d{2,4}/\\d{3,4}/\\d{4,5}",
111
+ scope: "country",
126
112
  country: "DE",
127
113
  entityType: "any",
128
114
  description: "German tax number assigned by the local tax office, varies by federal state",
@@ -1 +1 @@
1
- {"version":3,"file":"stnr.js","names":[],"sources":["../../src/de/stnr.ts"],"sourcesContent":["/**\n * Generate a random valid Steuernummer.\n * Uses Berlin regional format (FFBBBUUUUP, 10 digits).\n */\nconst generate = (): string => {\n const ff = randomDigits(2);\n const bbb = randomDigits(3);\n const uuuu = randomDigits(4);\n const p = randomDigits(1);\n return `${ff}${bbb}${uuuu}${p}`;\n};\n\n/**\n * StNr (Steuernummer).\n *\n * German tax number assigned by the local tax office.\n * Regional format: 10 or 11 digits. Unified federal\n * format: 13 digits (prefixed with a 2–4 digit BUFA\n * code). Structure varies by federal state.\n *\n * The number encodes: BUFA (Bundesfinanzamtsnummer),\n * district code, serial number, and check digit. No\n * algorithmic check digit validation is standardised\n * across all states; validation is format-only.\n *\n * @see https://de.wikipedia.org/wiki/Steuernummer\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 * Format patterns per federal state.\n * [0] = regional format, [1] = unified (federal) format.\n *\n * Legend: F = finance office, B = district,\n * U = serial, P = check digit,\n * leading digits are literal.\n */\nconst STATES = {\n \"Baden-Württemberg\": [\"FFBBBUUUUP\", \"28FF0BBBUUUUP\"],\n Bayern: [\"FFFBBBUUUUP\", \"9FFF0BBBUUUUP\"],\n Berlin: [\"FFBBBUUUUP\", \"11FF0BBBUUUUP\"],\n Brandenburg: [\"0FFBBBUUUUP\", \"30FF0BBBUUUUP\"],\n Bremen: [\"FFBBBUUUUP\", \"24FF0BBBUUUUP\"],\n Hamburg: [\"FFBBBUUUUP\", \"22FF0BBBUUUUP\"],\n Hessen: [\"0FFBBBUUUUP\", \"26FF0BBBUUUUP\"],\n \"Mecklenburg-Vorpommern\": [\n \"0FFBBBUUUUP\",\n \"40FF0BBBUUUUP\",\n ],\n Niedersachsen: [\"FFBBBUUUUP\", \"23FF0BBBUUUUP\"],\n \"Nordrhein-Westfalen\": [\"FFFBBBBUUUP\", \"5FFF0BBBBUUUP\"],\n \"Rheinland-Pfalz\": [\"FFBBBUUUUP\", \"27FF0BBBUUUUP\"],\n Saarland: [\"0FFBBBUUUUP\", \"10FF0BBBUUUUP\"],\n Sachsen: [\"2FFBBBUUUUP\", \"32FF0BBBUUUUP\"],\n \"Sachsen-Anhalt\": [\"1FFBBBUUUUP\", \"31FF0BBBUUUUP\"],\n \"Schleswig-Holstein\": [\"FFBBBUUUUP\", \"21FF0BBBUUUUP\"],\n Thüringen: [\"1FFBBBUUUUP\", \"41FF0BBBUUUUP\"],\n} as const;\n\ntype StateName = keyof typeof STATES;\n\n/**\n * Convert a format pattern to a regex.\n * Literal digits match themselves; F/B/U match any\n * digit; P (check digit) matches any digit.\n */\nconst patternToRegex = (pattern: string): RegExp => {\n let re = \"^\";\n for (const ch of pattern) {\n if (ch >= \"0\" && ch <= \"9\") {\n re += ch;\n } else {\n re += \"\\\\d\";\n }\n }\n re += \"$\";\n return new RegExp(re);\n};\n\n/** Pre-compiled regexes for each state + format. */\nconst COMPILED: Array<{\n state: StateName;\n regional: RegExp;\n regionalFmt: string;\n federal: RegExp;\n federalFmt: string;\n}> = (\n Object.entries(STATES) as Array<\n [StateName, readonly [string, string]]\n >\n).map(([state, [regionalFmt, federalFmt]]) => ({\n state,\n regional: patternToRegex(regionalFmt),\n regionalFmt,\n federal: patternToRegex(federalFmt),\n federalFmt,\n}));\n\nconst compact = (value: string): string =>\n clean(value, \" -/.\");\n\nconst matchesAnyPattern = (v: string): boolean => {\n for (const { regional, federal } of COMPILED) {\n if (regional.test(v) || federal.test(v)) return true;\n }\n return false;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"German Steuernummer must contain only digits\",\n );\n }\n\n if (\n v.length !== 10 &&\n v.length !== 11 &&\n v.length !== 13\n ) {\n return err(\n \"INVALID_LENGTH\",\n \"German Steuernummer must be 10, 11, or 13 digits\",\n );\n }\n\n if (!matchesAnyPattern(v)) {\n return err(\n \"INVALID_COMPONENT\",\n \"German Steuernummer does not match any \" +\n \"known state format\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\n/**\n * Format with slashes at segment boundaries.\n * Uses the first matching state pattern to determine\n * segment positions.\n */\nconst format = (value: string): string => {\n const v = compact(value);\n\n for (const entry of COMPILED) {\n const pattern =\n v.length === 13 ? entry.federal : entry.regional;\n if (!pattern.test(v)) continue;\n\n const fmt =\n v.length === 13\n ? entry.federalFmt\n : entry.regionalFmt;\n\n // Group by consecutive runs of the same letter\n // category: literal digits, F, B, U, P\n const segments: string[] = [];\n let segStart = 0;\n // SAFETY: fmt is a non-empty literal from COMPILED.\n // eslint-disable-next-line no-non-null-assertion\n let prevCat = charCat(fmt[0]!);\n\n for (let i = 1; i < fmt.length; i++) {\n // SAFETY: i < fmt.length.\n // eslint-disable-next-line no-non-null-assertion\n const cat = charCat(fmt[i]!);\n if (cat !== prevCat) {\n segments.push(v.slice(segStart, i));\n segStart = i;\n prevCat = cat;\n }\n }\n segments.push(v.slice(segStart));\n\n return segments.join(\"/\");\n }\n\n return v;\n};\n\nconst charCat = (ch: string): string => {\n if (ch >= \"0\" && ch <= \"9\") return \"L\"; // literal\n return ch; // F, B, U, P\n};\n\n/** German Tax Number (Steuernummer). */\nconst stnr: Validator = {\n name: \"German Tax Number\",\n localName: \"Steuernummer\",\n abbreviation: \"StNr\",\n aliases: [\"Steuernummer\", \"St.Nr.\"] as const,\n candidatePattern: \"\\\\d{2,4}/\\\\d{3,4}/\\\\d{4,5}\",\n country: \"DE\",\n entityType: \"any\",\n description:\n \"German tax number assigned by the local \" +\n \"tax office, varies by federal state\",\n sourceUrl: \"https://de.wikipedia.org/wiki/Steuernummer\",\n lengths: [10, 11, 13] as const,\n examples: [\"2181508150\", \"18181508155\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default stnr;\nexport { compact, format, validate, generate };\n"],"mappings":"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"}
1
+ {"version":3,"file":"stnr.js","names":[],"sources":["../../src/de/stnr.ts"],"sourcesContent":["/**\n * Generate a random valid Steuernummer.\n * Uses Berlin regional format (FFBBBUUUUP, 10 digits).\n */\nconst generate = (): string => {\n const ff = randomDigits(2);\n const bbb = randomDigits(3);\n const uuuu = randomDigits(4);\n const p = randomDigits(1);\n return `${ff}${bbb}${uuuu}${p}`;\n};\n\n/**\n * StNr (Steuernummer).\n *\n * German tax number assigned by the local tax office.\n * Regional format: 10 or 11 digits. Unified federal\n * format: 13 digits (prefixed with a 2–4 digit BUFA\n * code). Structure varies by federal state.\n *\n * The number encodes: BUFA (Bundesfinanzamtsnummer),\n * district code, serial number, and check digit. No\n * algorithmic check digit validation is standardised\n * across all states; validation is format-only.\n *\n * @see https://de.wikipedia.org/wiki/Steuernummer\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 * Format patterns per federal state.\n * [0] = regional format, [1] = unified (federal) format.\n *\n * Legend: F = finance office, B = district,\n * U = serial, P = check digit,\n * leading digits are literal.\n */\nconst STATES = {\n \"Baden-Württemberg\": [\"FFBBBUUUUP\", \"28FF0BBBUUUUP\"],\n Bayern: [\"FFFBBBUUUUP\", \"9FFF0BBBUUUUP\"],\n Berlin: [\"FFBBBUUUUP\", \"11FF0BBBUUUUP\"],\n Brandenburg: [\"0FFBBBUUUUP\", \"30FF0BBBUUUUP\"],\n Bremen: [\"FFBBBUUUUP\", \"24FF0BBBUUUUP\"],\n Hamburg: [\"FFBBBUUUUP\", \"22FF0BBBUUUUP\"],\n Hessen: [\"0FFBBBUUUUP\", \"26FF0BBBUUUUP\"],\n \"Mecklenburg-Vorpommern\": [\n \"0FFBBBUUUUP\",\n \"40FF0BBBUUUUP\",\n ],\n Niedersachsen: [\"FFBBBUUUUP\", \"23FF0BBBUUUUP\"],\n \"Nordrhein-Westfalen\": [\"FFFBBBBUUUP\", \"5FFF0BBBBUUUP\"],\n \"Rheinland-Pfalz\": [\"FFBBBUUUUP\", \"27FF0BBBUUUUP\"],\n Saarland: [\"0FFBBBUUUUP\", \"10FF0BBBUUUUP\"],\n Sachsen: [\"2FFBBBUUUUP\", \"32FF0BBBUUUUP\"],\n \"Sachsen-Anhalt\": [\"1FFBBBUUUUP\", \"31FF0BBBUUUUP\"],\n \"Schleswig-Holstein\": [\"FFBBBUUUUP\", \"21FF0BBBUUUUP\"],\n Thüringen: [\"1FFBBBUUUUP\", \"41FF0BBBUUUUP\"],\n} as const;\n\ntype StateName = keyof typeof STATES;\n\n/**\n * Convert a format pattern to a regex.\n * Literal digits match themselves; F/B/U match any\n * digit; P (check digit) matches any digit.\n */\nconst patternToRegex = (pattern: string): RegExp => {\n let re = \"^\";\n for (const ch of pattern) {\n if (ch >= \"0\" && ch <= \"9\") {\n re += ch;\n } else {\n re += \"\\\\d\";\n }\n }\n re += \"$\";\n return new RegExp(re);\n};\n\n/** Pre-compiled regexes for each state + format. */\nconst COMPILED: Array<{\n state: StateName;\n regional: RegExp;\n regionalFmt: string;\n federal: RegExp;\n federalFmt: string;\n}> = (\n Object.entries(STATES) as Array<\n [StateName, readonly [string, string]]\n >\n).map(([state, [regionalFmt, federalFmt]]) => ({\n state,\n regional: patternToRegex(regionalFmt),\n regionalFmt,\n federal: patternToRegex(federalFmt),\n federalFmt,\n}));\n\nconst compact = (value: string): string =>\n clean(value, \" -/.\");\n\nconst matchesAnyPattern = (v: string): boolean => {\n for (const { regional, federal } of COMPILED) {\n if (regional.test(v) || federal.test(v)) return true;\n }\n return false;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"German Steuernummer must contain only digits\",\n );\n }\n\n if (\n v.length !== 10 &&\n v.length !== 11 &&\n v.length !== 13\n ) {\n return err(\n \"INVALID_LENGTH\",\n \"German Steuernummer must be 10, 11, or 13 digits\",\n );\n }\n\n if (!matchesAnyPattern(v)) {\n return err(\n \"INVALID_COMPONENT\",\n \"German Steuernummer does not match any \" +\n \"known state format\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\n/**\n * Format with slashes at segment boundaries.\n * Uses the first matching state pattern to determine\n * segment positions.\n */\nconst format = (value: string): string => {\n const v = compact(value);\n\n for (const entry of COMPILED) {\n const pattern =\n v.length === 13 ? entry.federal : entry.regional;\n if (!pattern.test(v)) continue;\n\n const fmt =\n v.length === 13\n ? entry.federalFmt\n : entry.regionalFmt;\n\n // Group by consecutive runs of the same letter\n // category: literal digits, F, B, U, P\n const segments: string[] = [];\n let segStart = 0;\n // SAFETY: fmt is a non-empty literal from COMPILED.\n // eslint-disable-next-line no-non-null-assertion\n let prevCat = charCat(fmt[0]!);\n\n for (let i = 1; i < fmt.length; i++) {\n // SAFETY: i < fmt.length.\n // eslint-disable-next-line no-non-null-assertion\n const cat = charCat(fmt[i]!);\n if (cat !== prevCat) {\n segments.push(v.slice(segStart, i));\n segStart = i;\n prevCat = cat;\n }\n }\n segments.push(v.slice(segStart));\n\n return segments.join(\"/\");\n }\n\n return v;\n};\n\nconst charCat = (ch: string): string => {\n if (ch >= \"0\" && ch <= \"9\") return \"L\"; // literal\n return ch; // F, B, U, P\n};\n\n/** German Tax Number (Steuernummer). */\nconst stnr: CountryValidator<\"DE\"> = {\n name: \"German Tax Number\",\n localName: \"Steuernummer\",\n abbreviation: \"StNr\",\n aliases: [\"Steuernummer\", \"St.Nr.\"] as const,\n candidatePattern: \"\\\\d{2,4}/\\\\d{3,4}/\\\\d{4,5}\",\n scope: \"country\",\n country: \"DE\",\n entityType: \"any\",\n description:\n \"German tax number assigned by the local \" +\n \"tax office, varies by federal state\",\n sourceUrl: \"https://de.wikipedia.org/wiki/Steuernummer\",\n lengths: [10, 11, 13] as const,\n examples: [\"2181508150\", \"18181508155\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default stnr;\nexport { compact, format, validate, generate };\n"],"mappings":"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"}
package/dist/de/svnr.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/de/svnr.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 German SVNR. */
8
8
  declare const generate: () => string;
9
9
  /** German Social Insurance Number. */
10
- declare const svnr: Validator;
10
+ declare const svnr: CountryValidator<"DE">;
11
11
  //#endregion
12
12
  export { compact, svnr as default, format, generate, validate };
13
13
  //# sourceMappingURL=svnr.d.ts.map
package/dist/de/svnr.js CHANGED
@@ -1,18 +1,8 @@
1
1
  import { clean } from "../_util/clean.js";
2
+ import { isValidDate, resolveTwoDigitYear } from "../_util/date.js";
2
3
  import { randomInt } from "../_util/generate.js";
3
4
  import { err } from "../_util/result.js";
4
- import { isValidDate, resolveTwoDigitYear } from "../_util/date.js";
5
5
  //#region src/de/svnr.ts
6
- /**
7
- * SVNR (Sozialversicherungsnummer).
8
- *
9
- * German social insurance number. 12 characters:
10
- * area number (2 digits) + date of birth (DDMMYY)
11
- * + initial letter of birth name (1 letter) +
12
- * serial number (2 digits) + check digit (1 digit).
13
- *
14
- * @see https://de.wikipedia.org/wiki/Sozialversicherungsnummer
15
- */
16
6
  const letterValue = (ch) => {
17
7
  const code = ch.charCodeAt(0);
18
8
  if (code >= 65 && code <= 90) return code - 64;
@@ -91,6 +81,7 @@ const svnr = {
91
81
  "Versicherungsnummer"
92
82
  ],
93
83
  candidatePattern: "\\d{2}\\s?\\d{6}\\s?[A-Z]\\s?\\d{3}",
84
+ scope: "country",
94
85
  country: "DE",
95
86
  entityType: "person",
96
87
  description: "German social insurance number encoding birth date and name initial",
@@ -1 +1 @@
1
- {"version":3,"file":"svnr.js","names":[],"sources":["../../src/de/svnr.ts"],"sourcesContent":["/**\n * SVNR (Sozialversicherungsnummer).\n *\n * German social insurance number. 12 characters:\n * area number (2 digits) + date of birth (DDMMYY)\n * + initial letter of birth name (1 letter) +\n * serial number (2 digits) + check digit (1 digit).\n *\n * @see https://de.wikipedia.org/wiki/Sozialversicherungsnummer\n */\n\nimport { clean } from \"#util/clean\";\nimport {\n isValidDate,\n resolveTwoDigitYear,\n} from \"#util/date\";\nimport { randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst letterValue = (ch: string): number => {\n const code = ch.charCodeAt(0);\n if (code >= 65 && code <= 90) return code - 64;\n return -1;\n};\n\nconst WEIGHTS = [\n 2, 1, 2, 5, 7, 1, 2, 1, 2, 1, 2, 1,\n] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -/\").toUpperCase();\n\nconst computeCheck = (v: string): number => {\n const digits: number[] = [];\n\n for (let i = 0; i < 8; i++) {\n digits.push(Number(v[i]));\n }\n\n // SAFETY: caller guarantees v.length === 12.\n // eslint-disable-next-line no-non-null-assertion\n const lv = letterValue(v[8]!);\n digits.push(Math.floor(lv / 10));\n digits.push(lv % 10);\n\n digits.push(Number(v[9]));\n digits.push(Number(v[10]));\n\n let sum = 0;\n for (const [i, weight] of WEIGHTS.entries()) {\n // SAFETY: WEIGHTS.length === 12 and we just pushed\n // 12 entries onto `digits`.\n // eslint-disable-next-line no-non-null-assertion\n const product = digits[i]! * weight;\n if (product >= 10) {\n sum += Math.floor(product / 10) + (product % 10);\n } else {\n sum += product;\n }\n }\n\n return sum % 10;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 12) {\n return err(\n \"INVALID_LENGTH\",\n \"German SVNR must be 12 characters\",\n );\n }\n\n if (!/^\\d{8}[A-Z]\\d{3}$/.test(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"German SVNR must be 8 digits, 1 letter, \" +\n \"3 digits\",\n );\n }\n\n const dd = Number(v.slice(2, 4));\n const mm = Number(v.slice(4, 6));\n const yy = Number(v.slice(6, 8));\n\n const year = resolveTwoDigitYear(yy);\n\n if (!isValidDate(year, mm, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"German SVNR contains an invalid birth date\",\n );\n }\n\n const expected = computeCheck(v);\n const actual = Number(v[11]);\n\n if (expected !== actual) {\n return err(\n \"INVALID_CHECKSUM\",\n \"German SVNR 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 (\n `${v.slice(0, 2)} ${v.slice(2, 8)}` +\n ` ${v.slice(8, 9)} ${v.slice(9, 11)}` +\n ` ${v.slice(11)}`\n );\n};\n\n/** Generate a random valid German SVNR. */\nconst generate = (): string => {\n for (;;) {\n const area = String(randomInt(1, 99)).padStart(2, \"0\");\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(40, 99)).padStart(2, \"0\");\n const letter = String.fromCharCode(\n 65 + randomInt(0, 25),\n );\n const serial = String(randomInt(0, 49)).padStart(\n 2,\n \"0\",\n );\n const partial = area + dd + mm + yy + letter + serial;\n const c = partial + String(computeCheck(partial));\n if (validate(c).valid) return c;\n }\n};\n\n/** German Social Insurance Number. */\nconst svnr: Validator = {\n name: \"German Social Insurance Number\",\n localName: \"Sozialversicherungsnummer\",\n abbreviation: \"SVNR\",\n aliases: [\n \"Sozialversicherungsnummer\",\n \"SVNR\",\n \"Versicherungsnummer\",\n ] as const,\n candidatePattern: \"\\\\d{2}\\\\s?\\\\d{6}\\\\s?[A-Z]\\\\s?\\\\d{3}\",\n country: \"DE\",\n entityType: \"person\",\n description:\n \"German social insurance number encoding \" +\n \"birth date and name initial\",\n sourceUrl:\n \"https://de.wikipedia.org/wiki/\" +\n \"Sozialversicherungsnummer\",\n lengths: [12] as const,\n examples: [\"12010188M011\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default svnr;\nexport { compact, format, validate, generate };\n"],"mappings":"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"}
1
+ {"version":3,"file":"svnr.js","names":[],"sources":["../../src/de/svnr.ts"],"sourcesContent":["/**\n * SVNR (Sozialversicherungsnummer).\n *\n * German social insurance number. 12 characters:\n * area number (2 digits) + date of birth (DDMMYY)\n * + initial letter of birth name (1 letter) +\n * serial number (2 digits) + check digit (1 digit).\n *\n * @see https://de.wikipedia.org/wiki/Sozialversicherungsnummer\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport {\n isValidDate,\n resolveTwoDigitYear,\n} from \"#util/date\";\nimport { randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\n\nconst letterValue = (ch: string): number => {\n const code = ch.charCodeAt(0);\n if (code >= 65 && code <= 90) return code - 64;\n return -1;\n};\n\nconst WEIGHTS = [\n 2, 1, 2, 5, 7, 1, 2, 1, 2, 1, 2, 1,\n] as const;\n\nconst compact = (value: string): string =>\n clean(value, \" -/\").toUpperCase();\n\nconst computeCheck = (v: string): number => {\n const digits: number[] = [];\n\n for (let i = 0; i < 8; i++) {\n digits.push(Number(v[i]));\n }\n\n // SAFETY: caller guarantees v.length === 12.\n // eslint-disable-next-line no-non-null-assertion\n const lv = letterValue(v[8]!);\n digits.push(Math.floor(lv / 10));\n digits.push(lv % 10);\n\n digits.push(Number(v[9]));\n digits.push(Number(v[10]));\n\n let sum = 0;\n for (const [i, weight] of WEIGHTS.entries()) {\n // SAFETY: WEIGHTS.length === 12 and we just pushed\n // 12 entries onto `digits`.\n // eslint-disable-next-line no-non-null-assertion\n const product = digits[i]! * weight;\n if (product >= 10) {\n sum += Math.floor(product / 10) + (product % 10);\n } else {\n sum += product;\n }\n }\n\n return sum % 10;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 12) {\n return err(\n \"INVALID_LENGTH\",\n \"German SVNR must be 12 characters\",\n );\n }\n\n if (!/^\\d{8}[A-Z]\\d{3}$/.test(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"German SVNR must be 8 digits, 1 letter, \" +\n \"3 digits\",\n );\n }\n\n const dd = Number(v.slice(2, 4));\n const mm = Number(v.slice(4, 6));\n const yy = Number(v.slice(6, 8));\n\n const year = resolveTwoDigitYear(yy);\n\n if (!isValidDate(year, mm, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"German SVNR contains an invalid birth date\",\n );\n }\n\n const expected = computeCheck(v);\n const actual = Number(v[11]);\n\n if (expected !== actual) {\n return err(\n \"INVALID_CHECKSUM\",\n \"German SVNR 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 (\n `${v.slice(0, 2)} ${v.slice(2, 8)}` +\n ` ${v.slice(8, 9)} ${v.slice(9, 11)}` +\n ` ${v.slice(11)}`\n );\n};\n\n/** Generate a random valid German SVNR. */\nconst generate = (): string => {\n for (;;) {\n const area = String(randomInt(1, 99)).padStart(2, \"0\");\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(40, 99)).padStart(2, \"0\");\n const letter = String.fromCharCode(\n 65 + randomInt(0, 25),\n );\n const serial = String(randomInt(0, 49)).padStart(\n 2,\n \"0\",\n );\n const partial = area + dd + mm + yy + letter + serial;\n const c = partial + String(computeCheck(partial));\n if (validate(c).valid) return c;\n }\n};\n\n/** German Social Insurance Number. */\nconst svnr: CountryValidator<\"DE\"> = {\n name: \"German Social Insurance Number\",\n localName: \"Sozialversicherungsnummer\",\n abbreviation: \"SVNR\",\n aliases: [\n \"Sozialversicherungsnummer\",\n \"SVNR\",\n \"Versicherungsnummer\",\n ] as const,\n candidatePattern: \"\\\\d{2}\\\\s?\\\\d{6}\\\\s?[A-Z]\\\\s?\\\\d{3}\",\n scope: \"country\",\n country: \"DE\",\n entityType: \"person\",\n description:\n \"German social insurance number encoding \" +\n \"birth date and name initial\",\n sourceUrl:\n \"https://de.wikipedia.org/wiki/\" +\n \"Sozialversicherungsnummer\",\n lengths: [12] as const,\n examples: [\"12010188M011\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default svnr;\nexport { compact, format, validate, generate };\n"],"mappings":"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"}
package/dist/de/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/de/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 German VAT number. */
8
8
  declare const generate: () => string;
9
9
  /** German VAT Identification Number. */
10
- declare const vat: Validator;
10
+ declare const vat: CountryValidator<"DE">;
11
11
  //#endregion
12
12
  export { compact, vat as default, format, generate, validate };
13
13
  //# sourceMappingURL=vat.d.ts.map
package/dist/de/vat.js CHANGED
@@ -1,19 +1,9 @@
1
+ import { mod1110checkDigit, mod1110validate } from "../_checksums/mod1110.js";
1
2
  import { clean } from "../_util/clean.js";
2
3
  import { randomDigits, randomInt } from "../_util/generate.js";
3
4
  import { err } from "../_util/result.js";
4
5
  import { isdigits } from "../_util/strings.js";
5
- import { mod1110checkDigit, mod1110validate } from "../_checksums/mod1110.js";
6
6
  //#region src/de/vat.ts
7
- /**
8
- * USt-IdNr. (Umsatzsteuer-Identifikationsnummer).
9
- *
10
- * German VAT identification number. Format:
11
- * "DE" + 9 digits. The last digit is a check
12
- * digit computed using ISO 7064 Mod 11,10.
13
- *
14
- * @see https://www.bzst.de/DE/Unternehmen/Identifikationsnummern/Umsatzsteuer-Identifikationsnummer/umsatzsteuer-identifikationsnummer_node.html
15
- * @see https://www.bzst.de/SharedDocs/Downloads/DE/Merkblaetter/ust_idnr_aufbau.pdf
16
- */
17
7
  const compact = (value) => {
18
8
  const v = clean(value, " -/");
19
9
  if (v.startsWith("DE") || v.startsWith("de")) return v.slice(2);
@@ -48,6 +38,7 @@ const vat = {
48
38
  "VAT DE"
49
39
  ],
50
40
  candidatePattern: "DE\\d{9}",
41
+ scope: "country",
51
42
  country: "DE",
52
43
  entityType: "company",
53
44
  description: "German VAT ID issued by the Federal Tax Office (BZSt)",
@@ -1 +1 @@
1
- {"version":3,"file":"vat.js","names":[],"sources":["../../src/de/vat.ts"],"sourcesContent":["/**\n * USt-IdNr. (Umsatzsteuer-Identifikationsnummer).\n *\n * German VAT identification number. Format:\n * \"DE\" + 9 digits. The last digit is a check\n * digit computed using ISO 7064 Mod 11,10.\n *\n * @see https://www.bzst.de/DE/Unternehmen/Identifikationsnummern/Umsatzsteuer-Identifikationsnummer/umsatzsteuer-identifikationsnummer_node.html\n * @see https://www.bzst.de/SharedDocs/Downloads/DE/Merkblaetter/ust_idnr_aufbau.pdf\n */\n\nimport {\n mod1110checkDigit,\n mod1110validate,\n} from \"#checksums/mod1110\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nimport type { ValidateResult, Validator } from \"../types\";\n\nconst compact = (value: string): string => {\n const v = clean(value, \" -/\");\n if (v.startsWith(\"DE\") || v.startsWith(\"de\")) {\n return v.slice(2);\n }\n return v;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"German VAT number must be 9 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"German VAT number must contain only digits\",\n );\n }\n if (v[0] === \"0\") {\n return err(\n \"INVALID_COMPONENT\",\n \"German VAT number cannot start with 0\",\n );\n }\n if (!mod1110validate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"German VAT number check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string =>\n `DE${compact(value)}`;\n\n/** Generate a random valid German VAT number. */\nconst generate = (): string => {\n const first = String(randomInt(1, 9));\n const rest = randomDigits(7);\n const payload = `${first}${rest}`;\n const check = mod1110checkDigit(payload);\n return `${payload}${String(check)}`;\n};\n\n/** German VAT Identification Number. */\nconst vat: Validator = {\n name: \"German VAT Number\",\n localName: \"Umsatzsteuer-Identifikationsnummer\",\n abbreviation: \"USt-IdNr.\",\n aliases: [\n \"USt-IdNr\",\n \"Umsatzsteuer-Identifikationsnummer\",\n \"VAT DE\",\n ] as const,\n candidatePattern: \"DE\\\\d{9}\",\n country: \"DE\",\n entityType: \"company\",\n description:\n \"German VAT ID issued by the Federal Tax Office (BZSt)\",\n sourceUrl:\n \"https://www.bzst.de/DE/Unternehmen/Identifikationsnummern/Umsatzsteuer-Identifikationsnummer/umsatzsteuer-identifikationsnummer_node.html\",\n lengths: [9] as const,\n examples: [\"136695976\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default vat;\nexport { compact, format, generate, validate };\n"],"mappings":";;;;;;;;;;;;;;;;AAsBA,MAAM,WAAW,UAA0B;CACzC,MAAM,IAAI,MAAM,OAAO,MAAM;AAC7B,KAAI,EAAE,WAAW,KAAK,IAAI,EAAE,WAAW,KAAK,CAC1C,QAAO,EAAE,MAAM,EAAE;AAEnB,QAAO;;AAGT,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,EAAE,WAAW,EACf,QAAO,IACL,kBACA,qCACD;AAEH,KAAI,CAAC,SAAS,EAAE,CACd,QAAO,IACL,kBACA,6CACD;AAEH,KAAI,EAAE,OAAO,IACX,QAAO,IACL,qBACA,wCACD;AAEH,KAAI,CAAC,gBAAgB,EAAE,CACrB,QAAO,IACL,oBACA,yCACD;AAEH,QAAO;EAAE,OAAO;EAAM,SAAS;EAAG;;AAGpC,MAAM,UAAU,UACd,KAAK,QAAQ,MAAM;;AAGrB,MAAM,iBAAyB;CAG7B,MAAM,UAAU,GAFF,OAAO,UAAU,GAAG,EAAE,CAAC,GACxB,aAAa,EAAE;CAE5B,MAAM,QAAQ,kBAAkB,QAAQ;AACxC,QAAO,GAAG,UAAU,OAAO,MAAM;;;AAInC,MAAM,MAAiB;CACrB,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;EACD;CACD,kBAAkB;CAClB,SAAS;CACT,YAAY;CACZ,aACE;CACF,WACE;CACF,SAAS,CAAC,EAAE;CACZ,UAAU,CAAC,YAAY;CACvB;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"vat.js","names":[],"sources":["../../src/de/vat.ts"],"sourcesContent":["/**\n * USt-IdNr. (Umsatzsteuer-Identifikationsnummer).\n *\n * German VAT identification number. Format:\n * \"DE\" + 9 digits. The last digit is a check\n * digit computed using ISO 7064 Mod 11,10.\n *\n * @see https://www.bzst.de/DE/Unternehmen/Identifikationsnummern/Umsatzsteuer-Identifikationsnummer/umsatzsteuer-identifikationsnummer_node.html\n * @see https://www.bzst.de/SharedDocs/Downloads/DE/Merkblaetter/ust_idnr_aufbau.pdf\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport {\n mod1110checkDigit,\n mod1110validate,\n} from \"#checksums/mod1110\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst compact = (value: string): string => {\n const v = clean(value, \" -/\");\n if (v.startsWith(\"DE\") || v.startsWith(\"de\")) {\n return v.slice(2);\n }\n return v;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"German VAT number must be 9 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"German VAT number must contain only digits\",\n );\n }\n if (v[0] === \"0\") {\n return err(\n \"INVALID_COMPONENT\",\n \"German VAT number cannot start with 0\",\n );\n }\n if (!mod1110validate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"German VAT number check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string =>\n `DE${compact(value)}`;\n\n/** Generate a random valid German VAT number. */\nconst generate = (): string => {\n const first = String(randomInt(1, 9));\n const rest = randomDigits(7);\n const payload = `${first}${rest}`;\n const check = mod1110checkDigit(payload);\n return `${payload}${String(check)}`;\n};\n\n/** German VAT Identification Number. */\nconst vat: CountryValidator<\"DE\"> = {\n name: \"German VAT Number\",\n localName: \"Umsatzsteuer-Identifikationsnummer\",\n abbreviation: \"USt-IdNr.\",\n aliases: [\n \"USt-IdNr\",\n \"Umsatzsteuer-Identifikationsnummer\",\n \"VAT DE\",\n ] as const,\n candidatePattern: \"DE\\\\d{9}\",\n scope: \"country\",\n country: \"DE\",\n entityType: \"company\",\n description:\n \"German VAT ID issued by the Federal Tax Office (BZSt)\",\n sourceUrl:\n \"https://www.bzst.de/DE/Unternehmen/Identifikationsnummern/Umsatzsteuer-Identifikationsnummer/umsatzsteuer-identifikationsnummer_node.html\",\n lengths: [9] as const,\n examples: [\"136695976\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default vat;\nexport { compact, format, generate, validate };\n"],"mappings":";;;;;;AAyBA,MAAM,WAAW,UAA0B;CACzC,MAAM,IAAI,MAAM,OAAO,KAAK;CAC5B,IAAI,EAAE,WAAW,IAAI,KAAK,EAAE,WAAW,IAAI,GACzC,OAAO,EAAE,MAAM,CAAC;CAElB,OAAO;AACT;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,GACf,OAAO,IACL,kBACA,oCACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,4CACF;CAEF,IAAI,EAAE,OAAO,KACX,OAAO,IACL,qBACA,uCACF;CAEF,IAAI,CAAC,gBAAgB,CAAC,GACpB,OAAO,IACL,oBACA,wCACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UACd,KAAK,QAAQ,KAAK;;AAGpB,MAAM,iBAAyB;CAG7B,MAAM,UAAU,GAFF,OAAO,UAAU,GAAG,CAAC,CAEZ,IADV,aAAa,CACI;CAC9B,MAAM,QAAQ,kBAAkB,OAAO;CACvC,OAAO,GAAG,UAAU,OAAO,KAAK;AAClC;;AAGA,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;CACF;CACA,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,aACE;CACF,WACE;CACF,SAAS,CAAC,CAAC;CACX,UAAU,CAAC,WAAW;CACtB;CACA;CACA;CACA;AACF"}