@stll/stdnum 2.0.0 → 2.1.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.
- package/README.md +12 -13
- package/dist/_checksums/keccak.d.ts +5 -0
- package/dist/_checksums/keccak.js +118 -0
- package/dist/_checksums/keccak.js.map +1 -0
- package/dist/_checksums/mod112.js.map +1 -1
- package/dist/_checksums/sha256.d.ts +5 -0
- package/dist/_checksums/sha256.js +164 -0
- package/dist/_checksums/sha256.js.map +1 -0
- package/dist/_checksums/verhoeff.js.map +1 -1
- package/dist/_util/arabic.js.map +1 -1
- package/dist/_util/clean.js.map +1 -1
- package/dist/_util/date.js.map +1 -1
- package/dist/ad/nrt.js.map +1 -1
- package/dist/ae/eid.js.map +1 -1
- package/dist/ai/tin.js.map +1 -1
- package/dist/al/nipt.js.map +1 -1
- package/dist/am/tin.js.map +1 -1
- package/dist/ar/cbu.js.map +1 -1
- package/dist/ar/cuit.js.map +1 -1
- package/dist/ar/dni.js.map +1 -1
- package/dist/at/businessid.js.map +1 -1
- package/dist/at/vnr.js.map +1 -1
- package/dist/au/abn.js.map +1 -1
- package/dist/au/tfn.js.map +1 -1
- package/dist/az/voen.js.map +1 -1
- package/dist/ba/jmbg.js.map +1 -1
- package/dist/be/bis.js.map +1 -1
- package/dist/be/nn.js.map +1 -1
- package/dist/be/vat.js.map +1 -1
- package/dist/bg/egn.js.map +1 -1
- package/dist/bg/vat.js.map +1 -1
- package/dist/bh/cpr.js.map +1 -1
- package/dist/bic.js.map +1 -1
- package/dist/br/cnpj.js.map +1 -1
- package/dist/br/cpf.js.map +1 -1
- package/dist/by/unp.js.map +1 -1
- package/dist/bz/tin.js.map +1 -1
- package/dist/ch/uid.js.map +1 -1
- package/dist/ch/vat.js.map +1 -1
- package/dist/cl/rut.js.map +1 -1
- package/dist/cn/ric.js.map +1 -1
- package/dist/cn/uscc.js.map +1 -1
- package/dist/cr/cpf.js.map +1 -1
- package/dist/crypto/btcbase58.d.ts +11 -0
- package/dist/crypto/btcbase58.js +76 -0
- package/dist/crypto/btcbase58.js.map +1 -0
- package/dist/crypto/btcbech32.d.ts +19 -0
- package/dist/crypto/btcbech32.js +145 -0
- package/dist/crypto/btcbech32.js.map +1 -0
- package/dist/crypto/eth.d.ts +11 -0
- package/dist/crypto/eth.js +63 -0
- package/dist/crypto/eth.js.map +1 -0
- package/dist/crypto/mod.d.ts +12 -0
- package/dist/crypto/mod.js +16 -0
- package/dist/crypto/mod.js.map +1 -0
- package/dist/crypto/wallet.d.ts +10 -0
- package/dist/crypto/wallet.js +55 -0
- package/dist/crypto/wallet.js.map +1 -0
- package/dist/cu/ni.js.map +1 -1
- package/dist/cz/rc.js.map +1 -1
- package/dist/de/handelsreg.js.map +1 -1
- package/dist/de/idnr.js.map +1 -1
- package/dist/de/stnr.js.map +1 -1
- package/dist/de/svnr.js.map +1 -1
- package/dist/dk/cpr.js.map +1 -1
- package/dist/dk/cvr.js.map +1 -1
- package/dist/dk/vat.js.map +1 -1
- package/dist/do/rnc.js.map +1 -1
- package/dist/ec/ruc.js.map +1 -1
- package/dist/ee/ik.js.map +1 -1
- package/dist/ee/vat.js.map +1 -1
- package/dist/eg/tn.js.map +1 -1
- package/dist/es/dni.js.map +1 -1
- package/dist/es/nie.js.map +1 -1
- package/dist/es/nss.js.map +1 -1
- package/dist/eu/vat.js.map +1 -1
- package/dist/fi/hetu.js.map +1 -1
- package/dist/fi/vat.js.map +1 -1
- package/dist/fi/ytunnus.js.map +1 -1
- package/dist/fr/nif.js.map +1 -1
- package/dist/fr/nir.js.map +1 -1
- package/dist/fr/tva.js.map +1 -1
- package/dist/gb/mod.d.ts +3 -2
- package/dist/gb/mod.js +3 -1
- package/dist/gb/mod.js.map +1 -1
- package/dist/gb/nhs.d.ts +11 -0
- package/dist/gb/nhs.js +51 -0
- package/dist/gb/nhs.js.map +1 -0
- package/dist/gb/nino.js.map +1 -1
- package/dist/gb/sedol.js.map +1 -1
- package/dist/gb/utr.js.map +1 -1
- package/dist/gb/vat.js.map +1 -1
- package/dist/ge/pin.js.map +1 -1
- package/dist/gh/tin.js.map +1 -1
- package/dist/gr/amka.js.map +1 -1
- package/dist/gt/nit.js.map +1 -1
- package/dist/hk/hkid.js.map +1 -1
- package/dist/hu/vat.js.map +1 -1
- package/dist/iban.js.map +1 -1
- package/dist/id/npwp.js.map +1 -1
- package/dist/ie/pps.js.map +1 -1
- package/dist/ie/vat.js.map +1 -1
- package/dist/il/idnr.js.map +1 -1
- package/dist/in/aadhaar.js.map +1 -1
- package/dist/in/gstin.js.map +1 -1
- package/dist/in/pan.js.map +1 -1
- package/dist/index.d.ts +76 -75
- package/dist/index.js +2 -1
- package/dist/ir/nid.js.map +1 -1
- package/dist/is/kennitala.js.map +1 -1
- package/dist/isin.js.map +1 -1
- package/dist/it/codicefiscale.js.map +1 -1
- package/dist/it/iva.js.map +1 -1
- package/dist/kr/rrn.js.map +1 -1
- package/dist/kw/civil.js.map +1 -1
- package/dist/kz/iin.js.map +1 -1
- package/dist/lei.js.map +1 -1
- package/dist/li/peid.js.map +1 -1
- package/dist/lk/nic.js.map +1 -1
- package/dist/lt/asmens.js.map +1 -1
- package/dist/lt/vat.js.map +1 -1
- package/dist/lu/vat.js.map +1 -1
- package/dist/lv/vat.js.map +1 -1
- package/dist/ma/ice.js.map +1 -1
- package/dist/mc/tva.js.map +1 -1
- package/dist/mt/vat.js.map +1 -1
- package/dist/mu/brn.js.map +1 -1
- package/dist/mx/clabe.js.map +1 -1
- package/dist/mx/curp.js.map +1 -1
- package/dist/mx/rfc.js.map +1 -1
- package/dist/my/nric.js.map +1 -1
- package/dist/ni/ruc.js.map +1 -1
- package/dist/nl/bsn.js.map +1 -1
- package/dist/nl/vat.js.map +1 -1
- package/dist/no/fodselsnummer.js.map +1 -1
- package/dist/no/mva.js.map +1 -1
- package/dist/no/orgnr.js.map +1 -1
- package/dist/nz/ird.js.map +1 -1
- package/dist/pa/ruc.js.map +1 -1
- package/dist/patterns.js.map +1 -1
- package/dist/pe/ruc.js.map +1 -1
- package/dist/pl/pesel.js.map +1 -1
- package/dist/pl/regon.js.map +1 -1
- package/dist/pt/cc.js.map +1 -1
- package/dist/ro/cnp.js.map +1 -1
- package/dist/ro/vat.js.map +1 -1
- package/dist/rs/pib.js.map +1 -1
- package/dist/ru/inn.js.map +1 -1
- package/dist/se/personnummer.js.map +1 -1
- package/dist/sg/uen.js.map +1 -1
- package/dist/si/emso.js.map +1 -1
- package/dist/si/vat.js.map +1 -1
- package/dist/sk/dic.js.map +1 -1
- package/dist/tw/ubn.js.map +1 -1
- package/dist/ua/edrpou.js.map +1 -1
- package/dist/us/itin.js.map +1 -1
- package/dist/us/rtn.js.map +1 -1
- package/dist/us/ssn.js.map +1 -1
- package/dist/uy/rut.js.map +1 -1
- package/dist/ve/rif.js.map +1 -1
- package/dist/vn/mst.js.map +1 -1
- package/dist/za/idnr.js.map +1 -1
- package/package.json +31 -6
- package/src/_checksums/keccak.ts +145 -0
- package/src/_checksums/sha256.ts +125 -0
- package/src/crypto/btcbase58.ts +144 -0
- package/src/crypto/btcbech32.ts +210 -0
- package/src/crypto/eth.ts +114 -0
- package/src/crypto/mod.ts +4 -0
- package/src/crypto/wallet.ts +67 -0
- package/src/gb/mod.ts +1 -0
- package/src/gb/nhs.ts +92 -0
- package/src/index.ts +1 -0
package/dist/id/npwp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"npwp.js","names":[],"sources":["../../src/id/npwp.ts"],"sourcesContent":["/**\n * NPWP (Nomor Pokok Wajib Pajak, Indonesian tax ID).\n *\n * 15 or 16 digits. The 15-digit (legacy) format has a\n * Luhn check on the first 9 digits. The 16-digit format\n * is either a NIK (starts with non-zero) validated as a\n * province-code and birth-date checks, or the legacy\n * format prefixed with 0 (Luhn on first 10 digits).\n *\n * @see https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Indonesia-TIN.pdf\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport {\n luhnValidate,\n luhnChecksum,\n} from \"#checksums/luhn\";\nimport { clean } from \"#util/clean\";\nimport { isValidDate } from \"#util/date\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst compact = (value: string): string =>\n clean(value, \" .-\");\n\n/**\n * Valid 2-digit province codes for NIK, sourced from\n * python-stdnum's id/loc numdb.\n */\nconst NIK_PROVINCES = new Set([\n \"11\",\n \"12\",\n \"13\",\n \"14\",\n \"15\",\n \"16\",\n \"17\",\n \"18\",\n \"19\",\n \"21\",\n \"31\",\n \"32\",\n \"33\",\n \"34\",\n \"35\",\n \"36\",\n \"51\",\n \"52\",\n \"53\",\n \"61\",\n \"62\",\n \"63\",\n \"64\",\n \"71\",\n \"72\",\n \"73\",\n \"74\",\n \"75\",\n \"76\",\n \"81\",\n \"82\",\n \"91\",\n \"94\",\n]);\n\n/**\n * Validate a 16-digit NIK (Nomor Induk Kependudukan).\n * Format: PPRRSSDDMMYYXXXX where PP = province,\n * RRSS = regency/city + sub-district,\n * DDMMYY = birth date (DD+40 for females),\n * XXXX = serial.\n */\nconst validateNik = (v: string): ValidateResult => {\n // Province code check\n if (!NIK_PROVINCES.has(v.slice(0, 2))) {\n return err(\n \"INVALID_COMPONENT\",\n \"NIK province code is invalid\",\n );\n }\n let day = Number(v.slice(6, 8));\n const month = Number(v.slice(8, 10));\n const year = Number(v.slice(10, 12));\n // Females have 40 added to the day\n if (day > 40) day -= 40;\n // Validate the date (century is ambiguous in NIK)\n if (\n !isValidDate(1900 + year, month, day) &&\n !isValidDate(2000 + year, month, day)\n ) {\n return err(\n \"INVALID_COMPONENT\",\n \"NIK contains an invalid date\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"NPWP must contain only digits\",\n );\n }\n if (v.length === 15) {\n // Legacy 15-digit format: Luhn on first 9 digits\n if (!luhnValidate(v.slice(0, 9))) {\n return err(\n \"INVALID_CHECKSUM\",\n \"NPWP Luhn check on first 9 digits failed\",\n );\n }\n return { valid: true, compact: v };\n }\n if (v.length === 16) {\n if (v[0] !== \"0\") {\n // NIK format\n return validateNik(v);\n }\n // 0-prefixed legacy: Luhn on first 10 digits\n if (!luhnValidate(v.slice(0, 10))) {\n return err(\n \"INVALID_CHECKSUM\",\n \"NPWP Luhn check on first 10 digits failed\",\n );\n }\n return { valid: true, compact: v };\n }\n return err(\n \"INVALID_LENGTH\",\n \"NPWP must be 15 or 16 digits\",\n );\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n if (v.length === 16) {\n // NIK or 0-prefixed legacy: no standard mask\n return v;\n }\n return (\n `${v.slice(0, 2)}.${v.slice(2, 5)}.` +\n `${v.slice(5, 8)}.${v.slice(8, 9)}` +\n `-${v.slice(9, 12)}.${v.slice(12)}`\n );\n};\n\n/** Generate a random valid 15-digit NPWP. */\nconst generate = (): string => {\n for (;;) {\n const p = randomDigits(8);\n const cs = luhnChecksum(p + \"0\");\n const c = p + String((10 - cs) % 10) + randomDigits(6);\n if (validate(c).valid) return c;\n }\n};\n\n/** Indonesian Taxpayer Identification Number. */\nconst npwp: CountryValidator<\"ID\"> = {\n name: \"Indonesian Taxpayer Identification Number\",\n localName: \"Nomor Pokok Wajib Pajak\",\n abbreviation: \"NPWP\",\n aliases: [\"NPWP\", \"Nomor Pokok Wajib Pajak\"] as const,\n candidatePattern:\n \"\\\\d{2}\\\\.?\\\\d{3}\\\\.?\\\\d{3}\\\\.?\\\\d-?\\\\d{3}\\\\.?\\\\d{3}\",\n scope: \"country\",\n country: \"ID\",\n entityType: \"any\",\n lengths: [15, 16],\n examples: [\"013000666091000\", \"016090524017000\"],\n description:\n \"15 or 16-digit tax identification number issued by \" +\n \"the Directorate General of Taxes\",\n sourceUrl:\n \"https://en.wikipedia.org/wiki/\" +\n \"Tax_identification_number#Indonesia\",\n compact,\n format,\n validate,\n generate,\n};\n\nexport default npwp;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;AA2BA,MAAM,WAAW,UACf,MAAM,OAAO,KAAK;;;;;AAMpB,MAAM,gBAAgB,IAAI,IAAI;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;;;;AASD,MAAM,eAAe,MAA8B;CAEjD,IAAI,CAAC,cAAc,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,GAClC,OAAO,IACL,qBACA,8BACF;CAEF,IAAI,MAAM,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC9B,MAAM,QAAQ,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;CACnC,MAAM,OAAO,OAAO,EAAE,MAAM,IAAI,EAAE,CAAC;CAEnC,IAAI,MAAM,IAAI,OAAO;CAErB,IACE,CAAC,YAAY,OAAO,MAAM,OAAO,GAAG,KACpC,CAAC,YAAY,MAAO,MAAM,OAAO,GAAG,GAEpC,OAAO,IACL,qBACA,8BACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,+BACF;CAEF,IAAI,EAAE,WAAW,IAAI;EAEnB,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,CAAC,CAAC,GAC7B,OAAO,IACL,oBACA,0CACF;EAEF,OAAO;GAAE,OAAO;GAAM,SAAS;EAAE;CACnC;CACA,IAAI,EAAE,WAAW,IAAI;EACnB,IAAI,EAAE,OAAO,KAEX,OAAO,YAAY,CAAC;EAGtB,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,EAAE,CAAC,GAC9B,OAAO,IACL,oBACA,2CACF;EAEF,OAAO;GAAE,OAAO;GAAM,SAAS;EAAE;CACnC;CACA,OAAO,IACL,kBACA,8BACF;AACF;AAEA,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,IAEf,OAAO;CAET,OACE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAC/B,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAA,GAC5B,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE;AAEpC;;AAGA,MAAM,iBAAyB;CAC7B,SAAS;EACP,MAAM,IAAI,aAAa,CAAC;EACxB,MAAM,KAAK,aAAa,IAAI,GAAG;EAC/B,MAAM,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAE,IAAI,aAAa,CAAC;EACrD,IAAI,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"npwp.js","names":[],"sources":["../../src/id/npwp.ts"],"sourcesContent":["/**\n * NPWP (Nomor Pokok Wajib Pajak, Indonesian tax ID).\n *\n * 15 or 16 digits. The 15-digit (legacy) format has a\n * Luhn check on the first 9 digits. The 16-digit format\n * is either a NIK (starts with non-zero) validated as a\n * province-code and birth-date checks, or the legacy\n * format prefixed with 0 (Luhn on first 10 digits).\n *\n * @see https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Indonesia-TIN.pdf\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport {\n luhnValidate,\n luhnChecksum,\n} from \"#checksums/luhn\";\nimport { clean } from \"#util/clean\";\nimport { isValidDate } from \"#util/date\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst compact = (value: string): string =>\n clean(value, \" .-\");\n\n/**\n * Valid 2-digit province codes for NIK, sourced from\n * python-stdnum's id/loc numdb.\n */\nconst NIK_PROVINCES = new Set([\n \"11\",\n \"12\",\n \"13\",\n \"14\",\n \"15\",\n \"16\",\n \"17\",\n \"18\",\n \"19\",\n \"21\",\n \"31\",\n \"32\",\n \"33\",\n \"34\",\n \"35\",\n \"36\",\n \"51\",\n \"52\",\n \"53\",\n \"61\",\n \"62\",\n \"63\",\n \"64\",\n \"71\",\n \"72\",\n \"73\",\n \"74\",\n \"75\",\n \"76\",\n \"81\",\n \"82\",\n \"91\",\n \"94\",\n]);\n\n/**\n * Validate a 16-digit NIK (Nomor Induk Kependudukan).\n * Format: PPRRSSDDMMYYXXXX where PP = province,\n * RRSS = regency/city + sub-district,\n * DDMMYY = birth date (DD+40 for females),\n * XXXX = serial.\n */\nconst validateNik = (v: string): ValidateResult => {\n // Province code check\n if (!NIK_PROVINCES.has(v.slice(0, 2))) {\n return err(\n \"INVALID_COMPONENT\",\n \"NIK province code is invalid\",\n );\n }\n let day = Number(v.slice(6, 8));\n const month = Number(v.slice(8, 10));\n const year = Number(v.slice(10, 12));\n // Females have 40 added to the day\n if (day > 40) day -= 40;\n // Validate the date (century is ambiguous in NIK)\n if (\n !isValidDate(1900 + year, month, day) &&\n !isValidDate(2000 + year, month, day)\n ) {\n return err(\n \"INVALID_COMPONENT\",\n \"NIK contains an invalid date\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"NPWP must contain only digits\",\n );\n }\n if (v.length === 15) {\n // Legacy 15-digit format: Luhn on first 9 digits\n if (!luhnValidate(v.slice(0, 9))) {\n return err(\n \"INVALID_CHECKSUM\",\n \"NPWP Luhn check on first 9 digits failed\",\n );\n }\n return { valid: true, compact: v };\n }\n if (v.length === 16) {\n if (v[0] !== \"0\") {\n // NIK format\n return validateNik(v);\n }\n // 0-prefixed legacy: Luhn on first 10 digits\n if (!luhnValidate(v.slice(0, 10))) {\n return err(\n \"INVALID_CHECKSUM\",\n \"NPWP Luhn check on first 10 digits failed\",\n );\n }\n return { valid: true, compact: v };\n }\n return err(\n \"INVALID_LENGTH\",\n \"NPWP must be 15 or 16 digits\",\n );\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n if (v.length === 16) {\n // NIK or 0-prefixed legacy: no standard mask\n return v;\n }\n return (\n `${v.slice(0, 2)}.${v.slice(2, 5)}.` +\n `${v.slice(5, 8)}.${v.slice(8, 9)}` +\n `-${v.slice(9, 12)}.${v.slice(12)}`\n );\n};\n\n/** Generate a random valid 15-digit NPWP. */\nconst generate = (): string => {\n for (;;) {\n const p = randomDigits(8);\n const cs = luhnChecksum(p + \"0\");\n const c = p + String((10 - cs) % 10) + randomDigits(6);\n if (validate(c).valid) return c;\n }\n};\n\n/** Indonesian Taxpayer Identification Number. */\nconst npwp: CountryValidator<\"ID\"> = {\n name: \"Indonesian Taxpayer Identification Number\",\n localName: \"Nomor Pokok Wajib Pajak\",\n abbreviation: \"NPWP\",\n aliases: [\"NPWP\", \"Nomor Pokok Wajib Pajak\"] as const,\n candidatePattern:\n \"\\\\d{2}\\\\.?\\\\d{3}\\\\.?\\\\d{3}\\\\.?\\\\d-?\\\\d{3}\\\\.?\\\\d{3}\",\n scope: \"country\",\n country: \"ID\",\n entityType: \"any\",\n lengths: [15, 16],\n examples: [\"013000666091000\", \"016090524017000\"],\n description:\n \"15 or 16-digit tax identification number issued by \" +\n \"the Directorate General of Taxes\",\n sourceUrl:\n \"https://en.wikipedia.org/wiki/\" +\n \"Tax_identification_number#Indonesia\",\n compact,\n format,\n validate,\n generate,\n};\n\nexport default npwp;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;AA2BA,MAAM,WAAW,UACf,MAAM,OAAO,KAAK;;;;;AAMpB,MAAM,gBAAgB,IAAI,IAAI;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;;;;AASD,MAAM,eAAe,MAA8B;CAEjD,IAAI,CAAC,cAAc,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,GAClC,OAAO,IACL,qBACA,8BACF;CAEF,IAAI,MAAM,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC9B,MAAM,QAAQ,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;CACnC,MAAM,OAAO,OAAO,EAAE,MAAM,IAAI,EAAE,CAAC;CAEnC,IAAI,MAAM,IAAI,OAAO;CAErB,IACE,CAAC,YAAY,OAAO,MAAM,OAAO,GAAG,KACpC,CAAC,YAAY,MAAO,MAAM,OAAO,GAAG,GAEpC,OAAO,IACL,qBACA,8BACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,+BACF;CAEF,IAAI,EAAE,WAAW,IAAI;EAEnB,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,CAAC,CAAC,GAC7B,OAAO,IACL,oBACA,0CACF;EAEF,OAAO;GAAE,OAAO;GAAM,SAAS;EAAE;CACnC;CACA,IAAI,EAAE,WAAW,IAAI;EACnB,IAAI,EAAE,OAAO,KAEX,OAAO,YAAY,CAAC;EAGtB,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,EAAE,CAAC,GAC9B,OAAO,IACL,oBACA,2CACF;EAEF,OAAO;GAAE,OAAO;GAAM,SAAS;EAAE;CACnC;CACA,OAAO,IACL,kBACA,8BACF;AACF;AAEA,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,IAEf,OAAO;CAET,OACE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAC/B,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAA,GAC5B,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE;AAEpC;;AAGA,MAAM,iBAAyB;CAC7B,SAAS;EACP,MAAM,IAAI,aAAa,CAAC;EACxB,MAAM,KAAK,aAAa,IAAI,GAAG;EAC/B,MAAM,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAE,IAAI,aAAa,CAAC;EACrD,IAAI,SAAS,CAAC,CAAC,CAAC,OAAO,OAAO;CAChC;AACF;;AAGA,MAAM,OAA+B;CACnC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,QAAQ,yBAAyB;CAC3C,kBACE;CACF,OAAO;CACP,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,IAAI,EAAE;CAChB,UAAU,CAAC,mBAAmB,iBAAiB;CAC/C,aACE;CAEF,WACE;CAEF;CACA;CACA;CACA;AACF"}
|
package/dist/ie/pps.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pps.js","names":[],"sources":["../../src/ie/pps.ts"],"sourcesContent":["/**\n * PPS (Personal Public Service Number).\n *\n * Irish personal identification number. 7 digits\n * followed by a check letter and an optional second\n * letter (new format). Uses a weighted sum with\n * alphabet \"WABCDEFGHIJKLMNOPQRSTUV\".\n *\n * @see https://www.gov.ie/en/service/12e6de-get-a-personal-public-service-pps-number/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst ALPHABET = \"WABCDEFGHIJKLMNOPQRSTUV\";\n\nconst compact = (value: string): string =>\n clean(value, \" -\").toUpperCase();\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length < 8 || v.length > 9) {\n return err(\n \"INVALID_LENGTH\",\n \"PPS must be 8 or 9 characters\",\n );\n }\n\n const digits = v.slice(0, 7);\n if (!isdigits(digits)) {\n return err(\n \"INVALID_FORMAT\",\n \"PPS must start with 7 digits\",\n );\n }\n\n const checkLetter = v[7];\n const secondLetter = v.length >= 9 ? v[8] : undefined;\n\n // Compute weighted sum: weights 8..2 for digits\n let sum = 0;\n for (let i = 0; i < 7; i++) {\n sum += Number(digits[i]) * (8 - i);\n }\n\n // New format: add 9 * index of 2nd letter\n if (secondLetter !== undefined && secondLetter !== \"W\") {\n const idx = ALPHABET.indexOf(secondLetter);\n if (idx === -1) {\n return err(\n \"INVALID_FORMAT\",\n \"PPS second letter is invalid\",\n );\n }\n sum += 9 * idx;\n }\n\n const remainder = sum % 23;\n const expected = ALPHABET[remainder];\n if (checkLetter !== expected) {\n return err(\n \"INVALID_CHECKSUM\",\n \"PPS check letter does not match\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid Irish PPS number. */\nconst generate = (): string => {\n for (;;) {\n for (let c = 65; c <= 90; c++) {\n const cand = randomDigits(7) + String.fromCharCode(c);\n if (validate(cand).valid) return compact(cand);\n }\n }\n};\n\n/** Irish Personal Public Service Number. */\nconst pps: CountryValidator<\"IE\"> = {\n name: \"Irish Personal ID\",\n localName: \"Personal Public Service Number\",\n abbreviation: \"PPS\",\n aliases: [\"PPS number\", \"PPSN\", \"RSI number\"] as const,\n candidatePattern: \"\\\\d{7}[A-Z]{1,2}\",\n scope: \"country\",\n country: \"IE\",\n entityType: \"person\",\n sourceUrl:\n \"https://www.gov.ie/en/service/12e6de-get-a-personal-public-service-pps-number/\",\n examples: [\"6433435F\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default pps;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;AAqBA,MAAM,WAAW;AAEjB,MAAM,WAAW,UACf,MAAM,OAAO,IAAI,
|
|
1
|
+
{"version":3,"file":"pps.js","names":[],"sources":["../../src/ie/pps.ts"],"sourcesContent":["/**\n * PPS (Personal Public Service Number).\n *\n * Irish personal identification number. 7 digits\n * followed by a check letter and an optional second\n * letter (new format). Uses a weighted sum with\n * alphabet \"WABCDEFGHIJKLMNOPQRSTUV\".\n *\n * @see https://www.gov.ie/en/service/12e6de-get-a-personal-public-service-pps-number/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst ALPHABET = \"WABCDEFGHIJKLMNOPQRSTUV\";\n\nconst compact = (value: string): string =>\n clean(value, \" -\").toUpperCase();\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length < 8 || v.length > 9) {\n return err(\n \"INVALID_LENGTH\",\n \"PPS must be 8 or 9 characters\",\n );\n }\n\n const digits = v.slice(0, 7);\n if (!isdigits(digits)) {\n return err(\n \"INVALID_FORMAT\",\n \"PPS must start with 7 digits\",\n );\n }\n\n const checkLetter = v[7];\n const secondLetter = v.length >= 9 ? v[8] : undefined;\n\n // Compute weighted sum: weights 8..2 for digits\n let sum = 0;\n for (let i = 0; i < 7; i++) {\n sum += Number(digits[i]) * (8 - i);\n }\n\n // New format: add 9 * index of 2nd letter\n if (secondLetter !== undefined && secondLetter !== \"W\") {\n const idx = ALPHABET.indexOf(secondLetter);\n if (idx === -1) {\n return err(\n \"INVALID_FORMAT\",\n \"PPS second letter is invalid\",\n );\n }\n sum += 9 * idx;\n }\n\n const remainder = sum % 23;\n const expected = ALPHABET[remainder];\n if (checkLetter !== expected) {\n return err(\n \"INVALID_CHECKSUM\",\n \"PPS check letter does not match\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid Irish PPS number. */\nconst generate = (): string => {\n for (;;) {\n for (let c = 65; c <= 90; c++) {\n const cand = randomDigits(7) + String.fromCharCode(c);\n if (validate(cand).valid) return compact(cand);\n }\n }\n};\n\n/** Irish Personal Public Service Number. */\nconst pps: CountryValidator<\"IE\"> = {\n name: \"Irish Personal ID\",\n localName: \"Personal Public Service Number\",\n abbreviation: \"PPS\",\n aliases: [\"PPS number\", \"PPSN\", \"RSI number\"] as const,\n candidatePattern: \"\\\\d{7}[A-Z]{1,2}\",\n scope: \"country\",\n country: \"IE\",\n entityType: \"person\",\n sourceUrl:\n \"https://www.gov.ie/en/service/12e6de-get-a-personal-public-service-pps-number/\",\n examples: [\"6433435F\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default pps;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;AAqBA,MAAM,WAAW;AAEjB,MAAM,WAAW,UACf,MAAM,OAAO,IAAI,CAAC,CAAC,YAAY;AAEjC,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,SAAS,KAAK,EAAE,SAAS,GAC7B,OAAO,IACL,kBACA,+BACF;CAGF,MAAM,SAAS,EAAE,MAAM,GAAG,CAAC;CAC3B,IAAI,CAAC,SAAS,MAAM,GAClB,OAAO,IACL,kBACA,8BACF;CAGF,MAAM,cAAc,EAAE;CACtB,MAAM,eAAe,EAAE,UAAU,IAAI,EAAE,KAAK,KAAA;CAG5C,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,OAAO,OAAO,OAAO,EAAE,KAAK,IAAI;CAIlC,IAAI,iBAAiB,KAAA,KAAa,iBAAiB,KAAK;EACtD,MAAM,MAAM,SAAS,QAAQ,YAAY;EACzC,IAAI,QAAQ,IACV,OAAO,IACL,kBACA,8BACF;EAEF,OAAO,IAAI;CACb;CAIA,IAAI,gBADa,SADC,MAAM,KAGtB,OAAO,IACL,oBACA,iCACF;CAGF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B,QAAQ,KAAK;;AAGvD,MAAM,iBAAyB;CAC7B,SACE,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK;EAC7B,MAAM,OAAO,aAAa,CAAC,IAAI,OAAO,aAAa,CAAC;EACpD,IAAI,SAAS,IAAI,CAAC,CAAC,OAAO,OAAO,QAAQ,IAAI;CAC/C;AAEJ;;AAGA,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EAAC;EAAc;EAAQ;CAAY;CAC5C,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WACE;CACF,UAAU,CAAC,UAAU;CACrB;CACA;CACA;CACA;AACF"}
|
package/dist/ie/vat.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vat.js","names":[],"sources":["../../src/ie/vat.ts"],"sourcesContent":["/**\n * VAT (Irish VAT number).\n *\n * 8-9 characters, complex format with old and new\n * styles.\n *\n * @see https://www.vatify.eu/ireland-vat-number.html\n * @see https://www.revenue.ie/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst ALPHABET = \"WABCDEFGHIJKLMNOPQRSTUV\";\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -/.\");\n if (v.startsWith(\"IE\") || v.startsWith(\"ie\")) {\n v = v.slice(2);\n }\n return v.toUpperCase();\n};\n\nconst checkNew = (v: string): boolean => {\n // New format: 7 digits + check letter + optional\n // trailing letter (W or A-Z)\n const trailing = v.length === 9 ? v.charAt(8) : \"W\";\n let sum = 0;\n for (let i = 0; i < 7; i++) {\n sum += (8 - i) * Number(v.charAt(i));\n }\n sum += 9 * ALPHABET.indexOf(trailing);\n const expected = ALPHABET.charAt(sum % 23);\n return v.charAt(7) === expected;\n};\n\nconst checkOld = (v: string): boolean => {\n // Old format: digit + letter + 5 digits +\n // check letter (8 chars total).\n // Rearrange to 7-digit new-style layout:\n // 0 + d[2..6] + d[0]\n const rearranged = `0${v.slice(2, 7)}${v.charAt(0)}`;\n let sum = 0;\n for (let i = 0; i < 7; i++) {\n sum += (8 - i) * Number(rearranged.charAt(i));\n }\n const expected = ALPHABET.charAt(sum % 23);\n return v.charAt(7) === expected;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 8 && v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"Irish VAT number must be 8 or 9 characters\",\n );\n }\n\n // New format: 7 digits + letter [+ letter]\n if (\n isdigits(v.slice(0, 7)) &&\n /^[A-Z]$/.test(v.charAt(7))\n ) {\n if (v.length === 9 && !/^[A-Z+*]$/.test(v.charAt(8))) {\n return err(\n \"INVALID_FORMAT\",\n \"Irish VAT trailing character must be a letter\",\n );\n }\n if (!checkNew(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Irish VAT number check letter mismatch\",\n );\n }\n return { valid: true, compact: v };\n }\n\n // Old format: digit + letter + 5 digits + letter\n if (\n v.length === 8 &&\n /^\\d$/.test(v.charAt(0)) &&\n /^[A-Z+*]$/.test(v.charAt(1)) &&\n isdigits(v.slice(2, 7)) &&\n /^[A-Z]$/.test(v.charAt(7))\n ) {\n if (!checkOld(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Irish VAT number check letter mismatch\",\n );\n }\n return { valid: true, compact: v };\n }\n\n return err(\n \"INVALID_FORMAT\",\n \"Irish VAT number has invalid format\",\n );\n};\n\nconst format = (value: string): string =>\n `IE${compact(value)}`;\n\n/** Generate a random valid Irish VAT number. */\nconst generate = (): string => {\n for (;;) {\n for (let c = 65; c <= 90; c++) {\n const cand = randomDigits(7) + String.fromCharCode(c);\n if (validate(cand).valid) return compact(cand);\n }\n }\n};\n\n/** Irish VAT Number. */\nconst vat: CountryValidator<\"IE\"> = {\n name: \"Irish VAT Number\",\n localName: \"Value Added Tax Number\",\n abbreviation: \"VAT\",\n aliases: [\"VAT number IE\"] as const,\n candidatePattern: \"IE\\\\d[A-Z+*]\\\\d{5}[A-Z]\",\n scope: \"country\",\n country: \"IE\",\n entityType: \"any\",\n sourceUrl: \"https://www.revenue.ie/\",\n examples: [\"6433435F\", \"8D79739I\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default vat;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;AAoBA,MAAM,WAAW;AAEjB,MAAM,WAAW,UAA0B;CACzC,IAAI,IAAI,MAAM,OAAO,MAAM;CAC3B,IAAI,EAAE,WAAW,IAAI,KAAK,EAAE,WAAW,IAAI,GACzC,IAAI,EAAE,MAAM,CAAC;CAEf,OAAO,EAAE,YAAY;AACvB;AAEA,MAAM,YAAY,MAAuB;CAGvC,MAAM,WAAW,EAAE,WAAW,IAAI,EAAE,OAAO,CAAC,IAAI;CAChD,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,QAAQ,IAAI,KAAK,OAAO,EAAE,OAAO,CAAC,CAAC;CAErC,OAAO,IAAI,SAAS,QAAQ,QAAQ;CACpC,MAAM,WAAW,SAAS,OAAO,MAAM,EAAE;CACzC,OAAO,EAAE,OAAO,CAAC,MAAM;AACzB;AAEA,MAAM,YAAY,MAAuB;CAKvC,MAAM,aAAa,IAAI,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC;CACjD,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,QAAQ,IAAI,KAAK,OAAO,WAAW,OAAO,CAAC,CAAC;CAE9C,MAAM,WAAW,SAAS,OAAO,MAAM,EAAE;CACzC,OAAO,EAAE,OAAO,CAAC,MAAM;AACzB;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,KAAK,EAAE,WAAW,GACjC,OAAO,IACL,kBACA,4CACF;CAIF,IACE,SAAS,EAAE,MAAM,GAAG,CAAC,CAAC,KACtB,UAAU,KAAK,EAAE,OAAO,CAAC,CAAC,GAC1B;EACA,IAAI,EAAE,WAAW,KAAK,CAAC,YAAY,KAAK,EAAE,OAAO,CAAC,CAAC,GACjD,OAAO,IACL,kBACA,+CACF;EAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,oBACA,wCACF;EAEF,OAAO;GAAE,OAAO;GAAM,SAAS;EAAE;CACnC;CAGA,IACE,EAAE,WAAW,KACb,OAAO,KAAK,EAAE,OAAO,CAAC,CAAC,KACvB,YAAY,KAAK,EAAE,OAAO,CAAC,CAAC,KAC5B,SAAS,EAAE,MAAM,GAAG,CAAC,CAAC,KACtB,UAAU,KAAK,EAAE,OAAO,CAAC,CAAC,GAC1B;EACA,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,oBACA,wCACF;EAEF,OAAO;GAAE,OAAO;GAAM,SAAS;EAAE;CACnC;CAEA,OAAO,IACL,kBACA,qCACF;AACF;AAEA,MAAM,UAAU,UACd,KAAK,QAAQ,KAAK;;AAGpB,MAAM,iBAAyB;CAC7B,SACE,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK;EAC7B,MAAM,OAAO,aAAa,CAAC,IAAI,OAAO,aAAa,CAAC;EACpD,IAAI,SAAS,IAAI,
|
|
1
|
+
{"version":3,"file":"vat.js","names":[],"sources":["../../src/ie/vat.ts"],"sourcesContent":["/**\n * VAT (Irish VAT number).\n *\n * 8-9 characters, complex format with old and new\n * styles.\n *\n * @see https://www.vatify.eu/ireland-vat-number.html\n * @see https://www.revenue.ie/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst ALPHABET = \"WABCDEFGHIJKLMNOPQRSTUV\";\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -/.\");\n if (v.startsWith(\"IE\") || v.startsWith(\"ie\")) {\n v = v.slice(2);\n }\n return v.toUpperCase();\n};\n\nconst checkNew = (v: string): boolean => {\n // New format: 7 digits + check letter + optional\n // trailing letter (W or A-Z)\n const trailing = v.length === 9 ? v.charAt(8) : \"W\";\n let sum = 0;\n for (let i = 0; i < 7; i++) {\n sum += (8 - i) * Number(v.charAt(i));\n }\n sum += 9 * ALPHABET.indexOf(trailing);\n const expected = ALPHABET.charAt(sum % 23);\n return v.charAt(7) === expected;\n};\n\nconst checkOld = (v: string): boolean => {\n // Old format: digit + letter + 5 digits +\n // check letter (8 chars total).\n // Rearrange to 7-digit new-style layout:\n // 0 + d[2..6] + d[0]\n const rearranged = `0${v.slice(2, 7)}${v.charAt(0)}`;\n let sum = 0;\n for (let i = 0; i < 7; i++) {\n sum += (8 - i) * Number(rearranged.charAt(i));\n }\n const expected = ALPHABET.charAt(sum % 23);\n return v.charAt(7) === expected;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 8 && v.length !== 9) {\n return err(\n \"INVALID_LENGTH\",\n \"Irish VAT number must be 8 or 9 characters\",\n );\n }\n\n // New format: 7 digits + letter [+ letter]\n if (\n isdigits(v.slice(0, 7)) &&\n /^[A-Z]$/.test(v.charAt(7))\n ) {\n if (v.length === 9 && !/^[A-Z+*]$/.test(v.charAt(8))) {\n return err(\n \"INVALID_FORMAT\",\n \"Irish VAT trailing character must be a letter\",\n );\n }\n if (!checkNew(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Irish VAT number check letter mismatch\",\n );\n }\n return { valid: true, compact: v };\n }\n\n // Old format: digit + letter + 5 digits + letter\n if (\n v.length === 8 &&\n /^\\d$/.test(v.charAt(0)) &&\n /^[A-Z+*]$/.test(v.charAt(1)) &&\n isdigits(v.slice(2, 7)) &&\n /^[A-Z]$/.test(v.charAt(7))\n ) {\n if (!checkOld(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Irish VAT number check letter mismatch\",\n );\n }\n return { valid: true, compact: v };\n }\n\n return err(\n \"INVALID_FORMAT\",\n \"Irish VAT number has invalid format\",\n );\n};\n\nconst format = (value: string): string =>\n `IE${compact(value)}`;\n\n/** Generate a random valid Irish VAT number. */\nconst generate = (): string => {\n for (;;) {\n for (let c = 65; c <= 90; c++) {\n const cand = randomDigits(7) + String.fromCharCode(c);\n if (validate(cand).valid) return compact(cand);\n }\n }\n};\n\n/** Irish VAT Number. */\nconst vat: CountryValidator<\"IE\"> = {\n name: \"Irish VAT Number\",\n localName: \"Value Added Tax Number\",\n abbreviation: \"VAT\",\n aliases: [\"VAT number IE\"] as const,\n candidatePattern: \"IE\\\\d[A-Z+*]\\\\d{5}[A-Z]\",\n scope: \"country\",\n country: \"IE\",\n entityType: \"any\",\n sourceUrl: \"https://www.revenue.ie/\",\n examples: [\"6433435F\", \"8D79739I\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default vat;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;AAoBA,MAAM,WAAW;AAEjB,MAAM,WAAW,UAA0B;CACzC,IAAI,IAAI,MAAM,OAAO,MAAM;CAC3B,IAAI,EAAE,WAAW,IAAI,KAAK,EAAE,WAAW,IAAI,GACzC,IAAI,EAAE,MAAM,CAAC;CAEf,OAAO,EAAE,YAAY;AACvB;AAEA,MAAM,YAAY,MAAuB;CAGvC,MAAM,WAAW,EAAE,WAAW,IAAI,EAAE,OAAO,CAAC,IAAI;CAChD,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,QAAQ,IAAI,KAAK,OAAO,EAAE,OAAO,CAAC,CAAC;CAErC,OAAO,IAAI,SAAS,QAAQ,QAAQ;CACpC,MAAM,WAAW,SAAS,OAAO,MAAM,EAAE;CACzC,OAAO,EAAE,OAAO,CAAC,MAAM;AACzB;AAEA,MAAM,YAAY,MAAuB;CAKvC,MAAM,aAAa,IAAI,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC;CACjD,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,QAAQ,IAAI,KAAK,OAAO,WAAW,OAAO,CAAC,CAAC;CAE9C,MAAM,WAAW,SAAS,OAAO,MAAM,EAAE;CACzC,OAAO,EAAE,OAAO,CAAC,MAAM;AACzB;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,KAAK,EAAE,WAAW,GACjC,OAAO,IACL,kBACA,4CACF;CAIF,IACE,SAAS,EAAE,MAAM,GAAG,CAAC,CAAC,KACtB,UAAU,KAAK,EAAE,OAAO,CAAC,CAAC,GAC1B;EACA,IAAI,EAAE,WAAW,KAAK,CAAC,YAAY,KAAK,EAAE,OAAO,CAAC,CAAC,GACjD,OAAO,IACL,kBACA,+CACF;EAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,oBACA,wCACF;EAEF,OAAO;GAAE,OAAO;GAAM,SAAS;EAAE;CACnC;CAGA,IACE,EAAE,WAAW,KACb,OAAO,KAAK,EAAE,OAAO,CAAC,CAAC,KACvB,YAAY,KAAK,EAAE,OAAO,CAAC,CAAC,KAC5B,SAAS,EAAE,MAAM,GAAG,CAAC,CAAC,KACtB,UAAU,KAAK,EAAE,OAAO,CAAC,CAAC,GAC1B;EACA,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,oBACA,wCACF;EAEF,OAAO;GAAE,OAAO;GAAM,SAAS;EAAE;CACnC;CAEA,OAAO,IACL,kBACA,qCACF;AACF;AAEA,MAAM,UAAU,UACd,KAAK,QAAQ,KAAK;;AAGpB,MAAM,iBAAyB;CAC7B,SACE,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK;EAC7B,MAAM,OAAO,aAAa,CAAC,IAAI,OAAO,aAAa,CAAC;EACpD,IAAI,SAAS,IAAI,CAAC,CAAC,OAAO,OAAO,QAAQ,IAAI;CAC/C;AAEJ;;AAGA,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,eAAe;CACzB,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,YAAY,UAAU;CACjC;CACA;CACA;CACA;AACF"}
|
package/dist/il/idnr.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idnr.js","names":[],"sources":["../../src/il/idnr.ts"],"sourcesContent":["/**\n * Identity Number (Mispar Zehut, מספר זהות).\n *\n * Israeli personal identity number. 9 digits\n * (zero-padded) with a Luhn checksum.\n *\n * @see https://en.wikipedia.org/wiki/Israeli_identity_card\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport {\n luhnValidate,\n luhnChecksum,\n} from \"#checksums/luhn\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst compact = (value: string): string =>\n clean(value, \" -\").padStart(9, \"0\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length > 9) {\n return err(\n \"INVALID_LENGTH\",\n \"Israeli ID must be at most 9 digits\",\n );\n }\n if (!isdigits(v) || Number(v) === 0) {\n return err(\n \"INVALID_FORMAT\",\n \"Israeli ID must contain only digits\" +\n \" and not be zero\",\n );\n }\n if (!luhnValidate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Israeli ID Luhn 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, -1)}-${v.slice(-1)}`;\n};\n\n/** Generate a random valid Israeli ID number. */\nconst generate = (): string => {\n const payload = randomDigits(8);\n const cs = luhnChecksum(payload + \"0\");\n return payload + String((10 - cs) % 10);\n};\n\n/** Israeli Identity Number (Mispar Zehut). */\nconst idnr: CountryValidator<\"IL\"> = {\n name: \"Israeli Identity Number\",\n localName: \"מספר זהות\",\n abbreviation: \"ת.ז.\",\n aliases: [\n \"תעודת זהות\",\n \"Teudat Zehut\",\n \"ID number\",\n ] as const,\n candidatePattern: \"\\\\d{9}\",\n scope: \"country\",\n country: \"IL\",\n entityType: \"person\",\n compact,\n format,\n validate,\n description:\n \"Israeli personal identification number\" +\n \" (Mispar Zehut)\",\n sourceUrl:\n \"https://en.wikipedia.org/wiki/Israeli_identity_card\",\n lengths: [9] as const,\n examples: [\"039337423\", \"000000018\"] as const,\n generate,\n};\n\nexport default idnr;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AAuBA,MAAM,WAAW,UACf,MAAM,OAAO,IAAI,
|
|
1
|
+
{"version":3,"file":"idnr.js","names":[],"sources":["../../src/il/idnr.ts"],"sourcesContent":["/**\n * Identity Number (Mispar Zehut, מספר זהות).\n *\n * Israeli personal identity number. 9 digits\n * (zero-padded) with a Luhn checksum.\n *\n * @see https://en.wikipedia.org/wiki/Israeli_identity_card\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport {\n luhnValidate,\n luhnChecksum,\n} from \"#checksums/luhn\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst compact = (value: string): string =>\n clean(value, \" -\").padStart(9, \"0\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length > 9) {\n return err(\n \"INVALID_LENGTH\",\n \"Israeli ID must be at most 9 digits\",\n );\n }\n if (!isdigits(v) || Number(v) === 0) {\n return err(\n \"INVALID_FORMAT\",\n \"Israeli ID must contain only digits\" +\n \" and not be zero\",\n );\n }\n if (!luhnValidate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Israeli ID Luhn 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, -1)}-${v.slice(-1)}`;\n};\n\n/** Generate a random valid Israeli ID number. */\nconst generate = (): string => {\n const payload = randomDigits(8);\n const cs = luhnChecksum(payload + \"0\");\n return payload + String((10 - cs) % 10);\n};\n\n/** Israeli Identity Number (Mispar Zehut). */\nconst idnr: CountryValidator<\"IL\"> = {\n name: \"Israeli Identity Number\",\n localName: \"מספר זהות\",\n abbreviation: \"ת.ז.\",\n aliases: [\n \"תעודת זהות\",\n \"Teudat Zehut\",\n \"ID number\",\n ] as const,\n candidatePattern: \"\\\\d{9}\",\n scope: \"country\",\n country: \"IL\",\n entityType: \"person\",\n compact,\n format,\n validate,\n description:\n \"Israeli personal identification number\" +\n \" (Mispar Zehut)\",\n sourceUrl:\n \"https://en.wikipedia.org/wiki/Israeli_identity_card\",\n lengths: [9] as const,\n examples: [\"039337423\", \"000000018\"] as const,\n generate,\n};\n\nexport default idnr;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AAuBA,MAAM,WAAW,UACf,MAAM,OAAO,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG;AAEpC,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,SAAS,GACb,OAAO,IACL,kBACA,qCACF;CAEF,IAAI,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,MAAM,GAChC,OAAO,IACL,kBACA,qDAEF;CAEF,IAAI,CAAC,aAAa,CAAC,GACjB,OAAO,IACL,oBACA,sCACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,KAAK;CACvB,OAAO,GAAG,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE;AACxC;;AAGA,MAAM,iBAAyB;CAC7B,MAAM,UAAU,aAAa,CAAC;CAC9B,MAAM,KAAK,aAAa,UAAU,GAAG;CACrC,OAAO,UAAU,QAAQ,KAAK,MAAM,EAAE;AACxC;;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;CACA;CACA;CACA,aACE;CAEF,WACE;CACF,SAAS,CAAC,CAAC;CACX,UAAU,CAAC,aAAa,WAAW;CACnC;AACF"}
|
package/dist/in/aadhaar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aadhaar.js","names":[],"sources":["../../src/in/aadhaar.ts"],"sourcesContent":["/**\n * Aadhaar (Indian unique identity number).\n *\n * 12 digits with Verhoeff checksum (last digit).\n * Cannot start with 0 or 1.\n * Issued by the Unique Identification Authority\n * of India (UIDAI).\n *\n * @see https://en.wikipedia.org/wiki/Aadhaar\n * @see https://uidai.gov.in/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport {\n verhoeffValidate,\n verhoeffCheckDigit,\n} from \"#checksums/verhoeff\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 12) {\n return err(\n \"INVALID_LENGTH\",\n \"Aadhaar must be 12 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Aadhaar must contain only digits\",\n );\n }\n if (v[0] === \"0\" || v[0] === \"1\") {\n return err(\n \"INVALID_COMPONENT\",\n \"Aadhaar cannot start with 0 or 1\",\n );\n }\n // Aadhaar cannot be a palindrome\n if (v === v.split(\"\").reverse().join(\"\")) {\n return err(\n \"INVALID_FORMAT\",\n \"Aadhaar cannot be a palindrome\",\n );\n }\n if (!verhoeffValidate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Aadhaar 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, 4)} ${v.slice(4, 8)} ${v.slice(8)}`;\n};\n\n/** Generate a random valid Aadhaar number. */\nconst generate = (): string => {\n const first = String(randomInt(2, 9));\n const payload = first + randomDigits(10);\n return payload + String(verhoeffCheckDigit(payload));\n};\n\n/** Indian Unique Identity Number. */\nconst aadhaar: CountryValidator<\"IN\"> = {\n name: \"Indian Unique Identity Number\",\n localName: \"Aadhaar\",\n abbreviation: \"Aadhaar\",\n aliases: [\"Aadhaar\", \"आधार\"] as const,\n candidatePattern: \"\\\\d{4}\\\\s?\\\\d{4}\\\\s?\\\\d{4}\",\n scope: \"country\",\n country: \"IN\",\n entityType: \"person\",\n lengths: [12],\n examples: [\"234123412346\", \"295274982189\"],\n description:\n \"12-digit unique identity number issued by UIDAI\",\n sourceUrl: \"https://uidai.gov.in/\",\n compact,\n format,\n validate,\n generate,\n};\n\nexport default aadhaar;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AA0BA,MAAM,WAAW,UACf,MAAM,OAAO,IAAI;AAEnB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,IACf,OAAO,IACL,kBACA,2BACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,kCACF;CAEF,IAAI,EAAE,OAAO,OAAO,EAAE,OAAO,KAC3B,OAAO,IACL,qBACA,kCACF;CAGF,IAAI,MAAM,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"aadhaar.js","names":[],"sources":["../../src/in/aadhaar.ts"],"sourcesContent":["/**\n * Aadhaar (Indian unique identity number).\n *\n * 12 digits with Verhoeff checksum (last digit).\n * Cannot start with 0 or 1.\n * Issued by the Unique Identification Authority\n * of India (UIDAI).\n *\n * @see https://en.wikipedia.org/wiki/Aadhaar\n * @see https://uidai.gov.in/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport {\n verhoeffValidate,\n verhoeffCheckDigit,\n} from \"#checksums/verhoeff\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst compact = (value: string): string =>\n clean(value, \" -\");\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 12) {\n return err(\n \"INVALID_LENGTH\",\n \"Aadhaar must be 12 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Aadhaar must contain only digits\",\n );\n }\n if (v[0] === \"0\" || v[0] === \"1\") {\n return err(\n \"INVALID_COMPONENT\",\n \"Aadhaar cannot start with 0 or 1\",\n );\n }\n // Aadhaar cannot be a palindrome\n if (v === v.split(\"\").reverse().join(\"\")) {\n return err(\n \"INVALID_FORMAT\",\n \"Aadhaar cannot be a palindrome\",\n );\n }\n if (!verhoeffValidate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Aadhaar 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, 4)} ${v.slice(4, 8)} ${v.slice(8)}`;\n};\n\n/** Generate a random valid Aadhaar number. */\nconst generate = (): string => {\n const first = String(randomInt(2, 9));\n const payload = first + randomDigits(10);\n return payload + String(verhoeffCheckDigit(payload));\n};\n\n/** Indian Unique Identity Number. */\nconst aadhaar: CountryValidator<\"IN\"> = {\n name: \"Indian Unique Identity Number\",\n localName: \"Aadhaar\",\n abbreviation: \"Aadhaar\",\n aliases: [\"Aadhaar\", \"आधार\"] as const,\n candidatePattern: \"\\\\d{4}\\\\s?\\\\d{4}\\\\s?\\\\d{4}\",\n scope: \"country\",\n country: \"IN\",\n entityType: \"person\",\n lengths: [12],\n examples: [\"234123412346\", \"295274982189\"],\n description:\n \"12-digit unique identity number issued by UIDAI\",\n sourceUrl: \"https://uidai.gov.in/\",\n compact,\n format,\n validate,\n generate,\n};\n\nexport default aadhaar;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AA0BA,MAAM,WAAW,UACf,MAAM,OAAO,IAAI;AAEnB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,IACf,OAAO,IACL,kBACA,2BACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,kCACF;CAEF,IAAI,EAAE,OAAO,OAAO,EAAE,OAAO,KAC3B,OAAO,IACL,qBACA,kCACF;CAGF,IAAI,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,GACrC,OAAO,IACL,kBACA,gCACF;CAEF,IAAI,CAAC,iBAAiB,CAAC,GACrB,OAAO,IACL,oBACA,8BACF;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,CAAC;AACvD;;AAGA,MAAM,iBAAyB;CAE7B,MAAM,UADQ,OAAO,UAAU,GAAG,CAAC,CACf,IAAI,aAAa,EAAE;CACvC,OAAO,UAAU,OAAO,mBAAmB,OAAO,CAAC;AACrD;;AAGA,MAAM,UAAkC;CACtC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,WAAW,MAAM;CAC3B,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,EAAE;CACZ,UAAU,CAAC,gBAAgB,cAAc;CACzC,aACE;CACF,WAAW;CACX;CACA;CACA;CACA;AACF"}
|
package/dist/in/gstin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gstin.js","names":[],"sources":["../../src/in/gstin.ts"],"sourcesContent":["/**\n * GSTIN (Goods and Services Tax Identification\n * Number, India).\n *\n * 15 characters: 2-digit state code + 10-char PAN +\n * 1 entity number (1-9, A-Z) + \"Z\" + 1 check digit.\n * Check digit uses the Luhn mod 36 algorithm.\n *\n * @see https://en.wikipedia.org/wiki/Goods_and_Services_Tax_Identification_Number\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { charValue } from \"#util/strings\";\n\nconst GSTIN_RE =\n /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z][0-9A-Z]Z[0-9A-Z]$/;\n\n/** Valid Indian state/UT codes: 01-37. */\nconst VALID_STATE_CODES = new Set([\n \"01\",\n \"02\",\n \"03\",\n \"04\",\n \"05\",\n \"06\",\n \"07\",\n \"08\",\n \"09\",\n \"10\",\n \"11\",\n \"12\",\n \"13\",\n \"14\",\n \"15\",\n \"16\",\n \"17\",\n \"18\",\n \"19\",\n \"20\",\n \"21\",\n \"22\",\n \"23\",\n \"24\",\n \"25\",\n \"26\",\n \"27\",\n \"28\",\n \"29\",\n \"30\",\n \"31\",\n \"32\",\n \"33\",\n \"34\",\n \"35\",\n \"36\",\n \"37\",\n]);\n\nconst BASE = 36;\n\n/**\n * Luhn mod 36 checksum over the full GSTIN.\n * Returns 0 for a valid number.\n */\nconst luhn36Checksum = (value: string): number => {\n let sum = 0;\n let double = false;\n for (let i = value.length - 1; i >= 0; i--) {\n const ch = value[i];\n if (ch === undefined) continue;\n let v = charValue(ch);\n if (double) {\n v *= 2;\n sum += Math.floor(v / BASE) + (v % BASE);\n } else {\n sum += v;\n }\n double = !double;\n }\n return sum % BASE;\n};\n\nconst compact = (value: string): string =>\n clean(value, \" -\").toUpperCase();\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 15) {\n return err(\n \"INVALID_LENGTH\",\n \"GSTIN must be 15 characters\",\n );\n }\n if (!GSTIN_RE.test(v)) {\n return err(\"INVALID_FORMAT\", \"GSTIN format is invalid\");\n }\n const stateCode = v.slice(0, 2);\n if (!VALID_STATE_CODES.has(stateCode)) {\n return err(\n \"INVALID_COMPONENT\",\n \"GSTIN state code is invalid\",\n );\n }\n if (v[12] === \"0\") {\n return err(\n \"INVALID_COMPONENT\",\n \"GSTIN entity number cannot be 0\",\n );\n }\n if (luhn36Checksum(v) !== 0) {\n return err(\n \"INVALID_CHECKSUM\",\n \"GSTIN check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid GSTIN. */\nconst generate = (): string => {\n for (;;) {\n const state = String(randomInt(1, 37)).padStart(2, \"0\");\n let pan = \"\";\n for (let i = 0; i < 5; i++)\n pan += String.fromCharCode(65 + randomInt(0, 25));\n pan +=\n randomDigits(4) +\n String.fromCharCode(65 + randomInt(0, 25));\n const entity = String(randomInt(1, 9));\n const partial = state + pan + entity + \"Z\";\n for (let d = 0; d <= 9; d++) {\n const c = partial + String(d);\n if (validate(c).valid) return c;\n }\n for (let c = 65; c <= 90; c++) {\n const cand = partial + String.fromCharCode(c);\n if (validate(cand).valid) return cand;\n }\n }\n};\n\n/** Indian Goods and Services Tax ID. */\nconst gstin: CountryValidator<\"IN\"> = {\n name: \"Indian Goods and Services Tax ID\",\n localName: \"Goods and Services Tax Identification Number\",\n abbreviation: \"GSTIN\",\n aliases: [\"GSTIN\", \"GST number\"] as const,\n candidatePattern:\n \"\\\\d{2}[A-Z]{5}\\\\d{4}[A-Z][A-Z\\\\d][Z][A-Z\\\\d]\",\n scope: \"country\",\n country: \"IN\",\n entityType: \"company\",\n lengths: [15],\n examples: [\"27AAPFU0939F1ZV\", \"29AAGCB7383J1Z4\"],\n description:\n \"15-character tax identifier for GST-registered businesses\",\n sourceUrl:\n \"https://en.wikipedia.org/wiki/Goods_and_Services_Tax_Identification_Number\",\n compact,\n format,\n validate,\n generate,\n};\n\nexport default gstin;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;AAqBA,MAAM,WACJ;;AAGF,MAAM,oBAAoB,IAAI,IAAI;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,OAAO;;;;;AAMb,MAAM,kBAAkB,UAA0B;CAChD,IAAI,MAAM;CACV,IAAI,SAAS;CACb,KAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;EAC1C,MAAM,KAAK,MAAM;EACjB,IAAI,OAAO,KAAA,GAAW;EACtB,IAAI,IAAI,UAAU,EAAE;EACpB,IAAI,QAAQ;GACV,KAAK;GACL,OAAO,KAAK,MAAM,IAAI,IAAI,IAAK,IAAI;EACrC,OACE,OAAO;EAET,SAAS,CAAC;CACZ;CACA,OAAO,MAAM;AACf;AAEA,MAAM,WAAW,UACf,MAAM,OAAO,IAAI,
|
|
1
|
+
{"version":3,"file":"gstin.js","names":[],"sources":["../../src/in/gstin.ts"],"sourcesContent":["/**\n * GSTIN (Goods and Services Tax Identification\n * Number, India).\n *\n * 15 characters: 2-digit state code + 10-char PAN +\n * 1 entity number (1-9, A-Z) + \"Z\" + 1 check digit.\n * Check digit uses the Luhn mod 36 algorithm.\n *\n * @see https://en.wikipedia.org/wiki/Goods_and_Services_Tax_Identification_Number\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { charValue } from \"#util/strings\";\n\nconst GSTIN_RE =\n /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z][0-9A-Z]Z[0-9A-Z]$/;\n\n/** Valid Indian state/UT codes: 01-37. */\nconst VALID_STATE_CODES = new Set([\n \"01\",\n \"02\",\n \"03\",\n \"04\",\n \"05\",\n \"06\",\n \"07\",\n \"08\",\n \"09\",\n \"10\",\n \"11\",\n \"12\",\n \"13\",\n \"14\",\n \"15\",\n \"16\",\n \"17\",\n \"18\",\n \"19\",\n \"20\",\n \"21\",\n \"22\",\n \"23\",\n \"24\",\n \"25\",\n \"26\",\n \"27\",\n \"28\",\n \"29\",\n \"30\",\n \"31\",\n \"32\",\n \"33\",\n \"34\",\n \"35\",\n \"36\",\n \"37\",\n]);\n\nconst BASE = 36;\n\n/**\n * Luhn mod 36 checksum over the full GSTIN.\n * Returns 0 for a valid number.\n */\nconst luhn36Checksum = (value: string): number => {\n let sum = 0;\n let double = false;\n for (let i = value.length - 1; i >= 0; i--) {\n const ch = value[i];\n if (ch === undefined) continue;\n let v = charValue(ch);\n if (double) {\n v *= 2;\n sum += Math.floor(v / BASE) + (v % BASE);\n } else {\n sum += v;\n }\n double = !double;\n }\n return sum % BASE;\n};\n\nconst compact = (value: string): string =>\n clean(value, \" -\").toUpperCase();\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 15) {\n return err(\n \"INVALID_LENGTH\",\n \"GSTIN must be 15 characters\",\n );\n }\n if (!GSTIN_RE.test(v)) {\n return err(\"INVALID_FORMAT\", \"GSTIN format is invalid\");\n }\n const stateCode = v.slice(0, 2);\n if (!VALID_STATE_CODES.has(stateCode)) {\n return err(\n \"INVALID_COMPONENT\",\n \"GSTIN state code is invalid\",\n );\n }\n if (v[12] === \"0\") {\n return err(\n \"INVALID_COMPONENT\",\n \"GSTIN entity number cannot be 0\",\n );\n }\n if (luhn36Checksum(v) !== 0) {\n return err(\n \"INVALID_CHECKSUM\",\n \"GSTIN check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Generate a random valid GSTIN. */\nconst generate = (): string => {\n for (;;) {\n const state = String(randomInt(1, 37)).padStart(2, \"0\");\n let pan = \"\";\n for (let i = 0; i < 5; i++)\n pan += String.fromCharCode(65 + randomInt(0, 25));\n pan +=\n randomDigits(4) +\n String.fromCharCode(65 + randomInt(0, 25));\n const entity = String(randomInt(1, 9));\n const partial = state + pan + entity + \"Z\";\n for (let d = 0; d <= 9; d++) {\n const c = partial + String(d);\n if (validate(c).valid) return c;\n }\n for (let c = 65; c <= 90; c++) {\n const cand = partial + String.fromCharCode(c);\n if (validate(cand).valid) return cand;\n }\n }\n};\n\n/** Indian Goods and Services Tax ID. */\nconst gstin: CountryValidator<\"IN\"> = {\n name: \"Indian Goods and Services Tax ID\",\n localName: \"Goods and Services Tax Identification Number\",\n abbreviation: \"GSTIN\",\n aliases: [\"GSTIN\", \"GST number\"] as const,\n candidatePattern:\n \"\\\\d{2}[A-Z]{5}\\\\d{4}[A-Z][A-Z\\\\d][Z][A-Z\\\\d]\",\n scope: \"country\",\n country: \"IN\",\n entityType: \"company\",\n lengths: [15],\n examples: [\"27AAPFU0939F1ZV\", \"29AAGCB7383J1Z4\"],\n description:\n \"15-character tax identifier for GST-registered businesses\",\n sourceUrl:\n \"https://en.wikipedia.org/wiki/Goods_and_Services_Tax_Identification_Number\",\n compact,\n format,\n validate,\n generate,\n};\n\nexport default gstin;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;AAqBA,MAAM,WACJ;;AAGF,MAAM,oBAAoB,IAAI,IAAI;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,OAAO;;;;;AAMb,MAAM,kBAAkB,UAA0B;CAChD,IAAI,MAAM;CACV,IAAI,SAAS;CACb,KAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;EAC1C,MAAM,KAAK,MAAM;EACjB,IAAI,OAAO,KAAA,GAAW;EACtB,IAAI,IAAI,UAAU,EAAE;EACpB,IAAI,QAAQ;GACV,KAAK;GACL,OAAO,KAAK,MAAM,IAAI,IAAI,IAAK,IAAI;EACrC,OACE,OAAO;EAET,SAAS,CAAC;CACZ;CACA,OAAO,MAAM;AACf;AAEA,MAAM,WAAW,UACf,MAAM,OAAO,IAAI,CAAC,CAAC,YAAY;AAEjC,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,IACf,OAAO,IACL,kBACA,6BACF;CAEF,IAAI,CAAC,SAAS,KAAK,CAAC,GAClB,OAAO,IAAI,kBAAkB,yBAAyB;CAExD,MAAM,YAAY,EAAE,MAAM,GAAG,CAAC;CAC9B,IAAI,CAAC,kBAAkB,IAAI,SAAS,GAClC,OAAO,IACL,qBACA,6BACF;CAEF,IAAI,EAAE,QAAQ,KACZ,OAAO,IACL,qBACA,iCACF;CAEF,IAAI,eAAe,CAAC,MAAM,GACxB,OAAO,IACL,oBACA,4BACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B,QAAQ,KAAK;;AAGvD,MAAM,iBAAyB;CAC7B,SAAS;EACP,MAAM,QAAQ,OAAO,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;EACtD,IAAI,MAAM;EACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,OAAO,OAAO,aAAa,KAAK,UAAU,GAAG,EAAE,CAAC;EAClD,OACE,aAAa,CAAC,IACd,OAAO,aAAa,KAAK,UAAU,GAAG,EAAE,CAAC;EAC3C,MAAM,SAAS,OAAO,UAAU,GAAG,CAAC,CAAC;EACrC,MAAM,UAAU,QAAQ,MAAM,SAAS;EACvC,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;GAC3B,MAAM,IAAI,UAAU,OAAO,CAAC;GAC5B,IAAI,SAAS,CAAC,CAAC,CAAC,OAAO,OAAO;EAChC;EACA,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK;GAC7B,MAAM,OAAO,UAAU,OAAO,aAAa,CAAC;GAC5C,IAAI,SAAS,IAAI,CAAC,CAAC,OAAO,OAAO;EACnC;CACF;AACF;;AAGA,MAAM,QAAgC;CACpC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,SAAS,YAAY;CAC/B,kBACE;CACF,OAAO;CACP,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,EAAE;CACZ,UAAU,CAAC,mBAAmB,iBAAiB;CAC/C,aACE;CACF,WACE;CACF;CACA;CACA;CACA;AACF"}
|
package/dist/in/pan.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pan.js","names":[],"sources":["../../src/in/pan.ts"],"sourcesContent":["/** Generate a random valid Indian PAN. */\nconst generate = (): string => {\n const randomLetter = (): string =>\n String.fromCodePoint(65 + randomInt(0, 25));\n const first3 =\n randomLetter() + randomLetter() + randomLetter();\n const holderType = randomChar(HOLDER_TYPES);\n const fifth = randomLetter();\n const digits = randomDigits(4);\n const last = randomLetter();\n return `${first3}${holderType}${fifth}${digits}${last}`;\n};\n\n/**\n * PAN (Permanent Account Number, Indian tax ID).\n *\n * 10 characters: 5 letters + 4 digits + 1 letter.\n * The 4th letter encodes the holder type\n * (P=person, C=company, H=HUF, A=AOP, B=BOI,\n * G=government, J=AJP, L=local authority, F=FOP,\n * T=trust). The 5th letter is the first letter\n * of the surname or entity name.\n * No checksum; format validation only.\n *\n * @see https://en.wikipedia.org/wiki/Permanent_account_number\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport {\n randomChar,\n randomDigits,\n randomInt,\n} from \"#util/generate\";\nimport { err } from \"#util/result\";\n\nconst PAN_RE = /^[A-Z]{5}\\d{4}[A-Z]$/;\n\nconst HOLDER_TYPES = \"ABCFGHJLPT\";\n\nconst compact = (value: string): string =>\n clean(value, \" -\").toUpperCase();\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 10) {\n return err(\n \"INVALID_LENGTH\",\n \"PAN must be 10 characters\",\n );\n }\n if (!PAN_RE.test(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"PAN must be 5 letters + 4 digits + 1 letter\",\n );\n }\n // SAFETY: regex above guarantees v.length === 10.\n // eslint-disable-next-line no-non-null-assertion\n if (!HOLDER_TYPES.includes(v[3]!)) {\n return err(\n \"INVALID_COMPONENT\",\n \"PAN 4th character must be a valid holder type\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Indian Permanent Account Number. */\nconst pan: CountryValidator<\"IN\"> = {\n name: \"Indian Permanent Account Number\",\n localName: \"Permanent Account Number\",\n abbreviation: \"PAN\",\n aliases: [\"PAN\", \"Permanent Account Number\"] as const,\n candidatePattern: \"[A-Z]{5}\\\\d{4}[A-Z]\",\n scope: \"country\",\n country: \"IN\",\n entityType: \"any\",\n lengths: [10],\n examples: [\"ABCPP1234C\", \"AAACR5055K\"],\n description: \"10-character alphanumeric tax identifier\",\n sourceUrl:\n \"https://en.wikipedia.org/wiki/Permanent_account_number\",\n compact,\n format,\n validate,\n generate,\n};\n\nexport default pan;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;AACA,MAAM,iBAAyB;CAC7B,MAAM,qBACJ,OAAO,cAAc,KAAK,UAAU,GAAG,EAAE,CAAC;CAO5C,OAAO,GALL,aAAa,IAAI,aAAa,IAAI,aAAa,IAC9B,WAAW,YAIF,IAHd,aAGsB,IAFrB,aAAa,CAEiB,IADhC,aACuC;AACtD;AA6BA,MAAM,SAAS;AAEf,MAAM,eAAe;AAErB,MAAM,WAAW,UACf,MAAM,OAAO,IAAI,
|
|
1
|
+
{"version":3,"file":"pan.js","names":[],"sources":["../../src/in/pan.ts"],"sourcesContent":["/** Generate a random valid Indian PAN. */\nconst generate = (): string => {\n const randomLetter = (): string =>\n String.fromCodePoint(65 + randomInt(0, 25));\n const first3 =\n randomLetter() + randomLetter() + randomLetter();\n const holderType = randomChar(HOLDER_TYPES);\n const fifth = randomLetter();\n const digits = randomDigits(4);\n const last = randomLetter();\n return `${first3}${holderType}${fifth}${digits}${last}`;\n};\n\n/**\n * PAN (Permanent Account Number, Indian tax ID).\n *\n * 10 characters: 5 letters + 4 digits + 1 letter.\n * The 4th letter encodes the holder type\n * (P=person, C=company, H=HUF, A=AOP, B=BOI,\n * G=government, J=AJP, L=local authority, F=FOP,\n * T=trust). The 5th letter is the first letter\n * of the surname or entity name.\n * No checksum; format validation only.\n *\n * @see https://en.wikipedia.org/wiki/Permanent_account_number\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { clean } from \"#util/clean\";\nimport {\n randomChar,\n randomDigits,\n randomInt,\n} from \"#util/generate\";\nimport { err } from \"#util/result\";\n\nconst PAN_RE = /^[A-Z]{5}\\d{4}[A-Z]$/;\n\nconst HOLDER_TYPES = \"ABCFGHJLPT\";\n\nconst compact = (value: string): string =>\n clean(value, \" -\").toUpperCase();\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 10) {\n return err(\n \"INVALID_LENGTH\",\n \"PAN must be 10 characters\",\n );\n }\n if (!PAN_RE.test(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"PAN must be 5 letters + 4 digits + 1 letter\",\n );\n }\n // SAFETY: regex above guarantees v.length === 10.\n // eslint-disable-next-line no-non-null-assertion\n if (!HOLDER_TYPES.includes(v[3]!)) {\n return err(\n \"INVALID_COMPONENT\",\n \"PAN 4th character must be a valid holder type\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/** Indian Permanent Account Number. */\nconst pan: CountryValidator<\"IN\"> = {\n name: \"Indian Permanent Account Number\",\n localName: \"Permanent Account Number\",\n abbreviation: \"PAN\",\n aliases: [\"PAN\", \"Permanent Account Number\"] as const,\n candidatePattern: \"[A-Z]{5}\\\\d{4}[A-Z]\",\n scope: \"country\",\n country: \"IN\",\n entityType: \"any\",\n lengths: [10],\n examples: [\"ABCPP1234C\", \"AAACR5055K\"],\n description: \"10-character alphanumeric tax identifier\",\n sourceUrl:\n \"https://en.wikipedia.org/wiki/Permanent_account_number\",\n compact,\n format,\n validate,\n generate,\n};\n\nexport default pan;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;AACA,MAAM,iBAAyB;CAC7B,MAAM,qBACJ,OAAO,cAAc,KAAK,UAAU,GAAG,EAAE,CAAC;CAO5C,OAAO,GALL,aAAa,IAAI,aAAa,IAAI,aAAa,IAC9B,WAAW,YAIF,IAHd,aAGsB,IAFrB,aAAa,CAEiB,IADhC,aACuC;AACtD;AA6BA,MAAM,SAAS;AAEf,MAAM,eAAe;AAErB,MAAM,WAAW,UACf,MAAM,OAAO,IAAI,CAAC,CAAC,YAAY;AAEjC,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,IACf,OAAO,IACL,kBACA,2BACF;CAEF,IAAI,CAAC,OAAO,KAAK,CAAC,GAChB,OAAO,IACL,kBACA,6CACF;CAIF,IAAI,CAAC,aAAa,SAAS,EAAE,EAAG,GAC9B,OAAO,IACL,qBACA,+CACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B,QAAQ,KAAK;;AAGvD,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,OAAO,0BAA0B;CAC3C,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,SAAS,CAAC,EAAE;CACZ,UAAU,CAAC,cAAc,YAAY;CACrC,aAAa;CACb,WACE;CACF;CACA;CACA;CACA;AACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -24,82 +24,83 @@ import { mod_d_exports as mod_d_exports$20 } from "./cn/mod.js";
|
|
|
24
24
|
import { mod_d_exports as mod_d_exports$21 } from "./co/mod.js";
|
|
25
25
|
import { mod_d_exports as mod_d_exports$22 } from "./cr/mod.js";
|
|
26
26
|
import creditCard, { CardNetwork, detectNetwork } from "./creditcard.js";
|
|
27
|
-
import { mod_d_exports as mod_d_exports$23 } from "./
|
|
28
|
-
import { mod_d_exports as mod_d_exports$24 } from "./
|
|
29
|
-
import { mod_d_exports as mod_d_exports$25 } from "./
|
|
30
|
-
import { mod_d_exports as mod_d_exports$26 } from "./
|
|
31
|
-
import { mod_d_exports as mod_d_exports$27 } from "./
|
|
32
|
-
import { mod_d_exports as mod_d_exports$28 } from "./
|
|
33
|
-
import { mod_d_exports as mod_d_exports$29 } from "./
|
|
34
|
-
import { mod_d_exports as mod_d_exports$30 } from "./
|
|
35
|
-
import { mod_d_exports as mod_d_exports$31 } from "./
|
|
36
|
-
import { mod_d_exports as mod_d_exports$32 } from "./
|
|
37
|
-
import { mod_d_exports as mod_d_exports$33 } from "./
|
|
38
|
-
import { mod_d_exports as mod_d_exports$34 } from "./
|
|
39
|
-
import { mod_d_exports as mod_d_exports$35 } from "./
|
|
40
|
-
import { mod_d_exports as mod_d_exports$36 } from "./
|
|
41
|
-
import { mod_d_exports as mod_d_exports$37 } from "./
|
|
42
|
-
import { mod_d_exports as mod_d_exports$38 } from "./
|
|
43
|
-
import { mod_d_exports as mod_d_exports$39 } from "./
|
|
44
|
-
import { mod_d_exports as mod_d_exports$40 } from "./
|
|
45
|
-
import { mod_d_exports as mod_d_exports$41 } from "./
|
|
46
|
-
import { mod_d_exports as mod_d_exports$42 } from "./
|
|
47
|
-
import { mod_d_exports as mod_d_exports$43 } from "./
|
|
27
|
+
import { mod_d_exports as mod_d_exports$23 } from "./crypto/mod.js";
|
|
28
|
+
import { mod_d_exports as mod_d_exports$24 } from "./cu/mod.js";
|
|
29
|
+
import { mod_d_exports as mod_d_exports$25 } from "./cy/mod.js";
|
|
30
|
+
import { mod_d_exports as mod_d_exports$26 } from "./cz/mod.js";
|
|
31
|
+
import { mod_d_exports as mod_d_exports$27 } from "./de/mod.js";
|
|
32
|
+
import { mod_d_exports as mod_d_exports$28 } from "./dk/mod.js";
|
|
33
|
+
import { mod_d_exports as mod_d_exports$29 } from "./do/mod.js";
|
|
34
|
+
import { mod_d_exports as mod_d_exports$30 } from "./ec/mod.js";
|
|
35
|
+
import { mod_d_exports as mod_d_exports$31 } from "./ee/mod.js";
|
|
36
|
+
import { mod_d_exports as mod_d_exports$32 } from "./eg/mod.js";
|
|
37
|
+
import { mod_d_exports as mod_d_exports$33 } from "./es/mod.js";
|
|
38
|
+
import { mod_d_exports as mod_d_exports$34 } from "./eu/mod.js";
|
|
39
|
+
import { mod_d_exports as mod_d_exports$35 } from "./fi/mod.js";
|
|
40
|
+
import { mod_d_exports as mod_d_exports$36 } from "./fr/mod.js";
|
|
41
|
+
import { mod_d_exports as mod_d_exports$37 } from "./gb/mod.js";
|
|
42
|
+
import { mod_d_exports as mod_d_exports$38 } from "./ge/mod.js";
|
|
43
|
+
import { mod_d_exports as mod_d_exports$39 } from "./gh/mod.js";
|
|
44
|
+
import { mod_d_exports as mod_d_exports$40 } from "./gr/mod.js";
|
|
45
|
+
import { mod_d_exports as mod_d_exports$41 } from "./gt/mod.js";
|
|
46
|
+
import { mod_d_exports as mod_d_exports$42 } from "./hk/mod.js";
|
|
47
|
+
import { mod_d_exports as mod_d_exports$43 } from "./hr/mod.js";
|
|
48
|
+
import { mod_d_exports as mod_d_exports$44 } from "./hu/mod.js";
|
|
48
49
|
import iban from "./iban.js";
|
|
49
|
-
import { mod_d_exports as mod_d_exports$
|
|
50
|
-
import { mod_d_exports as mod_d_exports$
|
|
51
|
-
import { mod_d_exports as mod_d_exports$
|
|
52
|
-
import { mod_d_exports as mod_d_exports$
|
|
50
|
+
import { mod_d_exports as mod_d_exports$45 } from "./id/mod.js";
|
|
51
|
+
import { mod_d_exports as mod_d_exports$46 } from "./ie/mod.js";
|
|
52
|
+
import { mod_d_exports as mod_d_exports$47 } from "./il/mod.js";
|
|
53
|
+
import { mod_d_exports as mod_d_exports$48 } from "./in/mod.js";
|
|
53
54
|
import isin from "./isin.js";
|
|
54
55
|
import lei from "./lei.js";
|
|
55
56
|
import luhn from "./luhn.js";
|
|
56
|
-
import { mod_d_exports as mod_d_exports$
|
|
57
|
-
import { mod_d_exports as mod_d_exports$
|
|
58
|
-
import { mod_d_exports as mod_d_exports$
|
|
59
|
-
import { mod_d_exports as mod_d_exports$
|
|
60
|
-
import { mod_d_exports as mod_d_exports$
|
|
61
|
-
import { mod_d_exports as mod_d_exports$
|
|
62
|
-
import { mod_d_exports as mod_d_exports$
|
|
63
|
-
import { mod_d_exports as mod_d_exports$
|
|
64
|
-
import { mod_d_exports as mod_d_exports$
|
|
65
|
-
import { mod_d_exports as mod_d_exports$
|
|
66
|
-
import { mod_d_exports as mod_d_exports$
|
|
67
|
-
import { mod_d_exports as mod_d_exports$
|
|
68
|
-
import { mod_d_exports as mod_d_exports$
|
|
69
|
-
import { mod_d_exports as mod_d_exports$
|
|
70
|
-
import { mod_d_exports as mod_d_exports$
|
|
71
|
-
import { mod_d_exports as mod_d_exports$
|
|
72
|
-
import { mod_d_exports as mod_d_exports$
|
|
73
|
-
import { mod_d_exports as mod_d_exports$
|
|
74
|
-
import { mod_d_exports as mod_d_exports$
|
|
75
|
-
import { mod_d_exports as mod_d_exports$
|
|
76
|
-
import { mod_d_exports as mod_d_exports$
|
|
77
|
-
import { mod_d_exports as mod_d_exports$
|
|
78
|
-
import { mod_d_exports as mod_d_exports$
|
|
79
|
-
import { mod_d_exports as mod_d_exports$
|
|
80
|
-
import { mod_d_exports as mod_d_exports$
|
|
81
|
-
import { mod_d_exports as mod_d_exports$
|
|
82
|
-
import { mod_d_exports as mod_d_exports$
|
|
83
|
-
import { mod_d_exports as mod_d_exports$
|
|
84
|
-
import { mod_d_exports as mod_d_exports$
|
|
85
|
-
import { mod_d_exports as mod_d_exports$
|
|
86
|
-
import { mod_d_exports as mod_d_exports$
|
|
87
|
-
import { mod_d_exports as mod_d_exports$
|
|
88
|
-
import { mod_d_exports as mod_d_exports$
|
|
89
|
-
import { mod_d_exports as mod_d_exports$
|
|
90
|
-
import { mod_d_exports as mod_d_exports$
|
|
91
|
-
import { mod_d_exports as mod_d_exports$
|
|
92
|
-
import { mod_d_exports as mod_d_exports$
|
|
93
|
-
import { mod_d_exports as mod_d_exports$
|
|
94
|
-
import { mod_d_exports as mod_d_exports$
|
|
95
|
-
import { mod_d_exports as mod_d_exports$
|
|
96
|
-
import { mod_d_exports as mod_d_exports$
|
|
97
|
-
import { mod_d_exports as mod_d_exports$
|
|
98
|
-
import { mod_d_exports as mod_d_exports$
|
|
99
|
-
import { mod_d_exports as mod_d_exports$
|
|
100
|
-
import { mod_d_exports as mod_d_exports$
|
|
101
|
-
import { mod_d_exports as mod_d_exports$
|
|
102
|
-
import { mod_d_exports as mod_d_exports$
|
|
103
|
-
import { mod_d_exports as mod_d_exports$
|
|
104
|
-
import { mod_d_exports as mod_d_exports$
|
|
105
|
-
export { type CardNetwork, type CountryCode, type CountryValidator, type ErrorCode, type GlobalValidator, type ParsableValidator, type ParsedBirthDate, type ParsedIdentifier, type ParsedPersonId, type StdnumError, type ValidateResult, type Validator, type ValidatorScope, mod_d_exports as ad, mod_d_exports$1 as ae, mod_d_exports$2 as ai, mod_d_exports$3 as al, mod_d_exports$4 as am, mod_d_exports$5 as ar, mod_d_exports$6 as at, mod_d_exports$7 as au, mod_d_exports$8 as az, mod_d_exports$9 as ba, mod_d_exports$10 as bd, mod_d_exports$11 as be, mod_d_exports$12 as bg, mod_d_exports$13 as bh, bic, mod_d_exports$14 as br, mod_d_exports$15 as by, mod_d_exports$16 as bz, mod_d_exports$17 as ca, mod_d_exports$18 as ch, mod_d_exports$19 as cl, mod_d_exports$20 as cn, mod_d_exports$21 as co, mod_d_exports$22 as cr, creditCard as creditcard, mod_d_exports$23 as
|
|
57
|
+
import { mod_d_exports as mod_d_exports$49 } from "./iq/mod.js";
|
|
58
|
+
import { mod_d_exports as mod_d_exports$50 } from "./ir/mod.js";
|
|
59
|
+
import { mod_d_exports as mod_d_exports$51 } from "./is/mod.js";
|
|
60
|
+
import { mod_d_exports as mod_d_exports$52 } from "./it/mod.js";
|
|
61
|
+
import { mod_d_exports as mod_d_exports$53 } from "./jp/mod.js";
|
|
62
|
+
import { mod_d_exports as mod_d_exports$54 } from "./kr/mod.js";
|
|
63
|
+
import { mod_d_exports as mod_d_exports$55 } from "./kw/mod.js";
|
|
64
|
+
import { mod_d_exports as mod_d_exports$56 } from "./kz/mod.js";
|
|
65
|
+
import { mod_d_exports as mod_d_exports$57 } from "./li/mod.js";
|
|
66
|
+
import { mod_d_exports as mod_d_exports$58 } from "./lk/mod.js";
|
|
67
|
+
import { mod_d_exports as mod_d_exports$59 } from "./lt/mod.js";
|
|
68
|
+
import { mod_d_exports as mod_d_exports$60 } from "./lu/mod.js";
|
|
69
|
+
import { mod_d_exports as mod_d_exports$61 } from "./lv/mod.js";
|
|
70
|
+
import { mod_d_exports as mod_d_exports$62 } from "./ma/mod.js";
|
|
71
|
+
import { mod_d_exports as mod_d_exports$63 } from "./mc/mod.js";
|
|
72
|
+
import { mod_d_exports as mod_d_exports$64 } from "./md/mod.js";
|
|
73
|
+
import { mod_d_exports as mod_d_exports$65 } from "./me/mod.js";
|
|
74
|
+
import { mod_d_exports as mod_d_exports$66 } from "./mk/mod.js";
|
|
75
|
+
import { mod_d_exports as mod_d_exports$67 } from "./mt/mod.js";
|
|
76
|
+
import { mod_d_exports as mod_d_exports$68 } from "./mu/mod.js";
|
|
77
|
+
import { mod_d_exports as mod_d_exports$69 } from "./mx/mod.js";
|
|
78
|
+
import { mod_d_exports as mod_d_exports$70 } from "./my/mod.js";
|
|
79
|
+
import { mod_d_exports as mod_d_exports$71 } from "./ng/mod.js";
|
|
80
|
+
import { mod_d_exports as mod_d_exports$72 } from "./ni/mod.js";
|
|
81
|
+
import { mod_d_exports as mod_d_exports$73 } from "./nl/mod.js";
|
|
82
|
+
import { mod_d_exports as mod_d_exports$74 } from "./no/mod.js";
|
|
83
|
+
import { mod_d_exports as mod_d_exports$75 } from "./nz/mod.js";
|
|
84
|
+
import { mod_d_exports as mod_d_exports$76 } from "./pa/mod.js";
|
|
85
|
+
import { mod_d_exports as mod_d_exports$77 } from "./pe/mod.js";
|
|
86
|
+
import { mod_d_exports as mod_d_exports$78 } from "./ph/mod.js";
|
|
87
|
+
import { mod_d_exports as mod_d_exports$79 } from "./pk/mod.js";
|
|
88
|
+
import { mod_d_exports as mod_d_exports$80 } from "./pl/mod.js";
|
|
89
|
+
import { mod_d_exports as mod_d_exports$81 } from "./pt/mod.js";
|
|
90
|
+
import { mod_d_exports as mod_d_exports$82 } from "./ro/mod.js";
|
|
91
|
+
import { mod_d_exports as mod_d_exports$83 } from "./rs/mod.js";
|
|
92
|
+
import { mod_d_exports as mod_d_exports$84 } from "./ru/mod.js";
|
|
93
|
+
import { mod_d_exports as mod_d_exports$85 } from "./se/mod.js";
|
|
94
|
+
import { mod_d_exports as mod_d_exports$86 } from "./sg/mod.js";
|
|
95
|
+
import { mod_d_exports as mod_d_exports$87 } from "./si/mod.js";
|
|
96
|
+
import { mod_d_exports as mod_d_exports$88 } from "./sk/mod.js";
|
|
97
|
+
import { mod_d_exports as mod_d_exports$89 } from "./th/mod.js";
|
|
98
|
+
import { mod_d_exports as mod_d_exports$90 } from "./tr/mod.js";
|
|
99
|
+
import { mod_d_exports as mod_d_exports$91 } from "./tw/mod.js";
|
|
100
|
+
import { mod_d_exports as mod_d_exports$92 } from "./ua/mod.js";
|
|
101
|
+
import { mod_d_exports as mod_d_exports$93 } from "./us/mod.js";
|
|
102
|
+
import { mod_d_exports as mod_d_exports$94 } from "./uy/mod.js";
|
|
103
|
+
import { mod_d_exports as mod_d_exports$95 } from "./ve/mod.js";
|
|
104
|
+
import { mod_d_exports as mod_d_exports$96 } from "./vn/mod.js";
|
|
105
|
+
import { mod_d_exports as mod_d_exports$97 } from "./za/mod.js";
|
|
106
|
+
export { type CardNetwork, type CountryCode, type CountryValidator, type ErrorCode, type GlobalValidator, type ParsableValidator, type ParsedBirthDate, type ParsedIdentifier, type ParsedPersonId, type StdnumError, type ValidateResult, type Validator, type ValidatorScope, mod_d_exports as ad, mod_d_exports$1 as ae, mod_d_exports$2 as ai, mod_d_exports$3 as al, mod_d_exports$4 as am, mod_d_exports$5 as ar, mod_d_exports$6 as at, mod_d_exports$7 as au, mod_d_exports$8 as az, mod_d_exports$9 as ba, mod_d_exports$10 as bd, mod_d_exports$11 as be, mod_d_exports$12 as bg, mod_d_exports$13 as bh, bic, mod_d_exports$14 as br, mod_d_exports$15 as by, mod_d_exports$16 as bz, mod_d_exports$17 as ca, mod_d_exports$18 as ch, mod_d_exports$19 as cl, mod_d_exports$20 as cn, mod_d_exports$21 as co, mod_d_exports$22 as cr, creditCard as creditcard, mod_d_exports$23 as crypto, mod_d_exports$24 as cu, mod_d_exports$25 as cy, mod_d_exports$26 as cz, mod_d_exports$27 as de, detectNetwork, mod_d_exports$28 as dk, mod_d_exports$29 as do_, mod_d_exports$30 as ec, mod_d_exports$31 as ee, mod_d_exports$32 as eg, mod_d_exports$33 as es, mod_d_exports$34 as eu, mod_d_exports$35 as fi, mod_d_exports$36 as fr, mod_d_exports$37 as gb, mod_d_exports$38 as ge, mod_d_exports$39 as gh, mod_d_exports$40 as gr, mod_d_exports$41 as gt, mod_d_exports$42 as hk, mod_d_exports$43 as hr, mod_d_exports$44 as hu, iban, mod_d_exports$45 as id, mod_d_exports$46 as ie, mod_d_exports$47 as il, mod_d_exports$48 as in_, mod_d_exports$49 as iq, mod_d_exports$50 as ir, mod_d_exports$51 as is_, isin, mod_d_exports$52 as it, mod_d_exports$53 as jp, mod_d_exports$54 as kr, mod_d_exports$55 as kw, mod_d_exports$56 as kz, lei, mod_d_exports$57 as li, mod_d_exports$58 as lk, mod_d_exports$59 as lt, mod_d_exports$60 as lu, luhn, mod_d_exports$61 as lv, mod_d_exports$62 as ma, mod_d_exports$63 as mc, mod_d_exports$64 as md, mod_d_exports$65 as me, mod_d_exports$66 as mk, mod_d_exports$67 as mt, mod_d_exports$68 as mu, mod_d_exports$69 as mx, mod_d_exports$70 as my, mod_d_exports$71 as ng, mod_d_exports$72 as ni, mod_d_exports$73 as nl, mod_d_exports$74 as no, mod_d_exports$75 as nz, mod_d_exports$76 as pa, mod_d_exports$77 as pe, mod_d_exports$78 as ph, mod_d_exports$79 as pk, mod_d_exports$80 as pl, mod_d_exports$81 as pt, mod_d_exports$82 as ro, mod_d_exports$83 as rs, mod_d_exports$84 as ru, mod_d_exports$85 as se, mod_d_exports$86 as sg, mod_d_exports$87 as si, mod_d_exports$88 as sk, mod_d_exports$89 as th, mod_d_exports$90 as tr, mod_d_exports$91 as tw, mod_d_exports$92 as ua, mod_d_exports$93 as us, mod_d_exports$94 as uy, mod_d_exports$95 as ve, mod_d_exports$96 as vn, mod_d_exports$97 as za };
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,7 @@ import { cn_exports } from "./cn/mod.js";
|
|
|
23
23
|
import { co_exports } from "./co/mod.js";
|
|
24
24
|
import { cr_exports } from "./cr/mod.js";
|
|
25
25
|
import creditCard, { detectNetwork } from "./creditcard.js";
|
|
26
|
+
import { crypto_exports } from "./crypto/mod.js";
|
|
26
27
|
import { cu_exports } from "./cu/mod.js";
|
|
27
28
|
import { cy_exports } from "./cy/mod.js";
|
|
28
29
|
import { cz_exports } from "./cz/mod.js";
|
|
@@ -101,4 +102,4 @@ import { uy_exports } from "./uy/mod.js";
|
|
|
101
102
|
import { ve_exports } from "./ve/mod.js";
|
|
102
103
|
import { vn_exports } from "./vn/mod.js";
|
|
103
104
|
import { za_exports } from "./za/mod.js";
|
|
104
|
-
export { ad_exports as ad, ae_exports as ae, ai_exports as ai, al_exports as al, am_exports as am, ar_exports as ar, at_exports as at, au_exports as au, az_exports as az, ba_exports as ba, bd_exports as bd, be_exports as be, bg_exports as bg, bh_exports as bh, bic, br_exports as br, by_exports as by, bz_exports as bz, ca_exports as ca, ch_exports as ch, cl_exports as cl, cn_exports as cn, co_exports as co, cr_exports as cr, creditCard as creditcard, cu_exports as cu, cy_exports as cy, cz_exports as cz, de_exports as de, detectNetwork, dk_exports as dk, do_exports as do_, ec_exports as ec, ee_exports as ee, eg_exports as eg, es_exports as es, eu_exports as eu, fi_exports as fi, fr_exports as fr, gb_exports as gb, ge_exports as ge, gh_exports as gh, gr_exports as gr, gt_exports as gt, hk_exports as hk, hr_exports as hr, hu_exports as hu, iban, id_exports as id, ie_exports as ie, il_exports as il, in_exports as in_, iq_exports as iq, ir_exports as ir, is_exports as is_, isin, it_exports as it, jp_exports as jp, kr_exports as kr, kw_exports as kw, kz_exports as kz, lei, li_exports as li, lk_exports as lk, lt_exports as lt, lu_exports as lu, luhn, lv_exports as lv, ma_exports as ma, mc_exports as mc, md_exports as md, me_exports as me, mk_exports as mk, mt_exports as mt, mu_exports as mu, mx_exports as mx, my_exports as my, ng_exports as ng, ni_exports as ni, nl_exports as nl, no_exports as no, nz_exports as nz, pa_exports as pa, pe_exports as pe, ph_exports as ph, pk_exports as pk, pl_exports as pl, pt_exports as pt, ro_exports as ro, rs_exports as rs, ru_exports as ru, se_exports as se, sg_exports as sg, si_exports as si, sk_exports as sk, th_exports as th, tr_exports as tr, tw_exports as tw, ua_exports as ua, us_exports as us, uy_exports as uy, ve_exports as ve, vn_exports as vn, za_exports as za };
|
|
105
|
+
export { ad_exports as ad, ae_exports as ae, ai_exports as ai, al_exports as al, am_exports as am, ar_exports as ar, at_exports as at, au_exports as au, az_exports as az, ba_exports as ba, bd_exports as bd, be_exports as be, bg_exports as bg, bh_exports as bh, bic, br_exports as br, by_exports as by, bz_exports as bz, ca_exports as ca, ch_exports as ch, cl_exports as cl, cn_exports as cn, co_exports as co, cr_exports as cr, creditCard as creditcard, crypto_exports as crypto, cu_exports as cu, cy_exports as cy, cz_exports as cz, de_exports as de, detectNetwork, dk_exports as dk, do_exports as do_, ec_exports as ec, ee_exports as ee, eg_exports as eg, es_exports as es, eu_exports as eu, fi_exports as fi, fr_exports as fr, gb_exports as gb, ge_exports as ge, gh_exports as gh, gr_exports as gr, gt_exports as gt, hk_exports as hk, hr_exports as hr, hu_exports as hu, iban, id_exports as id, ie_exports as ie, il_exports as il, in_exports as in_, iq_exports as iq, ir_exports as ir, is_exports as is_, isin, it_exports as it, jp_exports as jp, kr_exports as kr, kw_exports as kw, kz_exports as kz, lei, li_exports as li, lk_exports as lk, lt_exports as lt, lu_exports as lu, luhn, lv_exports as lv, ma_exports as ma, mc_exports as mc, md_exports as md, me_exports as me, mk_exports as mk, mt_exports as mt, mu_exports as mu, mx_exports as mx, my_exports as my, ng_exports as ng, ni_exports as ni, nl_exports as nl, no_exports as no, nz_exports as nz, pa_exports as pa, pe_exports as pe, ph_exports as ph, pk_exports as pk, pl_exports as pl, pt_exports as pt, ro_exports as ro, rs_exports as rs, ru_exports as ru, se_exports as se, sg_exports as sg, si_exports as si, sk_exports as sk, th_exports as th, tr_exports as tr, tw_exports as tw, ua_exports as ua, us_exports as us, uy_exports as uy, ve_exports as ve, vn_exports as vn, za_exports as za };
|
package/dist/ir/nid.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nid.js","names":[],"sources":["../../src/ir/nid.ts"],"sourcesContent":["/**\n * NID (Iranian National ID, کد ملی, Code Melli).\n *\n * 10-digit personal identification number assigned to\n * every Iranian citizen. Digits 1-3 encode the province,\n * digits 4-9 are a sequential identifier, and digit 10\n * is a check digit.\n *\n * Check digit algorithm (mod 11):\n * sum = Σ(digit[i] × (10 − i)) for i = 0..8\n * r = sum mod 11\n * if r < 2: check digit = r\n * if r ≥ 2: check digit = 11 − r\n *\n * Numbers where all digits are identical (e.g.\n * 0000000000, 1111111111) are rejected.\n *\n * Accepts both Persian (Extended Arabic-Indic, U+06Fx)\n * and Arabic-Indic (U+066x) digits.\n *\n * @see https://www.sabteahval.ir/\n * @see https://persian-tools.js.org/functions/verifyIranianNationalId.html\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { normalizeArabicDigits } from \"#util/arabic\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\n/** All-same-digit patterns (0000000000 .. 9999999999). */\nconst ALL_SAME = new Set(\n Array.from({ length: 10 }, (_, i) =>\n String(i).repeat(10),\n ),\n);\n\nconst compact = (value: string): string =>\n normalizeArabicDigits(clean(value, \" -./\"));\n\n/**\n * Calculate the check digit from the first 9 digits.\n */\nconst calcCheckDigit = (number: string): number => {\n let sum = 0;\n for (let i = 0; i < 9; i++) {\n sum += Number(number[i]) * (10 - i);\n }\n const r = sum % 11;\n return r < 2 ? r : 11 - r;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 10) {\n return err(\n \"INVALID_LENGTH\",\n \"Iranian NID must be exactly 10 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Iranian NID must contain only digits\",\n );\n }\n if (ALL_SAME.has(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Iranian NID must not have all identical digits\",\n );\n }\n if (calcCheckDigit(v) !== Number(v[9])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Iranian NID check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\n/** Iranian NIDs are displayed without separators. */\nconst format = (value: string): string => compact(value);\n\n/**\n * Generate a random valid Iranian NID.\n * NOT cryptographically secure.\n */\nconst generate = (): string => {\n const base = randomDigits(9);\n const check = calcCheckDigit(base);\n const result = `${base}${check}`;\n if (ALL_SAME.has(result)) return generate();\n return result;\n};\n\n/** Iranian National Identification Number. */\nconst nid: CountryValidator<\"IR\"> = {\n name: \"Iranian National ID\",\n localName: \"کد ملی\",\n abbreviation: \"NID\",\n aliases: [\"NID\", \"کد ملی\", \"national code\"] as const,\n candidatePattern: \"\\\\d{10}\",\n scope: \"country\",\n country: \"IR\",\n entityType: \"person\",\n sourceUrl: \"https://www.sabteahval.ir/\",\n description:\n \"Iranian personal identification number (Code Melli)\",\n lengths: [10] as const,\n examples: [\"0932833810\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default nid;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;AAoCA,MAAM,WAAW,IAAI,IACnB,MAAM,KAAK,EAAE,QAAQ,GAAG,IAAI,GAAG,MAC7B,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"nid.js","names":[],"sources":["../../src/ir/nid.ts"],"sourcesContent":["/**\n * NID (Iranian National ID, کد ملی, Code Melli).\n *\n * 10-digit personal identification number assigned to\n * every Iranian citizen. Digits 1-3 encode the province,\n * digits 4-9 are a sequential identifier, and digit 10\n * is a check digit.\n *\n * Check digit algorithm (mod 11):\n * sum = Σ(digit[i] × (10 − i)) for i = 0..8\n * r = sum mod 11\n * if r < 2: check digit = r\n * if r ≥ 2: check digit = 11 − r\n *\n * Numbers where all digits are identical (e.g.\n * 0000000000, 1111111111) are rejected.\n *\n * Accepts both Persian (Extended Arabic-Indic, U+06Fx)\n * and Arabic-Indic (U+066x) digits.\n *\n * @see https://www.sabteahval.ir/\n * @see https://persian-tools.js.org/functions/verifyIranianNationalId.html\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport { normalizeArabicDigits } from \"#util/arabic\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\n/** All-same-digit patterns (0000000000 .. 9999999999). */\nconst ALL_SAME = new Set(\n Array.from({ length: 10 }, (_, i) =>\n String(i).repeat(10),\n ),\n);\n\nconst compact = (value: string): string =>\n normalizeArabicDigits(clean(value, \" -./\"));\n\n/**\n * Calculate the check digit from the first 9 digits.\n */\nconst calcCheckDigit = (number: string): number => {\n let sum = 0;\n for (let i = 0; i < 9; i++) {\n sum += Number(number[i]) * (10 - i);\n }\n const r = sum % 11;\n return r < 2 ? r : 11 - r;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 10) {\n return err(\n \"INVALID_LENGTH\",\n \"Iranian NID must be exactly 10 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Iranian NID must contain only digits\",\n );\n }\n if (ALL_SAME.has(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Iranian NID must not have all identical digits\",\n );\n }\n if (calcCheckDigit(v) !== Number(v[9])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Iranian NID check digit mismatch\",\n );\n }\n return { valid: true, compact: v };\n};\n\n/** Iranian NIDs are displayed without separators. */\nconst format = (value: string): string => compact(value);\n\n/**\n * Generate a random valid Iranian NID.\n * NOT cryptographically secure.\n */\nconst generate = (): string => {\n const base = randomDigits(9);\n const check = calcCheckDigit(base);\n const result = `${base}${check}`;\n if (ALL_SAME.has(result)) return generate();\n return result;\n};\n\n/** Iranian National Identification Number. */\nconst nid: CountryValidator<\"IR\"> = {\n name: \"Iranian National ID\",\n localName: \"کد ملی\",\n abbreviation: \"NID\",\n aliases: [\"NID\", \"کد ملی\", \"national code\"] as const,\n candidatePattern: \"\\\\d{10}\",\n scope: \"country\",\n country: \"IR\",\n entityType: \"person\",\n sourceUrl: \"https://www.sabteahval.ir/\",\n description:\n \"Iranian personal identification number (Code Melli)\",\n lengths: [10] as const,\n examples: [\"0932833810\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default nid;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;;AAoCA,MAAM,WAAW,IAAI,IACnB,MAAM,KAAK,EAAE,QAAQ,GAAG,IAAI,GAAG,MAC7B,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,CACrB,CACF;AAEA,MAAM,WAAW,UACf,sBAAsB,MAAM,OAAO,MAAM,CAAC;;;;AAK5C,MAAM,kBAAkB,WAA2B;CACjD,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,OAAO,OAAO,OAAO,EAAE,KAAK,KAAK;CAEnC,MAAM,IAAI,MAAM;CAChB,OAAO,IAAI,IAAI,IAAI,KAAK;AAC1B;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,IACf,OAAO,IACL,kBACA,uCACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,sCACF;CAEF,IAAI,SAAS,IAAI,CAAC,GAChB,OAAO,IACL,kBACA,gDACF;CAEF,IAAI,eAAe,CAAC,MAAM,OAAO,EAAE,EAAE,GACnC,OAAO,IACL,oBACA,kCACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;;AAGA,MAAM,UAAU,UAA0B,QAAQ,KAAK;;;;;AAMvD,MAAM,iBAAyB;CAC7B,MAAM,OAAO,aAAa,CAAC;CAE3B,MAAM,SAAS,GAAG,OADJ,eAAe,IACA;CAC7B,IAAI,SAAS,IAAI,MAAM,GAAG,OAAO,SAAS;CAC1C,OAAO;AACT;;AAGA,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EAAC;EAAO;EAAU;CAAe;CAC1C,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WAAW;CACX,aACE;CACF,SAAS,CAAC,EAAE;CACZ,UAAU,CAAC,YAAY;CACvB;CACA;CACA;CACA;AACF"}
|
package/dist/is/kennitala.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kennitala.js","names":[],"sources":["../../src/is/kennitala.ts"],"sourcesContent":["/**\n * Kennitala (Icelandic identification number).\n *\n * 10 digits: DDMMYY + 2 random + 1 check + 1 century.\n * Weights [3,2,7,6,5,4,3,2] on first 8 digits,\n * check digit at position 9, century at position 10\n * (weight 0, does not participate in checksum).\n * Organizations use day + 40. Century digit: 9 = 1900s,\n * 0 = 2000s.\n *\n * @see https://www.skra.is/\n */\n\nimport type {\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 WEIGHTS = [3, 2, 7, 6, 5, 4, 3, 2, 0, 0] 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 !== 10) {\n return err(\n \"INVALID_LENGTH\",\n \"Kennitala must be 10 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Kennitala must contain only digits\",\n );\n }\n\n // Checksum: weights on first 8 digits, check is 9th\n let sum = 0;\n for (let i = 0; i < 8; i++) {\n sum += Number(v.charAt(i)) * (WEIGHTS[i] ?? 0);\n }\n const remainder = (11 - (sum % 11)) % 11;\n if (remainder === 10 || remainder !== Number(v[8])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Kennitala check digit mismatch\",\n );\n }\n\n // Parse date\n let dd = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const yy = Number(v.slice(4, 6));\n const centuryDigit = Number(v[9]);\n\n // Organizations use day + 40\n if (dd > 40) dd -= 40;\n\n let century: number;\n if (centuryDigit === 9) {\n century = 1900;\n } else if (centuryDigit === 0) {\n century = 2000;\n } else {\n return err(\n \"INVALID_COMPONENT\",\n \"Kennitala century digit must be 0 or 9\",\n );\n }\n\n const year = century + yy;\n if (!isValidDate(year, mm, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Kennitala contains an invalid date\",\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/** Generate a random valid Icelandic kennitala. */\nconst generate = (): string => {\n for (;;) {\n const dd = String(randomInt(1, 28)).padStart(2, \"0\");\n const mm = String(randomInt(1, 12)).padStart(2, \"0\");\n const yy = String(randomInt(50, 99)).padStart(2, \"0\");\n const rr = String(randomInt(20, 99)).padStart(2, \"0\");\n const partial = dd + mm + yy + rr;\n for (let d = 0; d <= 9; d++) {\n const c = partial + String(d) + \"9\";\n if (validate(c).valid) return c;\n }\n }\n};\n\n/** Icelandic Identification Number. */\nconst kennitala: CountryValidator<\"IS\"> = {\n name: \"Icelandic ID Number\",\n localName: \"Kennitala\",\n abbreviation: \"kt.\",\n aliases: [\"kennitala\", \"kt.\"] as const,\n candidatePattern: \"\\\\d{6}-?\\\\d{4}\",\n scope: \"country\",\n country: \"IS\",\n entityType: \"any\",\n sourceUrl: \"https://www.skra.is/\",\n examples: [\"4504013150\", \"1201743399\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default kennitala;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AAwBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAAC;AAE7C,MAAM,WAAW,UACf,MAAM,OAAO,IAAI;AAEnB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,IACf,OAAO,IACL,kBACA,6BACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,oCACF;CAIF,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,OAAO,OAAO,EAAE,OAAO,CAAC,CAAC,KAAK,QAAQ,MAAM;CAE9C,MAAM,aAAa,KAAM,MAAM,MAAO;CACtC,IAAI,cAAc,MAAM,cAAc,OAAO,EAAE,EAAE,GAC/C,OAAO,IACL,oBACA,gCACF;CAIF,IAAI,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC7B,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC/B,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC/B,MAAM,eAAe,OAAO,EAAE,EAAE;CAGhC,IAAI,KAAK,IAAI,MAAM;CAEnB,IAAI;CACJ,IAAI,iBAAiB,GACnB,UAAU;MACL,IAAI,iBAAiB,GAC1B,UAAU;MAEV,OAAO,IACL,qBACA,wCACF;CAIF,IAAI,CAAC,YADQ,UAAU,IACA,IAAI,EAAE,GAC3B,OAAO,IACL,qBACA,oCACF;CAGF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,KAAK;CACvB,OAAO,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC;AACtC;;AAGA,MAAM,iBAAyB;CAC7B,SAAS;EACP,MAAM,KAAK,OAAO,UAAU,GAAG,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"kennitala.js","names":[],"sources":["../../src/is/kennitala.ts"],"sourcesContent":["/**\n * Kennitala (Icelandic identification number).\n *\n * 10 digits: DDMMYY + 2 random + 1 check + 1 century.\n * Weights [3,2,7,6,5,4,3,2] on first 8 digits,\n * check digit at position 9, century at position 10\n * (weight 0, does not participate in checksum).\n * Organizations use day + 40. Century digit: 9 = 1900s,\n * 0 = 2000s.\n *\n * @see https://www.skra.is/\n */\n\nimport type {\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 WEIGHTS = [3, 2, 7, 6, 5, 4, 3, 2, 0, 0] 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 !== 10) {\n return err(\n \"INVALID_LENGTH\",\n \"Kennitala must be 10 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Kennitala must contain only digits\",\n );\n }\n\n // Checksum: weights on first 8 digits, check is 9th\n let sum = 0;\n for (let i = 0; i < 8; i++) {\n sum += Number(v.charAt(i)) * (WEIGHTS[i] ?? 0);\n }\n const remainder = (11 - (sum % 11)) % 11;\n if (remainder === 10 || remainder !== Number(v[8])) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Kennitala check digit mismatch\",\n );\n }\n\n // Parse date\n let dd = Number(v.slice(0, 2));\n const mm = Number(v.slice(2, 4));\n const yy = Number(v.slice(4, 6));\n const centuryDigit = Number(v[9]);\n\n // Organizations use day + 40\n if (dd > 40) dd -= 40;\n\n let century: number;\n if (centuryDigit === 9) {\n century = 1900;\n } else if (centuryDigit === 0) {\n century = 2000;\n } else {\n return err(\n \"INVALID_COMPONENT\",\n \"Kennitala century digit must be 0 or 9\",\n );\n }\n\n const year = century + yy;\n if (!isValidDate(year, mm, dd)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Kennitala contains an invalid date\",\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/** Generate a random valid Icelandic kennitala. */\nconst generate = (): string => {\n for (;;) {\n const dd = String(randomInt(1, 28)).padStart(2, \"0\");\n const mm = String(randomInt(1, 12)).padStart(2, \"0\");\n const yy = String(randomInt(50, 99)).padStart(2, \"0\");\n const rr = String(randomInt(20, 99)).padStart(2, \"0\");\n const partial = dd + mm + yy + rr;\n for (let d = 0; d <= 9; d++) {\n const c = partial + String(d) + \"9\";\n if (validate(c).valid) return c;\n }\n }\n};\n\n/** Icelandic Identification Number. */\nconst kennitala: CountryValidator<\"IS\"> = {\n name: \"Icelandic ID Number\",\n localName: \"Kennitala\",\n abbreviation: \"kt.\",\n aliases: [\"kennitala\", \"kt.\"] as const,\n candidatePattern: \"\\\\d{6}-?\\\\d{4}\",\n scope: \"country\",\n country: \"IS\",\n entityType: \"any\",\n sourceUrl: \"https://www.skra.is/\",\n examples: [\"4504013150\", \"1201743399\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default kennitala;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AAwBA,MAAM,UAAU;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAAC;AAE7C,MAAM,WAAW,UACf,MAAM,OAAO,IAAI;AAEnB,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,IACf,OAAO,IACL,kBACA,6BACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,oCACF;CAIF,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,OAAO,OAAO,EAAE,OAAO,CAAC,CAAC,KAAK,QAAQ,MAAM;CAE9C,MAAM,aAAa,KAAM,MAAM,MAAO;CACtC,IAAI,cAAc,MAAM,cAAc,OAAO,EAAE,EAAE,GAC/C,OAAO,IACL,oBACA,gCACF;CAIF,IAAI,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC7B,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC/B,MAAM,KAAK,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;CAC/B,MAAM,eAAe,OAAO,EAAE,EAAE;CAGhC,IAAI,KAAK,IAAI,MAAM;CAEnB,IAAI;CACJ,IAAI,iBAAiB,GACnB,UAAU;MACL,IAAI,iBAAiB,GAC1B,UAAU;MAEV,OAAO,IACL,qBACA,wCACF;CAIF,IAAI,CAAC,YADQ,UAAU,IACA,IAAI,EAAE,GAC3B,OAAO,IACL,qBACA,oCACF;CAGF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UAA0B;CACxC,MAAM,IAAI,QAAQ,KAAK;CACvB,OAAO,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC;AACtC;;AAGA,MAAM,iBAAyB;CAC7B,SAAS;EACP,MAAM,KAAK,OAAO,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;EACnD,MAAM,KAAK,OAAO,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;EACnD,MAAM,KAAK,OAAO,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;EACpD,MAAM,KAAK,OAAO,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;EACpD,MAAM,UAAU,KAAK,KAAK,KAAK;EAC/B,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;GAC3B,MAAM,IAAI,UAAU,OAAO,CAAC,IAAI;GAChC,IAAI,SAAS,CAAC,CAAC,CAAC,OAAO,OAAO;EAChC;CACF;AACF;;AAGA,MAAM,YAAoC;CACxC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS,CAAC,aAAa,KAAK;CAC5B,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,cAAc,YAAY;CACrC;CACA;CACA;CACA;AACF"}
|
package/dist/isin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isin.js","names":[],"sources":["../src/isin.ts"],"sourcesContent":["/**\n * ISIN (International Securities Identification\n * Number).\n *\n * ISO 6166. 12-character alphanumeric code:\n * [A-Z]{2} (country) + [0-9A-Z]{9} (identifier) +\n * [0-9]{1} (check digit). Validated using the Luhn\n * algorithm on the alpha-numeric expansion.\n *\n * @see https://www.isin.org/\n */\n\nimport type {\n ValidateResult,\n GlobalValidator,\n} from \"./types\";\n\nimport { luhnChecksum } from \"#checksums/luhn\";\nimport { clean } from \"#util/clean\";\nimport { randomInt, randomPick } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { charValue, isalnum } from \"#util/strings\";\n\nconst ISIN_RE = /^[A-Z]{2}[0-9A-Z]{9}[0-9]$/;\n\nconst compact = (value: string): string =>\n clean(value, \" -\").toUpperCase();\n\n/**\n * Expand each character to its numeric value\n * (A=10..Z=35, digits unchanged) and concatenate.\n */\nconst expand = (value: string): string => {\n let result = \"\";\n for (let i = 0; i < value.length; i++) {\n const ch = value[i];\n if (ch !== undefined) {\n result += String(charValue(ch));\n }\n }\n return result;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 12) {\n return err(\n \"INVALID_LENGTH\",\n \"ISIN must be exactly 12 characters\",\n );\n }\n if (!isalnum(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"ISIN must contain only letters and digits\",\n );\n }\n if (!ISIN_RE.test(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"ISIN must match [A-Z]{2}[0-9A-Z]{9}[0-9]\",\n );\n }\n const expanded = expand(v);\n if (luhnChecksum(expanded) !== 0) {\n return err(\n \"INVALID_CHECKSUM\",\n \"ISIN check digit is incorrect\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n return `${v.slice(0, 2)} ${v.slice(2, 6)} ${v.slice(6, 10)} ${v.slice(10)}`;\n};\n\nconst ISIN_COUNTRIES = [\n \"US\",\n \"GB\",\n \"DE\",\n \"FR\",\n \"JP\",\n] as const;\n\n/** Generate a random valid ISIN. */\nconst generate = (): string => {\n for (;;) {\n const cc = randomPick(ISIN_COUNTRIES);\n let nsin = \"\";\n for (let i = 0; i < 9; i++)\n nsin += String(randomInt(0, 9));\n const base = cc + nsin;\n for (let d = 0; d <= 9; d++) {\n const c = base + String(d);\n if (validate(c).valid) return c;\n }\n }\n};\n\n/** International Securities Identification Number. */\nconst isin: GlobalValidator = {\n scope: \"global\",\n name: \"International Securities Identification Number\",\n localName:\n \"International Securities Identification Number\",\n abbreviation: \"ISIN\",\n aliases: [\n \"ISIN\",\n \"International Securities Identification Number\",\n ] as const,\n candidatePattern: \"[A-Z]{2}[A-Z0-9]{9}\\\\d\",\n entityType: \"any\",\n sourceUrl: \"https://www.isin.org/\",\n examples: [\"US0378331005\", \"GB0002634946\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default isin;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AAuBA,MAAM,UAAU;AAEhB,MAAM,WAAW,UACf,MAAM,OAAO,IAAI,
|
|
1
|
+
{"version":3,"file":"isin.js","names":[],"sources":["../src/isin.ts"],"sourcesContent":["/**\n * ISIN (International Securities Identification\n * Number).\n *\n * ISO 6166. 12-character alphanumeric code:\n * [A-Z]{2} (country) + [0-9A-Z]{9} (identifier) +\n * [0-9]{1} (check digit). Validated using the Luhn\n * algorithm on the alpha-numeric expansion.\n *\n * @see https://www.isin.org/\n */\n\nimport type {\n ValidateResult,\n GlobalValidator,\n} from \"./types\";\n\nimport { luhnChecksum } from \"#checksums/luhn\";\nimport { clean } from \"#util/clean\";\nimport { randomInt, randomPick } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { charValue, isalnum } from \"#util/strings\";\n\nconst ISIN_RE = /^[A-Z]{2}[0-9A-Z]{9}[0-9]$/;\n\nconst compact = (value: string): string =>\n clean(value, \" -\").toUpperCase();\n\n/**\n * Expand each character to its numeric value\n * (A=10..Z=35, digits unchanged) and concatenate.\n */\nconst expand = (value: string): string => {\n let result = \"\";\n for (let i = 0; i < value.length; i++) {\n const ch = value[i];\n if (ch !== undefined) {\n result += String(charValue(ch));\n }\n }\n return result;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 12) {\n return err(\n \"INVALID_LENGTH\",\n \"ISIN must be exactly 12 characters\",\n );\n }\n if (!isalnum(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"ISIN must contain only letters and digits\",\n );\n }\n if (!ISIN_RE.test(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"ISIN must match [A-Z]{2}[0-9A-Z]{9}[0-9]\",\n );\n }\n const expanded = expand(v);\n if (luhnChecksum(expanded) !== 0) {\n return err(\n \"INVALID_CHECKSUM\",\n \"ISIN check digit is incorrect\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => {\n const v = compact(value);\n return `${v.slice(0, 2)} ${v.slice(2, 6)} ${v.slice(6, 10)} ${v.slice(10)}`;\n};\n\nconst ISIN_COUNTRIES = [\n \"US\",\n \"GB\",\n \"DE\",\n \"FR\",\n \"JP\",\n] as const;\n\n/** Generate a random valid ISIN. */\nconst generate = (): string => {\n for (;;) {\n const cc = randomPick(ISIN_COUNTRIES);\n let nsin = \"\";\n for (let i = 0; i < 9; i++)\n nsin += String(randomInt(0, 9));\n const base = cc + nsin;\n for (let d = 0; d <= 9; d++) {\n const c = base + String(d);\n if (validate(c).valid) return c;\n }\n }\n};\n\n/** International Securities Identification Number. */\nconst isin: GlobalValidator = {\n scope: \"global\",\n name: \"International Securities Identification Number\",\n localName:\n \"International Securities Identification Number\",\n abbreviation: \"ISIN\",\n aliases: [\n \"ISIN\",\n \"International Securities Identification Number\",\n ] as const,\n candidatePattern: \"[A-Z]{2}[A-Z0-9]{9}\\\\d\",\n entityType: \"any\",\n sourceUrl: \"https://www.isin.org/\",\n examples: [\"US0378331005\", \"GB0002634946\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default isin;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AAuBA,MAAM,UAAU;AAEhB,MAAM,WAAW,UACf,MAAM,OAAO,IAAI,CAAC,CAAC,YAAY;;;;;AAMjC,MAAM,UAAU,UAA0B;CACxC,IAAI,SAAS;CACb,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,KAAK,MAAM;EACjB,IAAI,OAAO,KAAA,GACT,UAAU,OAAO,UAAU,EAAE,CAAC;CAElC;CACA,OAAO;AACT;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,IACf,OAAO,IACL,kBACA,oCACF;CAEF,IAAI,CAAC,QAAQ,CAAC,GACZ,OAAO,IACL,kBACA,2CACF;CAEF,IAAI,CAAC,QAAQ,KAAK,CAAC,GACjB,OAAO,IACL,kBACA,0CACF;CAGF,IAAI,aADa,OAAO,CACA,CAAC,MAAM,GAC7B,OAAO,IACL,oBACA,+BACF;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,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE;AAC1E;AAEA,MAAM,iBAAiB;CACrB;CACA;CACA;CACA;CACA;AACF;;AAGA,MAAM,iBAAyB;CAC7B,SAAS;EACP,MAAM,KAAK,WAAW,cAAc;EACpC,IAAI,OAAO;EACX,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,QAAQ,OAAO,UAAU,GAAG,CAAC,CAAC;EAChC,MAAM,OAAO,KAAK;EAClB,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;GAC3B,MAAM,IAAI,OAAO,OAAO,CAAC;GACzB,IAAI,SAAS,CAAC,CAAC,CAAC,OAAO,OAAO;EAChC;CACF;AACF;;AAGA,MAAM,OAAwB;CAC5B,OAAO;CACP,MAAM;CACN,WACE;CACF,cAAc;CACd,SAAS,CACP,QACA,gDACF;CACA,kBAAkB;CAClB,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,gBAAgB,cAAc;CACzC;CACA;CACA;CACA;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codicefiscale.js","names":["validateIva"],"sources":["../../src/it/codicefiscale.ts"],"sourcesContent":["/**\n * Codice Fiscale (Italian tax code).\n *\n * 16-character alphanumeric code encoding name,\n * birth date, gender, and birthplace. The last\n * character is a check letter computed using\n * odd/even position value tables.\n *\n * Supports omocodia: when two people share the\n * same code, the tax office replaces digit\n * positions with letters from the set LMNPQRSTUV\n * (L=0, M=1, N=2, P=3, Q=4, R=5, S=6, T=7,\n * U=8, V=9). Only these 10 letters are valid\n * substitutes at digit positions.\n *\n * Also accepts 11-digit numbers (delegates to\n * Partita IVA validation).\n *\n * @see https://www.agenziaentrate.gov.it/\n * @see https://it.wikipedia.org/wiki/Codice_fiscale#Omocodia\n */\n\nimport type {\n ParsedPersonId,\n ValidateResult,\n CountryValidator,\n} from \"../types\";\nimport { validate as validateIva } from \"./iva\";\n\nimport { clean } from \"#util/clean\";\nimport { randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\n// Values for odd-positioned characters (0-based\n// index 0, 2, 4, ...)\nconst ODD: Record<string, number> = {\n \"0\": 1,\n \"1\": 0,\n \"2\": 5,\n \"3\": 7,\n \"4\": 9,\n \"5\": 13,\n \"6\": 15,\n \"7\": 17,\n \"8\": 19,\n \"9\": 21,\n A: 1,\n B: 0,\n C: 5,\n D: 7,\n E: 9,\n F: 13,\n G: 15,\n H: 17,\n I: 19,\n J: 21,\n K: 2,\n L: 4,\n M: 18,\n N: 20,\n O: 11,\n P: 3,\n Q: 6,\n R: 8,\n S: 12,\n T: 14,\n U: 16,\n V: 10,\n W: 22,\n X: 25,\n Y: 24,\n Z: 23,\n};\n\n// Values for even-positioned characters (0-based\n// index 1, 3, 5, ...)\nconst EVEN: Record<string, number> = {\n \"0\": 0,\n \"1\": 1,\n \"2\": 2,\n \"3\": 3,\n \"4\": 4,\n \"5\": 5,\n \"6\": 6,\n \"7\": 7,\n \"8\": 8,\n \"9\": 9,\n A: 0,\n B: 1,\n C: 2,\n D: 3,\n E: 4,\n F: 5,\n G: 6,\n H: 7,\n I: 8,\n J: 9,\n K: 10,\n L: 11,\n M: 12,\n N: 13,\n O: 14,\n P: 15,\n Q: 16,\n R: 17,\n S: 18,\n T: 19,\n U: 20,\n V: 21,\n W: 22,\n X: 23,\n Y: 24,\n Z: 25,\n};\n\nconst CHECK_LETTERS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\n/** Omocodia letter-to-digit mapping. */\nconst OMOCODIA: Record<string, string> = {\n L: \"0\",\n M: \"1\",\n N: \"2\",\n P: \"3\",\n Q: \"4\",\n R: \"5\",\n S: \"6\",\n T: \"7\",\n U: \"8\",\n V: \"9\",\n};\n\n/** Month letter to 1-based month number. */\nconst MONTH_LETTERS: Record<string, number> = {\n A: 1,\n B: 2,\n C: 3,\n D: 4,\n E: 5,\n H: 6,\n L: 7,\n M: 8,\n P: 9,\n R: 10,\n S: 11,\n T: 12,\n};\n\nconst decodeCfDigit = (ch: string): number => {\n const mapped = OMOCODIA[ch];\n if (mapped !== undefined) return Number(mapped);\n return Number(ch);\n};\n\nconst compact = (value: string): string =>\n clean(value, \" -\").toUpperCase();\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n // 11-digit: delegate to Partita IVA\n if (v.length === 11 && isdigits(v)) {\n return validateIva(v);\n }\n\n if (v.length !== 16) {\n return err(\n \"INVALID_LENGTH\",\n \"Codice Fiscale must be 16 characters\",\n );\n }\n // Structural format: 6 letters + 2 alphanumeric\n // + 1 letter (month) + 2 alphanumeric + 1 letter\n // (municipality) + 3 alphanumeric + 1 check letter\n // The \"alphanumeric\" positions accept omocodia\n // substitution letters (LMNPQRSTUV for 0-9)\n if (\n // Omocodia: digits can be replaced with\n // LMNPQRSTUV only (not arbitrary letters)\n !/^[A-Z]{6}[0-9LMNPQRSTUV]{2}[ABCDEHLMPRST][0-9LMNPQRSTUV]{2}[A-Z][0-9LMNPQRSTUV]{3}[A-Z]$/.test(\n v,\n )\n ) {\n return err(\n \"INVALID_FORMAT\",\n \"Codice Fiscale format is invalid\",\n );\n }\n\n // Compute check letter\n let sum = 0;\n for (let i = 0; i < 15; i++) {\n const ch = v[i];\n if (ch === undefined) continue;\n if (i % 2 === 0) {\n // Odd position (1-based) = even index\n const val = ODD[ch];\n if (val === undefined) {\n return err(\n \"INVALID_FORMAT\",\n \"Codice Fiscale contains invalid char\",\n );\n }\n sum += val;\n } else {\n const val = EVEN[ch];\n if (val === undefined) {\n return err(\n \"INVALID_FORMAT\",\n \"Codice Fiscale contains invalid char\",\n );\n }\n sum += val;\n }\n }\n\n const expected = CHECK_LETTERS[sum % 26];\n if (expected !== v[15]) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Codice Fiscale check letter mismatch\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/**\n * Extract birth date and gender from a Codice Fiscale.\n * Returns null if the value is not valid or is an\n * 11-digit Partita IVA (no personal data embedded).\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 if (v.length !== 16) return null;\n\n const yy =\n decodeCfDigit(v.charAt(6)) * 10 +\n decodeCfDigit(v.charAt(7));\n const month = MONTH_LETTERS[v.charAt(8)];\n if (month === undefined) return null;\n let dd =\n decodeCfDigit(v.charAt(9)) * 10 +\n decodeCfDigit(v.charAt(10));\n\n const gender = dd > 40 ? \"female\" : \"male\";\n if (dd > 40) dd -= 40;\n\n const currentYear = new Date().getFullYear();\n let year = 2000 + yy;\n if (year > currentYear) year -= 100;\n\n return {\n birthDate: new Date(year, month - 1, dd),\n gender,\n };\n};\n\nconst LETTERS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\nconst MONTH_CODES = Object.keys(MONTH_LETTERS);\n\nconst randomLetter = (): string =>\n LETTERS.charAt(randomInt(0, LETTERS.length - 1));\n\n/** Generate a random valid 16-character Codice Fiscale. */\nconst generate = (): string => {\n let body = \"\";\n\n for (let i = 0; i < 6; i++) {\n body += randomLetter();\n }\n\n body += String(randomInt(0, 99)).padStart(2, \"0\");\n body +=\n MONTH_CODES[randomInt(0, MONTH_CODES.length - 1)] ??\n \"A\";\n\n const day =\n randomInt(1, 28) + (randomInt(0, 1) === 0 ? 0 : 40);\n body += String(day).padStart(2, \"0\");\n body += randomLetter();\n body += String(randomInt(0, 999)).padStart(3, \"0\");\n\n let sum = 0;\n for (let i = 0; i < body.length; i++) {\n const ch = body[i];\n if (ch === undefined) continue;\n sum += i % 2 === 0 ? (ODD[ch] ?? 0) : (EVEN[ch] ?? 0);\n }\n\n return `${body}${CHECK_LETTERS.charAt(sum % 26)}`;\n};\n\n/** Italian Tax Code. */\nconst codiceFiscale: CountryValidator<\n \"IT\",\n ParsedPersonId\n> = {\n name: \"Italian Tax Code\",\n localName: \"Codice Fiscale\",\n abbreviation: \"CF\",\n aliases: [\n \"codice fiscale\",\n \"C.F.\",\n \"CF\",\n \"cod. fisc.\",\n \"fiscal code\",\n ] as const,\n candidatePattern:\n \"[A-Z]{6}\\\\d{2}[A-Z]\\\\d{2}[A-Z]\\\\d{3}[A-Z]\",\n scope: \"country\",\n country: \"IT\",\n entityType: \"person\",\n description:\n \"Personal/company tax code (16-char personal, 11-digit company)\",\n sourceUrl: \"https://www.agenziaentrate.gov.it/\",\n lengths: [11, 16] as const,\n examples: [\"RCCMNL83S18D969H\"] as const,\n compact,\n format,\n parse,\n validate,\n generate,\n};\n\nexport default codiceFiscale;\nexport { compact, format, generate, parse, validate };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"codicefiscale.js","names":["validateIva"],"sources":["../../src/it/codicefiscale.ts"],"sourcesContent":["/**\n * Codice Fiscale (Italian tax code).\n *\n * 16-character alphanumeric code encoding name,\n * birth date, gender, and birthplace. The last\n * character is a check letter computed using\n * odd/even position value tables.\n *\n * Supports omocodia: when two people share the\n * same code, the tax office replaces digit\n * positions with letters from the set LMNPQRSTUV\n * (L=0, M=1, N=2, P=3, Q=4, R=5, S=6, T=7,\n * U=8, V=9). Only these 10 letters are valid\n * substitutes at digit positions.\n *\n * Also accepts 11-digit numbers (delegates to\n * Partita IVA validation).\n *\n * @see https://www.agenziaentrate.gov.it/\n * @see https://it.wikipedia.org/wiki/Codice_fiscale#Omocodia\n */\n\nimport type {\n ParsedPersonId,\n ValidateResult,\n CountryValidator,\n} from \"../types\";\nimport { validate as validateIva } from \"./iva\";\n\nimport { clean } from \"#util/clean\";\nimport { randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\n// Values for odd-positioned characters (0-based\n// index 0, 2, 4, ...)\nconst ODD: Record<string, number> = {\n \"0\": 1,\n \"1\": 0,\n \"2\": 5,\n \"3\": 7,\n \"4\": 9,\n \"5\": 13,\n \"6\": 15,\n \"7\": 17,\n \"8\": 19,\n \"9\": 21,\n A: 1,\n B: 0,\n C: 5,\n D: 7,\n E: 9,\n F: 13,\n G: 15,\n H: 17,\n I: 19,\n J: 21,\n K: 2,\n L: 4,\n M: 18,\n N: 20,\n O: 11,\n P: 3,\n Q: 6,\n R: 8,\n S: 12,\n T: 14,\n U: 16,\n V: 10,\n W: 22,\n X: 25,\n Y: 24,\n Z: 23,\n};\n\n// Values for even-positioned characters (0-based\n// index 1, 3, 5, ...)\nconst EVEN: Record<string, number> = {\n \"0\": 0,\n \"1\": 1,\n \"2\": 2,\n \"3\": 3,\n \"4\": 4,\n \"5\": 5,\n \"6\": 6,\n \"7\": 7,\n \"8\": 8,\n \"9\": 9,\n A: 0,\n B: 1,\n C: 2,\n D: 3,\n E: 4,\n F: 5,\n G: 6,\n H: 7,\n I: 8,\n J: 9,\n K: 10,\n L: 11,\n M: 12,\n N: 13,\n O: 14,\n P: 15,\n Q: 16,\n R: 17,\n S: 18,\n T: 19,\n U: 20,\n V: 21,\n W: 22,\n X: 23,\n Y: 24,\n Z: 25,\n};\n\nconst CHECK_LETTERS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\n/** Omocodia letter-to-digit mapping. */\nconst OMOCODIA: Record<string, string> = {\n L: \"0\",\n M: \"1\",\n N: \"2\",\n P: \"3\",\n Q: \"4\",\n R: \"5\",\n S: \"6\",\n T: \"7\",\n U: \"8\",\n V: \"9\",\n};\n\n/** Month letter to 1-based month number. */\nconst MONTH_LETTERS: Record<string, number> = {\n A: 1,\n B: 2,\n C: 3,\n D: 4,\n E: 5,\n H: 6,\n L: 7,\n M: 8,\n P: 9,\n R: 10,\n S: 11,\n T: 12,\n};\n\nconst decodeCfDigit = (ch: string): number => {\n const mapped = OMOCODIA[ch];\n if (mapped !== undefined) return Number(mapped);\n return Number(ch);\n};\n\nconst compact = (value: string): string =>\n clean(value, \" -\").toUpperCase();\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n\n // 11-digit: delegate to Partita IVA\n if (v.length === 11 && isdigits(v)) {\n return validateIva(v);\n }\n\n if (v.length !== 16) {\n return err(\n \"INVALID_LENGTH\",\n \"Codice Fiscale must be 16 characters\",\n );\n }\n // Structural format: 6 letters + 2 alphanumeric\n // + 1 letter (month) + 2 alphanumeric + 1 letter\n // (municipality) + 3 alphanumeric + 1 check letter\n // The \"alphanumeric\" positions accept omocodia\n // substitution letters (LMNPQRSTUV for 0-9)\n if (\n // Omocodia: digits can be replaced with\n // LMNPQRSTUV only (not arbitrary letters)\n !/^[A-Z]{6}[0-9LMNPQRSTUV]{2}[ABCDEHLMPRST][0-9LMNPQRSTUV]{2}[A-Z][0-9LMNPQRSTUV]{3}[A-Z]$/.test(\n v,\n )\n ) {\n return err(\n \"INVALID_FORMAT\",\n \"Codice Fiscale format is invalid\",\n );\n }\n\n // Compute check letter\n let sum = 0;\n for (let i = 0; i < 15; i++) {\n const ch = v[i];\n if (ch === undefined) continue;\n if (i % 2 === 0) {\n // Odd position (1-based) = even index\n const val = ODD[ch];\n if (val === undefined) {\n return err(\n \"INVALID_FORMAT\",\n \"Codice Fiscale contains invalid char\",\n );\n }\n sum += val;\n } else {\n const val = EVEN[ch];\n if (val === undefined) {\n return err(\n \"INVALID_FORMAT\",\n \"Codice Fiscale contains invalid char\",\n );\n }\n sum += val;\n }\n }\n\n const expected = CHECK_LETTERS[sum % 26];\n if (expected !== v[15]) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Codice Fiscale check letter mismatch\",\n );\n }\n\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string => compact(value);\n\n/**\n * Extract birth date and gender from a Codice Fiscale.\n * Returns null if the value is not valid or is an\n * 11-digit Partita IVA (no personal data embedded).\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 if (v.length !== 16) return null;\n\n const yy =\n decodeCfDigit(v.charAt(6)) * 10 +\n decodeCfDigit(v.charAt(7));\n const month = MONTH_LETTERS[v.charAt(8)];\n if (month === undefined) return null;\n let dd =\n decodeCfDigit(v.charAt(9)) * 10 +\n decodeCfDigit(v.charAt(10));\n\n const gender = dd > 40 ? \"female\" : \"male\";\n if (dd > 40) dd -= 40;\n\n const currentYear = new Date().getFullYear();\n let year = 2000 + yy;\n if (year > currentYear) year -= 100;\n\n return {\n birthDate: new Date(year, month - 1, dd),\n gender,\n };\n};\n\nconst LETTERS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\nconst MONTH_CODES = Object.keys(MONTH_LETTERS);\n\nconst randomLetter = (): string =>\n LETTERS.charAt(randomInt(0, LETTERS.length - 1));\n\n/** Generate a random valid 16-character Codice Fiscale. */\nconst generate = (): string => {\n let body = \"\";\n\n for (let i = 0; i < 6; i++) {\n body += randomLetter();\n }\n\n body += String(randomInt(0, 99)).padStart(2, \"0\");\n body +=\n MONTH_CODES[randomInt(0, MONTH_CODES.length - 1)] ??\n \"A\";\n\n const day =\n randomInt(1, 28) + (randomInt(0, 1) === 0 ? 0 : 40);\n body += String(day).padStart(2, \"0\");\n body += randomLetter();\n body += String(randomInt(0, 999)).padStart(3, \"0\");\n\n let sum = 0;\n for (let i = 0; i < body.length; i++) {\n const ch = body[i];\n if (ch === undefined) continue;\n sum += i % 2 === 0 ? (ODD[ch] ?? 0) : (EVEN[ch] ?? 0);\n }\n\n return `${body}${CHECK_LETTERS.charAt(sum % 26)}`;\n};\n\n/** Italian Tax Code. */\nconst codiceFiscale: CountryValidator<\n \"IT\",\n ParsedPersonId\n> = {\n name: \"Italian Tax Code\",\n localName: \"Codice Fiscale\",\n abbreviation: \"CF\",\n aliases: [\n \"codice fiscale\",\n \"C.F.\",\n \"CF\",\n \"cod. fisc.\",\n \"fiscal code\",\n ] as const,\n candidatePattern:\n \"[A-Z]{6}\\\\d{2}[A-Z]\\\\d{2}[A-Z]\\\\d{3}[A-Z]\",\n scope: \"country\",\n country: \"IT\",\n entityType: \"person\",\n description:\n \"Personal/company tax code (16-char personal, 11-digit company)\",\n sourceUrl: \"https://www.agenziaentrate.gov.it/\",\n lengths: [11, 16] as const,\n examples: [\"RCCMNL83S18D969H\"] as const,\n compact,\n format,\n parse,\n validate,\n generate,\n};\n\nexport default codiceFiscale;\nexport { compact, format, generate, parse, validate };\n"],"mappings":"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"}
|
package/dist/it/iva.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iva.js","names":[],"sources":["../../src/it/iva.ts"],"sourcesContent":["/**\n * Partita IVA (Italian VAT number).\n *\n * 11 digits: 7-digit company ID + 3-digit\n * province code + Luhn check digit.\n *\n * @see https://www.agenziaentrate.gov.it/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport {\n luhnValidate,\n luhnChecksum,\n} from \"#checksums/luhn\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst VALID_PROVINCES = new Set([\n ...Array.from({ length: 100 }, (_, i) =>\n String(i + 1).padStart(3, \"0\"),\n ),\n \"120\",\n \"121\",\n \"888\",\n \"999\",\n]);\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -\");\n if (v.startsWith(\"IT\") || v.startsWith(\"it\")) {\n v = v.slice(2);\n }\n return v;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 11) {\n return err(\n \"INVALID_LENGTH\",\n \"Partita IVA must be exactly 11 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Partita IVA must contain only digits\",\n );\n }\n // First 7 digits cannot all be zero\n if (/^0{7}/.test(v)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Partita IVA company ID cannot be all zeros\",\n );\n }\n // Province code validation\n const province = v.slice(7, 10);\n if (!VALID_PROVINCES.has(province)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Partita IVA province code is invalid\",\n );\n }\n if (!luhnValidate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Partita IVA fails Luhn check\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string =>\n `IT${compact(value)}`;\n\n/** Generate a random valid Italian Partita IVA. */\nconst generate = (): string => {\n const company = randomDigits(7);\n const province = String(randomInt(1, 100)).padStart(\n 3,\n \"0\",\n );\n const payload = company + province;\n const cs = luhnChecksum(payload + \"0\");\n return payload + String((10 - cs) % 10);\n};\n\n/** Italian VAT Number. */\nconst iva: CountryValidator<\"IT\"> = {\n name: \"Italian VAT Number\",\n localName: \"Partita IVA\",\n abbreviation: \"P.IVA\",\n aliases: [\n \"partita IVA\",\n \"P.IVA\",\n \"P. IVA\",\n \"VAT IT\",\n ] as const,\n candidatePattern: \"IT\\\\d{11}\",\n scope: \"country\",\n country: \"IT\",\n entityType: \"company\",\n sourceUrl: \"https://www.agenziaentrate.gov.it/\",\n examples: [\"00743110157\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default iva;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AAuBA,MAAM,kBAAkB,IAAI,IAAI;CAC9B,GAAG,MAAM,KAAK,EAAE,QAAQ,IAAI,IAAI,GAAG,MACjC,OAAO,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"iva.js","names":[],"sources":["../../src/it/iva.ts"],"sourcesContent":["/**\n * Partita IVA (Italian VAT number).\n *\n * 11 digits: 7-digit company ID + 3-digit\n * province code + Luhn check digit.\n *\n * @see https://www.agenziaentrate.gov.it/\n */\n\nimport type {\n ValidateResult,\n CountryValidator,\n} from \"../types\";\n\nimport {\n luhnValidate,\n luhnChecksum,\n} from \"#checksums/luhn\";\nimport { clean } from \"#util/clean\";\nimport { randomDigits, randomInt } from \"#util/generate\";\nimport { err } from \"#util/result\";\nimport { isdigits } from \"#util/strings\";\n\nconst VALID_PROVINCES = new Set([\n ...Array.from({ length: 100 }, (_, i) =>\n String(i + 1).padStart(3, \"0\"),\n ),\n \"120\",\n \"121\",\n \"888\",\n \"999\",\n]);\n\nconst compact = (value: string): string => {\n let v = clean(value, \" -\");\n if (v.startsWith(\"IT\") || v.startsWith(\"it\")) {\n v = v.slice(2);\n }\n return v;\n};\n\nconst validate = (value: string): ValidateResult => {\n const v = compact(value);\n if (v.length !== 11) {\n return err(\n \"INVALID_LENGTH\",\n \"Partita IVA must be exactly 11 digits\",\n );\n }\n if (!isdigits(v)) {\n return err(\n \"INVALID_FORMAT\",\n \"Partita IVA must contain only digits\",\n );\n }\n // First 7 digits cannot all be zero\n if (/^0{7}/.test(v)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Partita IVA company ID cannot be all zeros\",\n );\n }\n // Province code validation\n const province = v.slice(7, 10);\n if (!VALID_PROVINCES.has(province)) {\n return err(\n \"INVALID_COMPONENT\",\n \"Partita IVA province code is invalid\",\n );\n }\n if (!luhnValidate(v)) {\n return err(\n \"INVALID_CHECKSUM\",\n \"Partita IVA fails Luhn check\",\n );\n }\n return { valid: true, compact: v };\n};\n\nconst format = (value: string): string =>\n `IT${compact(value)}`;\n\n/** Generate a random valid Italian Partita IVA. */\nconst generate = (): string => {\n const company = randomDigits(7);\n const province = String(randomInt(1, 100)).padStart(\n 3,\n \"0\",\n );\n const payload = company + province;\n const cs = luhnChecksum(payload + \"0\");\n return payload + String((10 - cs) % 10);\n};\n\n/** Italian VAT Number. */\nconst iva: CountryValidator<\"IT\"> = {\n name: \"Italian VAT Number\",\n localName: \"Partita IVA\",\n abbreviation: \"P.IVA\",\n aliases: [\n \"partita IVA\",\n \"P.IVA\",\n \"P. IVA\",\n \"VAT IT\",\n ] as const,\n candidatePattern: \"IT\\\\d{11}\",\n scope: \"country\",\n country: \"IT\",\n entityType: \"company\",\n sourceUrl: \"https://www.agenziaentrate.gov.it/\",\n examples: [\"00743110157\"] as const,\n compact,\n format,\n validate,\n generate,\n};\n\nexport default iva;\nexport { compact, format, validate, generate };\n"],"mappings":";;;;;;AAuBA,MAAM,kBAAkB,IAAI,IAAI;CAC9B,GAAG,MAAM,KAAK,EAAE,QAAQ,IAAI,IAAI,GAAG,MACjC,OAAO,IAAI,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG,CAC/B;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,WAAW,UAA0B;CACzC,IAAI,IAAI,MAAM,OAAO,IAAI;CACzB,IAAI,EAAE,WAAW,IAAI,KAAK,EAAE,WAAW,IAAI,GACzC,IAAI,EAAE,MAAM,CAAC;CAEf,OAAO;AACT;AAEA,MAAM,YAAY,UAAkC;CAClD,MAAM,IAAI,QAAQ,KAAK;CACvB,IAAI,EAAE,WAAW,IACf,OAAO,IACL,kBACA,uCACF;CAEF,IAAI,CAAC,SAAS,CAAC,GACb,OAAO,IACL,kBACA,sCACF;CAGF,IAAI,QAAQ,KAAK,CAAC,GAChB,OAAO,IACL,qBACA,4CACF;CAGF,MAAM,WAAW,EAAE,MAAM,GAAG,EAAE;CAC9B,IAAI,CAAC,gBAAgB,IAAI,QAAQ,GAC/B,OAAO,IACL,qBACA,sCACF;CAEF,IAAI,CAAC,aAAa,CAAC,GACjB,OAAO,IACL,oBACA,8BACF;CAEF,OAAO;EAAE,OAAO;EAAM,SAAS;CAAE;AACnC;AAEA,MAAM,UAAU,UACd,KAAK,QAAQ,KAAK;;AAGpB,MAAM,iBAAyB;CAM7B,MAAM,UALU,aAAa,CAKP,IAJL,OAAO,UAAU,GAAG,GAAG,CAAC,CAAC,CAAC,SACzC,GACA,GAE+B;CACjC,MAAM,KAAK,aAAa,UAAU,GAAG;CACrC,OAAO,UAAU,QAAQ,KAAK,MAAM,EAAE;AACxC;;AAGA,MAAM,MAA8B;CAClC,MAAM;CACN,WAAW;CACX,cAAc;CACd,SAAS;EACP;EACA;EACA;EACA;CACF;CACA,kBAAkB;CAClB,OAAO;CACP,SAAS;CACT,YAAY;CACZ,WAAW;CACX,UAAU,CAAC,aAAa;CACxB;CACA;CACA;CACA;AACF"}
|