From 68171c59f82cc0bfb8522e1261e65481bc873e59 Mon Sep 17 00:00:00 2001 From: jan-kubica Date: Wed, 3 Jun 2026 10:09:02 +0200 Subject: [PATCH] feat: add scope discriminator to Validator Replace `country?: CountryCode` with a discriminated scope union so consumers can narrow country-scoped and global identifiers explicitly. Apply `scope: "global"` to cross-border validators and `scope: "country"` to country validators. Keep concrete validator exports branch-typed with `CountryValidator<"XX">` or `GlobalValidator`, and narrow country pattern helpers accordingly. Bump the package to 2.0.0 and update the changelog. --- CHANGELOG.md | 13 +++++++ __test__/invariants.test.ts | 39 +++++++++++++-------- package.json | 2 +- src/ad/nrt.ts | 8 +++-- src/ae/eid.ts | 8 +++-- src/ai/tin.ts | 8 +++-- src/al/nipt.ts | 8 +++-- src/am/tin.ts | 8 +++-- src/ar/cbu.ts | 8 +++-- src/ar/cuit.ts | 8 +++-- src/ar/dni.ts | 8 +++-- src/at/businessid.ts | 8 +++-- src/at/tin.ts | 8 +++-- src/at/uid.ts | 8 +++-- src/at/vnr.ts | 8 +++-- src/au/abn.ts | 8 +++-- src/au/acn.ts | 8 +++-- src/au/tfn.ts | 8 +++-- src/az/voen.ts | 8 +++-- src/ba/jmbg.ts | 5 +-- src/bd/nid.ts | 8 +++-- src/be/bis.ts | 8 +++-- src/be/nn.ts | 8 +++-- src/be/vat.ts | 8 +++-- src/bg/egn.ts | 5 +-- src/bg/pnf.ts | 8 +++-- src/bg/vat.ts | 8 +++-- src/bh/cpr.ts | 8 +++-- src/bic.ts | 8 +++-- src/br/cnpj.ts | 8 +++-- src/br/cpf.ts | 8 +++-- src/by/unp.ts | 8 +++-- src/bz/tin.ts | 8 +++-- src/ca/bn.ts | 8 +++-- src/ca/sin.ts | 8 +++-- src/ch/ssn.ts | 8 +++-- src/ch/uid.ts | 8 +++-- src/ch/vat.ts | 8 +++-- src/cl/rut.ts | 8 +++-- src/cn/ric.ts | 5 +-- src/cn/uscc.ts | 8 +++-- src/co/nit.ts | 8 +++-- src/cr/cpf.ts | 8 +++-- src/creditcard.ts | 8 +++-- src/cu/ni.ts | 5 +-- src/cy/vat.ts | 8 +++-- src/cz/dic.ts | 8 +++-- src/cz/ico.ts | 8 +++-- src/cz/rc.ts | 5 +-- src/de/handelsreg.ts | 8 +++-- src/de/idnr.ts | 8 +++-- src/de/stnr.ts | 8 +++-- src/de/svnr.ts | 8 +++-- src/de/vat.ts | 8 +++-- src/dk/cpr.ts | 5 +-- src/dk/cvr.ts | 8 +++-- src/dk/vat.ts | 8 +++-- src/do/rnc.ts | 8 +++-- src/ec/ruc.ts | 8 +++-- src/ee/ik.ts | 5 +-- src/ee/registrikood.ts | 8 +++-- src/ee/vat.ts | 8 +++-- src/eg/tn.ts | 8 +++-- src/es/cif.ts | 8 +++-- src/es/dni.ts | 8 +++-- src/es/nie.ts | 8 +++-- src/es/nss.ts | 8 +++-- src/es/vat.ts | 8 +++-- src/eu/vat.ts | 8 +++-- src/fi/hetu.ts | 5 +-- src/fi/vat.ts | 8 +++-- src/fi/ytunnus.ts | 8 +++-- src/fr/nif.ts | 8 +++-- src/fr/nir.ts | 5 +-- src/fr/siren.ts | 8 +++-- src/fr/siret.ts | 8 +++-- src/fr/tva.ts | 8 +++-- src/gb/nino.ts | 8 +++-- src/gb/sedol.ts | 8 +++-- src/gb/utr.ts | 8 +++-- src/gb/vat.ts | 8 +++-- src/ge/pin.ts | 8 +++-- src/gh/tin.ts | 8 +++-- src/gr/amka.ts | 8 +++-- src/gr/vat.ts | 8 +++-- src/gt/nit.ts | 8 +++-- src/hk/hkid.ts | 8 +++-- src/hr/vat.ts | 8 +++-- src/hu/vat.ts | 8 +++-- src/iban.ts | 8 +++-- src/id/npwp.ts | 8 +++-- src/ie/pps.ts | 8 +++-- src/ie/vat.ts | 8 +++-- src/il/idnr.ts | 8 +++-- src/in/aadhaar.ts | 8 +++-- src/in/gstin.ts | 8 +++-- src/in/pan.ts | 8 +++-- src/index.ts | 3 ++ src/iq/nid.ts | 8 +++-- src/ir/nid.ts | 8 +++-- src/is/kennitala.ts | 8 +++-- src/is/vsk.ts | 8 +++-- src/isin.ts | 8 +++-- src/it/codicefiscale.ts | 8 +++-- src/it/iva.ts | 8 +++-- src/jp/cn.ts | 8 +++-- src/jp/mynumber.ts | 8 +++-- src/kr/brn.ts | 8 +++-- src/kr/rrn.ts | 5 +-- src/kw/civil.ts | 5 +-- src/kz/iin.ts | 5 +-- src/lei.ts | 8 +++-- src/li/peid.ts | 8 +++-- src/lk/nic.ts | 5 +-- src/lt/asmens.ts | 8 +++-- src/lt/vat.ts | 8 +++-- src/lu/vat.ts | 8 +++-- src/luhn.ts | 8 +++-- src/lv/vat.ts | 8 +++-- src/ma/ice.ts | 8 +++-- src/mc/tva.ts | 8 +++-- src/md/idno.ts | 8 +++-- src/me/pib.ts | 8 +++-- src/mk/edb.ts | 8 +++-- src/mt/vat.ts | 8 +++-- src/mu/brn.ts | 8 +++-- src/mx/clabe.ts | 8 +++-- src/mx/curp.ts | 5 +-- src/mx/rfc.ts | 8 +++-- src/my/nric.ts | 5 +-- src/ng/nin.ts | 8 +++-- src/ni/ruc.ts | 8 +++-- src/nl/bsn.ts | 8 +++-- src/nl/kvk.ts | 8 +++-- src/nl/vat.ts | 8 +++-- src/no/fodselsnummer.ts | 8 +++-- src/no/mva.ts | 8 +++-- src/no/orgnr.ts | 8 +++-- src/nz/ird.ts | 8 +++-- src/pa/ruc.ts | 8 +++-- src/patterns.ts | 67 +++++++++++++++++++++++++++---------- src/pe/ruc.ts | 8 +++-- src/ph/philid.ts | 8 +++-- src/pk/cnic.ts | 8 +++-- src/pl/nip.ts | 8 +++-- src/pl/pesel.ts | 5 +-- src/pl/regon.ts | 8 +++-- src/pt/cc.ts | 8 +++-- src/pt/vat.ts | 8 +++-- src/ro/cnp.ts | 5 +-- src/ro/vat.ts | 8 +++-- src/rs/pib.ts | 8 +++-- src/ru/inn.ts | 8 +++-- src/se/orgnr.ts | 8 +++-- src/se/personnummer.ts | 48 +++++++++++++------------- src/se/vat.ts | 8 +++-- src/sg/uen.ts | 8 +++-- src/si/emso.ts | 5 +-- src/si/vat.ts | 8 +++-- src/sk/dic.ts | 8 +++-- src/sk/ico.ts | 5 +-- src/sk/rc.ts | 8 +++-- src/th/tin.ts | 8 +++-- src/tr/tckimlik.ts | 8 +++-- src/tr/vkn.ts | 8 +++-- src/tw/ubn.ts | 8 +++-- src/types.ts | 37 ++++++++++++++++++-- src/ua/edrpou.ts | 8 +++-- src/us/ein.ts | 8 +++-- src/us/itin.ts | 8 +++-- src/us/rtn.ts | 8 +++-- src/us/ssn.ts | 8 +++-- src/uy/rut.ts | 8 +++-- src/ve/rif.ts | 8 +++-- src/vn/mst.ts | 8 +++-- src/za/idnr.ts | 5 +-- 176 files changed, 1104 insertions(+), 397 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b346b87..bc46399 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,18 @@ The format is based on and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.0.0] - 2026-06-03 + +### Changed + +- `Validator` now carries a `scope` discriminator: + `{ scope: "country"; country: CountryCode }` or + `{ scope: "global" }`. The optional `country?` field + is removed in favor of this discriminated union. + Consumers that read `validator.country` must first + narrow on `validator.scope === "country"`. + `ValidatorScope` is exported from the package root. + ## [1.0.0] - 2026-05-17 ### Changed @@ -57,5 +69,6 @@ and this project adheres to artifacts. - Per-identifier entry points for tree-shaking. +[2.0.0]: https://github.com/stella/stdnum/releases/tag/v2.0.0 [1.0.0]: https://github.com/stella/stdnum/releases/tag/v1.0.0 [0.1.0]: https://github.com/stella/stdnum/releases/tag/v0.1.0 diff --git a/__test__/invariants.test.ts b/__test__/invariants.test.ts index 4eb4fa8..2ed7b78 100644 --- a/__test__/invariants.test.ts +++ b/__test__/invariants.test.ts @@ -4,9 +4,9 @@ * Auto-discovers all validators and checks metadata * consistency: examples exist, examples validate, * compact is idempotent, entityType is valid, - * required fields are non-empty, directory name - * matches country field, and example lengths match - * the declared `lengths` array. + * required fields are non-empty, scope matches the + * export namespace, and example lengths match the + * declared `lengths` array. * * New validators get all checks automatically when * added to the index. @@ -93,22 +93,33 @@ for (const [name, v] of validators) { }); } - // (c) Directory name matches country field - test("directory name matches country field", () => { + // (c) Scope matches export namespace + test("scope matches export namespace", () => { const ns = name.split(".")[0]!; if (INTERNATIONAL_NAMESPACES.has(ns)) { expect( - v.country, - `${name} is international but has country "${v.country}"`, - ).toBeUndefined(); - } else { - // Namespace `is_` maps to country "IS" - const expected = ns.replace(/_$/, "").toUpperCase(); + v.scope, + `${name}: expected global scope but got "${v.scope}"`, + ).toBe("global"); expect( - v.country, - `${name}: expected country "${expected}" but got "${v.country}"`, - ).toBe(expected); + "country" in v, + `${name} is global but has a country field`, + ).toBe(false); + return; } + + if (v.scope !== "country") { + throw new Error( + `${name}: expected country scope but got "${v.scope}"`, + ); + } + + // Namespace `is_` maps to country "IS" + const expected = ns.replace(/_$/, "").toUpperCase(); + expect( + v.country, + `${name}: expected country "${expected}" but got "${v.country}"`, + ).toBe(expected); }); // (d) Examples validate successfully diff --git a/package.json b/package.json index 46ad8af..84a9d04 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@stll/stdnum", - "version": "1.0.0", + "version": "2.0.0", "description": "Validate, compact, and format standard identifiers for Node.js and Bun. Pure TypeScript, zero dependencies, tree-shakeable per identifier.", "keywords": [ "credit-card", diff --git a/src/ad/nrt.ts b/src/ad/nrt.ts index 129e595..f9de3c9 100644 --- a/src/ad/nrt.ts +++ b/src/ad/nrt.ts @@ -25,7 +25,10 @@ const generate = (): string => { * @see https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Andorra-TIN.pdf */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { @@ -98,12 +101,13 @@ const format = (value: string): string => { }; /** Andorra NRT (Número de Registre Tributari). */ -const nrt: Validator = { +const nrt: CountryValidator<"AD"> = { name: "Andorra Tax Number", localName: "Número de Registre Tributari", abbreviation: "NRT", aliases: ["NRT", "Número de Registre Tributari"] as const, candidatePattern: "[A-Z]-?\\d{6}-?[A-Z]", + scope: "country", country: "AD", entityType: "any", sourceUrl: diff --git a/src/ae/eid.ts b/src/ae/eid.ts index 25e60af..8f6445c 100644 --- a/src/ae/eid.ts +++ b/src/ae/eid.ts @@ -10,7 +10,10 @@ * @see https://u.ae/en/information-and-services/visa-and-emirates-id/emirates-id */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { luhnChecksum, @@ -77,12 +80,13 @@ const generate = (): string => { }; /** UAE Emirates ID. */ -const eid: Validator = { +const eid: CountryValidator<"AE"> = { name: "Emirates ID", localName: "رقم الهوية", abbreviation: "EID", aliases: ["EID", "Emirates ID", "رقم الهوية"] as const, candidatePattern: "784-\\d{4}-\\d{7}-\\d", + scope: "country", country: "AE", entityType: "person", lengths: [15], diff --git a/src/ai/tin.ts b/src/ai/tin.ts index b5cc47d..db7196c 100644 --- a/src/ai/tin.ts +++ b/src/ai/tin.ts @@ -23,7 +23,10 @@ const generate = (): string => { * @see https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Anguilla-TIN.pdf */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -74,12 +77,13 @@ const format = (value: string): string => { * (format-only validation, no published check * digit algorithm). */ -const tin: Validator = { +const tin: CountryValidator<"AI"> = { name: "Anguilla Tax Identification Number", localName: "Tax Identification Number", abbreviation: "TIN", aliases: ["TIN"] as const, candidatePattern: "\\d{11}", + scope: "country", country: "AI", entityType: "any", lengths: [10] as const, diff --git a/src/al/nipt.ts b/src/al/nipt.ts index 8dc1649..5a7ab2d 100644 --- a/src/al/nipt.ts +++ b/src/al/nipt.ts @@ -18,7 +18,10 @@ const generate = (): string => { * @see https://www.tatime.gov.al/eng/c/4/103/business-lifecycle */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -57,13 +60,14 @@ const validate = (value: string): ValidateResult => { const format = (value: string): string => compact(value); /** Albanian NIPT (tax identification number). */ -const nipt: Validator = { +const nipt: CountryValidator<"AL"> = { name: "Albanian Tax Number", localName: "Numri i Identifikimit për Personin e Tatueshëm", abbreviation: "NIPT", aliases: ["NIPT", "NUIS"] as const, candidatePattern: "[A-Z]\\d{8}[A-Z]", + scope: "country", country: "AL", entityType: "any", sourceUrl: "https://www.tatime.gov.al/", diff --git a/src/am/tin.ts b/src/am/tin.ts index 93af26b..b75970d 100644 --- a/src/am/tin.ts +++ b/src/am/tin.ts @@ -16,7 +16,10 @@ const generate = (): string => randomDigits(8); * @see https://www.src.am/en/taxpayerSearchSystemPage/112 */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -49,12 +52,13 @@ const validate = (value: string): ValidateResult => { const format = (value: string): string => compact(value); /** Armenian Tax Identification Number. */ -const tin: Validator = { +const tin: CountryValidator<"AM"> = { name: "Armenian Tax ID", localName: "Հարկ վճարողի հաշվառման համար", abbreviation: "TIN", aliases: ["ՀՎՀՀ", "TIN"] as const, candidatePattern: "\\d{8}", + scope: "country", country: "AM", entityType: "any", lengths: [8] as const, diff --git a/src/ar/cbu.ts b/src/ar/cbu.ts index b2b2eb4..4355b1c 100644 --- a/src/ar/cbu.ts +++ b/src/ar/cbu.ts @@ -8,7 +8,10 @@ * @see https://es.wikipedia.org/wiki/Clave_bancaria_uniforme */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -84,12 +87,13 @@ const generate = (): string => { }; /** Argentine Uniform Bank Key. */ -const cbu: Validator = { +const cbu: CountryValidator<"AR"> = { name: "Argentine Bank Account Number", localName: "Clave Bancaria Uniforme", abbreviation: "CBU", aliases: ["CBU", "Clave Bancaria Uniforme"] as const, candidatePattern: "\\d{22}", + scope: "country", country: "AR", entityType: "any", sourceUrl: diff --git a/src/ar/cuit.ts b/src/ar/cuit.ts index 288851b..324def8 100644 --- a/src/ar/cuit.ts +++ b/src/ar/cuit.ts @@ -16,7 +16,10 @@ * @see https://en.wikipedia.org/wiki/CUIT_(Argentina) */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomPick } from "#util/generate"; @@ -120,7 +123,7 @@ const generate = (): string => { * Examples sourced from python-stdnum test suite * (ar.cuit module). */ -const cuit: Validator = { +const cuit: CountryValidator<"AR"> = { name: "Argentine Tax ID", localName: "Clave Única de Identificación Tributaria", abbreviation: "CUIT", @@ -130,6 +133,7 @@ const cuit: Validator = { "Clave Única de Identificación Tributaria", ] as const, candidatePattern: "\\d{2}-?\\d{8}-?\\d", + scope: "country", country: "AR", entityType: "any", compact, diff --git a/src/ar/dni.ts b/src/ar/dni.ts index 164914a..e94f8ea 100644 --- a/src/ar/dni.ts +++ b/src/ar/dni.ts @@ -11,7 +11,10 @@ const generate = (): string => randomDigits(8); * @see https://en.wikipedia.org/wiki/Documento_Nacional_de_Identidad_(Argentina) */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -53,7 +56,7 @@ const format = (value: string): string => { }; /** Argentine National Identity Document. */ -const dni: Validator = { +const dni: CountryValidator<"AR"> = { name: "Argentine Identity Card", localName: "Documento Nacional de Identidad", abbreviation: "DNI", @@ -63,6 +66,7 @@ const dni: Validator = { "Documento de Identidad", ] as const, candidatePattern: "\\d{1,2}\\.?\\d{3}\\.?\\d{3}", + scope: "country", country: "AR", entityType: "person", sourceUrl: diff --git a/src/at/businessid.ts b/src/at/businessid.ts index dcde0a8..b333afa 100644 --- a/src/at/businessid.ts +++ b/src/at/businessid.ts @@ -16,7 +16,10 @@ const generate = (): string => { * @see https://www.justiz.gv.at/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -54,12 +57,13 @@ const format = (value: string): string => `FN ${compact(value)}`; /** Austrian Company Register Number. */ -const businessid: Validator = { +const businessid: CountryValidator<"AT"> = { name: "Austrian Company Register Number", localName: "Firmenbuchnummer", abbreviation: "FN", aliases: ["Firmenbuchnummer", "FN", "FBN"] as const, candidatePattern: "FN\\s?\\d{5,6}[a-z]?", + scope: "country", country: "AT", entityType: "company", sourceUrl: "https://www.justiz.gv.at/", diff --git a/src/at/tin.ts b/src/at/tin.ts index cc70b51..2a3c5e2 100644 --- a/src/at/tin.ts +++ b/src/at/tin.ts @@ -10,7 +10,10 @@ * @see https://service.bmf.gv.at/Service/Anwend/Behoerden/show_mast.asp */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -69,12 +72,13 @@ const generate = (): string => { }; /** Austrian Tax Identification Number. */ -const tin: Validator = { +const tin: CountryValidator<"AT"> = { name: "Austrian Tax Identification Number", localName: "Abgabenkontonummer", abbreviation: "TIN", aliases: ["Steuernummer", "St.Nr.", "TIN"] as const, candidatePattern: "\\d{2}-?\\d{3}/\\d{4}", + scope: "country", country: "AT", entityType: "any", sourceUrl: diff --git a/src/at/uid.ts b/src/at/uid.ts index 61c1b4f..b1f34b9 100644 --- a/src/at/uid.ts +++ b/src/at/uid.ts @@ -8,7 +8,10 @@ * @see https://www.bmf.gv.at/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { luhnChecksum } from "#checksums/luhn"; import { clean } from "#util/clean"; @@ -68,7 +71,7 @@ const generate = (): string => { }; /** Austrian VAT Identification Number. */ -const uid: Validator = { +const uid: CountryValidator<"AT"> = { name: "Austrian VAT Number", localName: "Umsatzsteuer-Identifikationsnummer", abbreviation: "UID", @@ -78,6 +81,7 @@ const uid: Validator = { "ATU", ] as const, candidatePattern: "ATU\\d{8}", + scope: "country", country: "AT", entityType: "company", sourceUrl: "https://www.bmf.gv.at/", diff --git a/src/at/vnr.ts b/src/at/vnr.ts index 8360c66..1f7ffd0 100644 --- a/src/at/vnr.ts +++ b/src/at/vnr.ts @@ -21,7 +21,10 @@ * @see https://www.sozialversicherung.at/cdscontent/?contentid=10007.820902&viewmode=content */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -130,7 +133,7 @@ const generate = (): string => { }; /** Austrian Social Insurance Number. */ -const vnr: Validator = { +const vnr: CountryValidator<"AT"> = { name: "Austrian Social Insurance Number", localName: "Versicherungsnummer", abbreviation: "VNR", @@ -141,6 +144,7 @@ const vnr: Validator = { "Sozialversicherungsnummer", ] as const, candidatePattern: "\\d{4}\\s?\\d{6}", + scope: "country", country: "AT", entityType: "person", sourceUrl: diff --git a/src/au/abn.ts b/src/au/abn.ts index 65ccbe8..72c6f38 100644 --- a/src/au/abn.ts +++ b/src/au/abn.ts @@ -9,7 +9,10 @@ * @see https://abr.business.gov.au/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -65,12 +68,13 @@ const generate = (): string => { }; /** Australian Business Number. */ -const abn: Validator = { +const abn: CountryValidator<"AU"> = { name: "Australian Business Number", localName: "Australian Business Number", abbreviation: "ABN", aliases: ["ABN", "Australian Business Number"] as const, candidatePattern: "\\d{2}\\s?\\d{3}\\s?\\d{3}\\s?\\d{3}", + scope: "country", country: "AU", entityType: "company", sourceUrl: "https://abr.business.gov.au/", diff --git a/src/au/acn.ts b/src/au/acn.ts index d3c5461..7c0e144 100644 --- a/src/au/acn.ts +++ b/src/au/acn.ts @@ -9,7 +9,10 @@ * @see https://asic.gov.au/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -66,12 +69,13 @@ const generate = (): string => { }; /** Australian Company Number. */ -const acn: Validator = { +const acn: CountryValidator<"AU"> = { name: "Australian Company Number", localName: "Australian Company Number", abbreviation: "ACN", aliases: ["ACN", "Australian Company Number"] as const, candidatePattern: "\\d{3}\\s?\\d{3}\\s?\\d{3}", + scope: "country", country: "AU", entityType: "company", sourceUrl: "https://asic.gov.au/", diff --git a/src/au/tfn.ts b/src/au/tfn.ts index c13d851..43fd041 100644 --- a/src/au/tfn.ts +++ b/src/au/tfn.ts @@ -9,7 +9,10 @@ * @see https://www.ato.gov.au/Individuals/Tax-file-number/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -64,12 +67,13 @@ const generate = (): string => { }; /** Australian Tax File Number. */ -const tfn: Validator = { +const tfn: CountryValidator<"AU"> = { name: "Tax File Number", localName: "Tax File Number", abbreviation: "TFN", aliases: ["TFN", "Tax File Number"] as const, candidatePattern: "\\d{8,9}", + scope: "country", country: "AU", entityType: "person", sourceUrl: diff --git a/src/az/voen.ts b/src/az/voen.ts index 8b7d1eb..8ba6f60 100644 --- a/src/az/voen.ts +++ b/src/az/voen.ts @@ -13,7 +13,10 @@ * @see https://www.taxes.gov.az/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -106,12 +109,13 @@ const generate = (): string => { * * Examples sourced from python-stdnum test suite. */ -const voen: Validator = { +const voen: CountryValidator<"AZ"> = { name: "Azerbaijani Tax ID", localName: "Vergi Ödəyicisinin Eyniləşdirmə Nömrəsi", abbreviation: "VÖEN", aliases: ["VÖEN"] as const, candidatePattern: "\\d{10}", + scope: "country", country: "AZ", entityType: "any", lengths: [10] as const, diff --git a/src/ba/jmbg.ts b/src/ba/jmbg.ts index ceaa35a..8666613 100644 --- a/src/ba/jmbg.ts +++ b/src/ba/jmbg.ts @@ -11,7 +11,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { weightedSum } from "#checksums/weighted-sum"; @@ -106,12 +106,13 @@ const generate = (): string => { }; /** Bosnian Unique Master Citizen Number. */ -const jmbg: Validator = { +const jmbg: CountryValidator<"BA", ParsedPersonId> = { name: "Bosnian Personal ID", localName: "Jedinstveni matični broj građana", abbreviation: "JMBG", aliases: ["JMBG", "matični broj"] as const, candidatePattern: "\\d{13}", + scope: "country", country: "BA", entityType: "person", lengths: [13] as const, diff --git a/src/bd/nid.ts b/src/bd/nid.ts index c480926..b1c716f 100644 --- a/src/bd/nid.ts +++ b/src/bd/nid.ts @@ -30,7 +30,10 @@ const generate = (): string => { * @see https://www.nidw.gov.bd/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomPick } from "#util/generate"; @@ -106,7 +109,7 @@ const validate = (value: string): ValidateResult => { const format = (value: string): string => compact(value); /** Bangladesh National Identity Number. */ -const nid: Validator = { +const nid: CountryValidator<"BD"> = { name: "National Identity Number", localName: "জাতীয় পরিচয়পত্র", abbreviation: "NID", @@ -116,6 +119,7 @@ const nid: Validator = { "National ID Card", ] as const, candidatePattern: "\\d{10,17}", + scope: "country", country: "BD", entityType: "person", lengths: [10, 13, 17], diff --git a/src/be/bis.ts b/src/be/bis.ts index a10e98c..b9e83e2 100644 --- a/src/be/bis.ts +++ b/src/be/bis.ts @@ -10,7 +10,10 @@ * @see https://nl.wikipedia.org/wiki/Rijksregisternummer */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { checksum, format as nnFormat } from "./nn"; import { clean } from "#util/clean"; @@ -83,13 +86,14 @@ const generate = (): string => { }; /** Belgian BIS Number. */ -const bis: Validator = { +const bis: CountryValidator<"BE"> = { name: "Belgian BIS Number", localName: "BIS-nummer", abbreviation: "BIS", aliases: ["BIS-nummer", "numéro BIS"] as const, candidatePattern: "\\d{2}\\.?\\d{2}\\.?\\d{2}-?\\d{3}\\.?\\d{2}", + scope: "country", country: "BE", entityType: "person", sourceUrl: diff --git a/src/be/nn.ts b/src/be/nn.ts index 4310110..be6bde8 100644 --- a/src/be/nn.ts +++ b/src/be/nn.ts @@ -10,7 +10,10 @@ * @see https://www.ibz.rrn.fgov.be/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomInt } from "#util/generate"; @@ -100,7 +103,7 @@ const generate = (): string => { }; /** Belgian National Number. */ -const nn: Validator = { +const nn: CountryValidator<"BE"> = { name: "Belgian National Number", localName: "Numéro national", abbreviation: "NN", @@ -111,6 +114,7 @@ const nn: Validator = { ] as const, candidatePattern: "\\d{2}\\.?\\d{2}\\.?\\d{2}-?\\d{3}\\.?\\d{2}", + scope: "country", country: "BE", entityType: "person", sourceUrl: "https://www.ibz.rrn.fgov.be/", diff --git a/src/be/vat.ts b/src/be/vat.ts index 54d3ef5..5db4e07 100644 --- a/src/be/vat.ts +++ b/src/be/vat.ts @@ -8,7 +8,10 @@ * @see https://www.oecd.org/content/dam/oecd/en/topics/policy-issue-focus/aeoi/belgium-tin.pdf */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -82,7 +85,7 @@ const generate = (): string => { }; /** Belgian VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"BE"> = { name: "Belgian VAT Number", localName: "BTW-identificatienummer", abbreviation: "BTW", @@ -93,6 +96,7 @@ const vat: Validator = { "ondernemingsnummer", ] as const, candidatePattern: "BE0?\\d{9,10}", + scope: "country", country: "BE", entityType: "company", sourceUrl: "https://finances.belgium.be/", diff --git a/src/bg/egn.ts b/src/bg/egn.ts index e9a75f0..06c905a 100644 --- a/src/bg/egn.ts +++ b/src/bg/egn.ts @@ -18,7 +18,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { weightedSum } from "#checksums/weighted-sum"; @@ -137,7 +137,7 @@ const generate = (): string => { }; /** Bulgarian Personal Identification Number. */ -const egn: Validator = { +const egn: CountryValidator<"BG", ParsedPersonId> = { name: "Bulgarian Personal ID", localName: "Единен граждански номер", abbreviation: "ЕГН", @@ -147,6 +147,7 @@ const egn: Validator = { "EGN", ] as const, candidatePattern: "\\d{10}", + scope: "country", country: "BG", entityType: "person", sourceUrl: diff --git a/src/bg/pnf.ts b/src/bg/pnf.ts index 81bbe50..a5a7bbd 100644 --- a/src/bg/pnf.ts +++ b/src/bg/pnf.ts @@ -7,7 +7,10 @@ * @see https://en.wikipedia.org/wiki/Unique_citizenship_number */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -61,7 +64,7 @@ const generate = (): string => { }; /** Bulgarian Personal Number of a Foreigner. */ -const pnf: Validator = { +const pnf: CountryValidator<"BG"> = { name: "Bulgarian Foreigner Number", localName: "Личен номер на чужденец", abbreviation: "ЛНЧ", @@ -71,6 +74,7 @@ const pnf: Validator = { "PNF", ] as const, candidatePattern: "\\d{10}", + scope: "country", country: "BG", entityType: "person", sourceUrl: diff --git a/src/bg/vat.ts b/src/bg/vat.ts index 3cb96b0..1ec60c4 100644 --- a/src/bg/vat.ts +++ b/src/bg/vat.ts @@ -7,7 +7,10 @@ * @see https://www.oecd.org/content/dam/oecd/en/topics/policy-issue-focus/aeoi/bulgaria-tin.pdf */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -132,7 +135,7 @@ const generate = (): string => { }; /** Bulgarian VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"BG"> = { name: "Bulgarian VAT Number", localName: "ИН по ДДС", abbreviation: "ИН по ДДС", @@ -141,6 +144,7 @@ const vat: Validator = { "идентификационен номер по ДДС", ] as const, candidatePattern: "BG\\d{9,10}", + scope: "country", country: "BG", entityType: "any", sourceUrl: "https://www.nra.bg/", diff --git a/src/bh/cpr.ts b/src/bh/cpr.ts index 7f2cbc7..e102a67 100644 --- a/src/bh/cpr.ts +++ b/src/bh/cpr.ts @@ -16,7 +16,10 @@ * @see https://www.bahrain.bh/wps/portal/IDInfo_en */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -68,12 +71,13 @@ const generate = (): string => { }; /** Bahrain Central Population Registration number. */ -const cpr: Validator = { +const cpr: CountryValidator<"BH"> = { name: "Central Population Registration Number", localName: "الرقم السكاني", abbreviation: "CPR", aliases: ["CPR", "الرقم السكاني"] as const, candidatePattern: "\\d{9}", + scope: "country", country: "BH", entityType: "person", lengths: [9] as const, diff --git a/src/bic.ts b/src/bic.ts index 5dfd6a2..289b87a 100644 --- a/src/bic.ts +++ b/src/bic.ts @@ -36,7 +36,10 @@ const generate = (): string => { * @see https://www.swift.com/ */ -import type { ValidateResult, Validator } from "./types"; +import type { + ValidateResult, + GlobalValidator, +} from "./types"; import { clean } from "#util/clean"; import { @@ -82,7 +85,8 @@ const format = (value: string): string => { }; /** Business Identifier Code (SWIFT/BIC). */ -const bic: Validator = { +const bic: GlobalValidator = { + scope: "global", name: "Business Identifier Code", localName: "Business Identifier Code", abbreviation: "BIC", diff --git a/src/br/cnpj.ts b/src/br/cnpj.ts index c0f3b3d..82b53d7 100644 --- a/src/br/cnpj.ts +++ b/src/br/cnpj.ts @@ -19,7 +19,10 @@ * @see https://en.wikipedia.org/wiki/CNPJ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -128,7 +131,7 @@ const generate = (): string => { * - Petrobras: 33.000.167/0001-01 * - Banco do Brasil: 00.000.000/0001-91 */ -const cnpj: Validator = { +const cnpj: CountryValidator<"BR"> = { name: "Brazilian CNPJ", localName: "Cadastro Nacional da Pessoa Jurídica", abbreviation: "CNPJ", @@ -138,6 +141,7 @@ const cnpj: Validator = { ] as const, candidatePattern: "\\d{2}\\.?\\d{3}\\.?\\d{3}/?\\d{4}-?\\d{2}", + scope: "country", country: "BR", entityType: "company", sourceUrl: "https://www.gov.br/receitafederal/", diff --git a/src/br/cpf.ts b/src/br/cpf.ts index 254c810..51d3f71 100644 --- a/src/br/cpf.ts +++ b/src/br/cpf.ts @@ -13,7 +13,10 @@ * @see https://en.wikipedia.org/wiki/CPF_number */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -94,12 +97,13 @@ const generate = (): string => { }; /** Brazilian CPF (personal tax ID). */ -const cpf: Validator = { +const cpf: CountryValidator<"BR"> = { name: "Brazilian CPF", localName: "Cadastro de Pessoas Físicas", abbreviation: "CPF", aliases: ["CPF", "Cadastro de Pessoas Físicas"] as const, candidatePattern: "\\d{3}\\.?\\d{3}\\.?\\d{3}-?\\d{2}", + scope: "country", country: "BR", entityType: "person", sourceUrl: "https://www.gov.br/receitafederal/", diff --git a/src/by/unp.ts b/src/by/unp.ts index 5bd4eb7..edb9e1c 100644 --- a/src/by/unp.ts +++ b/src/by/unp.ts @@ -11,7 +11,10 @@ * @see https://www.nalog.gov.by/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -139,12 +142,13 @@ const generate = (): string => { }; /** Belarus UNP (Учётный номер плательщика). */ -const unp: Validator = { +const unp: CountryValidator<"BY"> = { name: "Belarus Tax Number", localName: "Учётный номер плательщика", abbreviation: "УНП", aliases: ["УНП", "UNP"] as const, candidatePattern: "\\d{9}", + scope: "country", country: "BY", entityType: "any", sourceUrl: "https://www.nalog.gov.by/", diff --git a/src/bz/tin.ts b/src/bz/tin.ts index 9bf910c..554a875 100644 --- a/src/bz/tin.ts +++ b/src/bz/tin.ts @@ -25,7 +25,10 @@ * @see https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Belize-TIN.pdf */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -94,12 +97,13 @@ const generate = (): string => { * * Examples derived from stdnum-js test suite. */ -const tin: Validator = { +const tin: CountryValidator<"BZ"> = { name: "Belize Tax Identification Number", localName: "Tax Identification Number", abbreviation: "TIN", aliases: ["TIN"] as const, candidatePattern: "\\d{6}", + scope: "country", country: "BZ", entityType: "any", lengths: [6, 8] as const, diff --git a/src/ca/bn.ts b/src/ca/bn.ts index b96f22e..c925dcf 100644 --- a/src/ca/bn.ts +++ b/src/ca/bn.ts @@ -8,7 +8,10 @@ * @see https://www.canada.ca/en/services/taxes/business-number.html */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { luhnValidate, @@ -82,7 +85,7 @@ const generate = (): string => { }; /** Canadian Business Number. */ -const bn: Validator = { +const bn: CountryValidator<"CA"> = { name: "Business Number", localName: "Business Number", abbreviation: "BN", @@ -92,6 +95,7 @@ const bn: Validator = { "numéro d'entreprise", ] as const, candidatePattern: "\\d{9}\\s?[A-Z]{2}\\s?\\d{4}", + scope: "country", country: "CA", entityType: "company", sourceUrl: diff --git a/src/ca/sin.ts b/src/ca/sin.ts index 6cff477..8d89472 100644 --- a/src/ca/sin.ts +++ b/src/ca/sin.ts @@ -8,7 +8,10 @@ * @see https://en.wikipedia.org/wiki/Social_Insurance_Number */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { luhnValidate, @@ -66,7 +69,7 @@ const generate = (): string => { }; /** Canadian Social Insurance Number. */ -const sin: Validator = { +const sin: CountryValidator<"CA"> = { name: "Social Insurance Number", localName: "Social Insurance Number", abbreviation: "SIN", @@ -76,6 +79,7 @@ const sin: Validator = { "NAS", ] as const, candidatePattern: "\\d{3}-?\\d{3}-?\\d{3}", + scope: "country", country: "CA", entityType: "person", sourceUrl: diff --git a/src/ch/ssn.ts b/src/ch/ssn.ts index 380147e..59885aa 100644 --- a/src/ch/ssn.ts +++ b/src/ch/ssn.ts @@ -8,7 +8,10 @@ * @see https://www.bsv.admin.ch/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -70,7 +73,7 @@ const generate = (): string => { }; /** Swiss Social Security Number. */ -const ssn: Validator = { +const ssn: CountryValidator<"CH"> = { name: "Swiss Social Security Number", localName: "AHV-Versichertennummer", abbreviation: "AHV", @@ -81,6 +84,7 @@ const ssn: Validator = { "AHV", ] as const, candidatePattern: "756\\.?\\d{4}\\.?\\d{4}\\.?\\d{2}", + scope: "country", country: "CH", entityType: "person", sourceUrl: "https://www.bsv.admin.ch/", diff --git a/src/ch/uid.ts b/src/ch/uid.ts index 528b91b..c7f1bc6 100644 --- a/src/ch/uid.ts +++ b/src/ch/uid.ts @@ -8,7 +8,10 @@ * @see https://www.uid.admin.ch/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -84,7 +87,7 @@ const generate = (): string => { }; /** Swiss Business Identification Number. */ -const uid: Validator = { +const uid: CountryValidator<"CH"> = { name: "Swiss Business ID", localName: "Unternehmens-Identifikationsnummer", abbreviation: "UID", @@ -94,6 +97,7 @@ const uid: Validator = { "IDE", ] as const, candidatePattern: "CHE-?\\d{3}\\.?\\d{3}\\.?\\d{3}", + scope: "country", country: "CH", entityType: "company", sourceUrl: "https://www.uid.admin.ch/", diff --git a/src/ch/vat.ts b/src/ch/vat.ts index f018398..beb6057 100644 --- a/src/ch/vat.ts +++ b/src/ch/vat.ts @@ -8,7 +8,10 @@ * @see https://www.estv.admin.ch/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { validate as validateUid, generate as generateUid, @@ -64,13 +67,14 @@ const format = (value: string): string => { const generate = (): string => generateUid() + "MWST"; /** Swiss VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"CH"> = { name: "Swiss VAT Number", localName: "Mehrwertsteuernummer", abbreviation: "MWST", aliases: ["MWST", "TVA", "IVA"] as const, candidatePattern: "CHE-?\\d{3}\\.?\\d{3}\\.?\\d{3}\\s?(?:MWST|TVA|IVA)", + scope: "country", country: "CH", entityType: "company", sourceUrl: "https://www.estv.admin.ch/", diff --git a/src/cl/rut.ts b/src/cl/rut.ts index 8222970..c6db737 100644 --- a/src/cl/rut.ts +++ b/src/cl/rut.ts @@ -13,7 +13,10 @@ * @see https://en.wikipedia.org/wiki/Rol_%C3%9Anico_Tributario */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -99,12 +102,13 @@ const generate = (): string => { * Examples sourced from python-stdnum test suite * (cl.rut module). */ -const rut: Validator = { +const rut: CountryValidator<"CL"> = { name: "Chilean Tax ID", localName: "Rol Único Tributario", abbreviation: "RUT", aliases: ["RUT", "Rol Único Tributario"] as const, candidatePattern: "\\d{1,2}\\.?\\d{3}\\.?\\d{3}-?[\\dkK]", + scope: "country", country: "CL", entityType: "any", compact, diff --git a/src/cn/ric.ts b/src/cn/ric.ts index 6be4cfe..176ad4f 100644 --- a/src/cn/ric.ts +++ b/src/cn/ric.ts @@ -14,7 +14,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { @@ -155,12 +155,13 @@ const generate = (): string => { }; /** Chinese Resident Identity Card number. */ -const ric: Validator = { +const ric: CountryValidator<"CN", ParsedPersonId> = { name: "Chinese Resident Identity Card", localName: "居民身份证号码", abbreviation: "RIC", aliases: ["身份证", "居民身份证号码", "RIC"] as const, candidatePattern: "\\d{17}[\\dX]", + scope: "country", country: "CN", entityType: "person", description: diff --git a/src/cn/uscc.ts b/src/cn/uscc.ts index fbbe614..d9ace28 100644 --- a/src/cn/uscc.ts +++ b/src/cn/uscc.ts @@ -9,7 +9,10 @@ * @see https://zh.wikipedia.org/wiki/统一社会信用代码 */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { @@ -98,13 +101,14 @@ const generate = (): string => { }; /** Chinese Unified Social Credit Code. */ -const uscc: Validator = { +const uscc: CountryValidator<"CN"> = { name: "Unified Social Credit Code", localName: "统一社会信用代码", abbreviation: "USCC", aliases: ["统一社会信用代码", "USCC"] as const, candidatePattern: "[0-9A-HJ-NP-RTUW-Y]{2}\\d{6}[0-9A-HJ-NP-RTUW-Y]{10}", + scope: "country", country: "CN", entityType: "company", description: diff --git a/src/co/nit.ts b/src/co/nit.ts index 48d31fa..6c68ad9 100644 --- a/src/co/nit.ts +++ b/src/co/nit.ts @@ -10,7 +10,10 @@ * @see https://es.wikipedia.org/wiki/Número_de_identificación_tributaria */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -86,7 +89,7 @@ const generate = (): string => { }; /** Colombian tax identification number. */ -const nit: Validator = { +const nit: CountryValidator<"CO"> = { name: "Número de Identificación Tributaria", localName: "Número de Identificación Tributaria", abbreviation: "NIT", @@ -95,6 +98,7 @@ const nit: Validator = { "Número de Identificación Tributaria", ] as const, candidatePattern: "\\d{9,10}-?\\d", + scope: "country", country: "CO", entityType: "any", description: "Tax identifier issued by the DIAN", diff --git a/src/cr/cpf.ts b/src/cr/cpf.ts index c736a5c..0a894cd 100644 --- a/src/cr/cpf.ts +++ b/src/cr/cpf.ts @@ -23,7 +23,10 @@ const generate = (): string => { * @see https://www.tse.go.cr/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -91,12 +94,13 @@ const format = (value: string): string => { * * Examples sourced from python-stdnum test suite. */ -const cpf: Validator = { +const cpf: CountryValidator<"CR"> = { name: "Costa Rican Physical Person ID", localName: "Cédula de Persona Física", abbreviation: "CPF", aliases: ["CPF", "cédula de persona física"] as const, candidatePattern: "\\d{9,12}", + scope: "country", country: "CR", entityType: "person", lengths: [10] as const, diff --git a/src/creditcard.ts b/src/creditcard.ts index 7ea7c0a..b7bc12e 100644 --- a/src/creditcard.ts +++ b/src/creditcard.ts @@ -9,7 +9,10 @@ * @see https://www.iso.org/standard/70484.html */ -import type { ValidateResult, Validator } from "./types"; +import type { + ValidateResult, + GlobalValidator, +} from "./types"; import { luhnChecksum, @@ -162,7 +165,8 @@ const generate = (): string => { }; /** Credit Card Number (Luhn). */ -const creditCard: Validator = { +const creditCard: GlobalValidator = { + scope: "global", name: "Credit Card Number", localName: "Credit Card Number", abbreviation: "CC", diff --git a/src/cu/ni.ts b/src/cu/ni.ts index 07e5bfd..0560b6c 100644 --- a/src/cu/ni.ts +++ b/src/cu/ni.ts @@ -18,7 +18,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { clean } from "#util/clean"; @@ -119,7 +119,7 @@ const generate = (): string => { * * Examples sourced from python-stdnum test suite. */ -const ni: Validator = { +const ni: CountryValidator<"CU", ParsedPersonId> = { name: "Cuban Identity Card Number", localName: "Número de Identidad", abbreviation: "NI", @@ -129,6 +129,7 @@ const ni: Validator = { "carnet de identidad", ] as const, candidatePattern: "\\d{11}", + scope: "country", country: "CU", entityType: "person", lengths: [11] as const, diff --git a/src/cy/vat.ts b/src/cy/vat.ts index 9c4e63f..e9ccbcb 100644 --- a/src/cy/vat.ts +++ b/src/cy/vat.ts @@ -7,7 +7,10 @@ * @see https://www.oecd.org/content/dam/oecd/en/topics/policy-issue-focus/aeoi/cyprus-tin.pdf */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -110,12 +113,13 @@ const generate = (): string => { }; /** Cypriot VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"CY"> = { name: "Cypriot VAT Number", localName: "Αριθμός Εγγραφής Φ.Π.Α.", abbreviation: "ΦΠΑ", aliases: ["ΦΠΑ", "VAT CY"] as const, candidatePattern: "CY\\d{8}[A-Z]", + scope: "country", country: "CY", entityType: "company", sourceUrl: "https://www.mof.gov.cy/", diff --git a/src/cz/dic.ts b/src/cz/dic.ts index dc86d34..cee2017 100644 --- a/src/cz/dic.ts +++ b/src/cz/dic.ts @@ -11,7 +11,10 @@ * @see https://adisspr.mfcr.cz/dpr/DphReg */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { validate as validateRc } from "./rc"; import { weightedSum } from "#checksums/weighted-sum"; @@ -115,12 +118,13 @@ const generate = (): string => { }; /** Czech VAT Number. */ -const dic: Validator = { +const dic: CountryValidator<"CZ"> = { name: "Czech VAT Number", localName: "Daňové identifikační číslo", abbreviation: "DIČ", aliases: ["DIČ", "daňové identifikační číslo"] as const, candidatePattern: "CZ\\d{8,10}", + scope: "country", country: "CZ", entityType: "any", sourceUrl: "https://adisspr.mfcr.cz/dpr/DphReg", diff --git a/src/cz/ico.ts b/src/cz/ico.ts index 683fb13..8795453 100644 --- a/src/cz/ico.ts +++ b/src/cz/ico.ts @@ -8,7 +8,10 @@ * @see https://www.czso.cz/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -59,12 +62,13 @@ const generate = (): string => { }; /** Czech Company Identification Number. */ -const ico: Validator = { +const ico: CountryValidator<"CZ"> = { name: "Czech Company ID", localName: "Identifikační číslo osoby", abbreviation: "IČO", aliases: ["IČO", "IČ", "identifikační číslo"] as const, candidatePattern: "\\d{8}", + scope: "country", country: "CZ", entityType: "company", description: diff --git a/src/cz/rc.ts b/src/cz/rc.ts index 7e79e69..ae2d274 100644 --- a/src/cz/rc.ts +++ b/src/cz/rc.ts @@ -27,7 +27,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { clean } from "#util/clean"; @@ -196,12 +196,13 @@ const generate = (): string => { }; /** Czech/Slovak Birth Number. */ -const rc: Validator = { +const rc: CountryValidator<"CZ", ParsedPersonId> = { name: "Czech Birth Number", localName: "Rodné číslo", abbreviation: "RČ", aliases: ["rodné číslo", "RČ", "birth number"] as const, candidatePattern: "\\d{6}/\\d{3,4}", + scope: "country", country: "CZ", entityType: "person", description: diff --git a/src/de/handelsreg.ts b/src/de/handelsreg.ts index 90bce4c..0525f1c 100644 --- a/src/de/handelsreg.ts +++ b/src/de/handelsreg.ts @@ -31,7 +31,10 @@ const generate = (): string => { * @see https://de.wikipedia.org/wiki/Handelsregister_(Deutschland) */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomPick } from "#util/generate"; @@ -92,7 +95,7 @@ const validate = (value: string): ValidateResult => { const format = (value: string): string => compact(value); /** German Company Register Number. */ -const handelsreg: Validator = { +const handelsreg: CountryValidator<"DE"> = { name: "German Company Register Number", localName: "Handelsregisternummer", abbreviation: "HReg", @@ -103,6 +106,7 @@ const handelsreg: Validator = { "HRA", ] as const, candidatePattern: "(?:HRA|HRB|GnR|PR|VR)\\s*\\d{1,7}", + scope: "country", country: "DE", entityType: "company", sourceUrl: diff --git a/src/de/idnr.ts b/src/de/idnr.ts index e74e7d2..32b5546 100644 --- a/src/de/idnr.ts +++ b/src/de/idnr.ts @@ -10,7 +10,10 @@ * @see https://www.bzst.de/DE/Privatpersonen/SteuerlicheIdentifikationsnummer/steuerlicheidentifikationsnummer_node.html */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { mod1110validate, @@ -118,7 +121,7 @@ const generate = (): string => { }; /** German Personal Tax ID. */ -const idnr: Validator = { +const idnr: CountryValidator<"DE"> = { name: "German Tax ID", localName: "Steuerliche Identifikationsnummer", abbreviation: "IdNr", @@ -128,6 +131,7 @@ const idnr: Validator = { "Steuer-ID", ] as const, candidatePattern: "\\d{2}\\s?\\d{3}\\s?\\d{3}\\s?\\d{3}", + scope: "country", country: "DE", entityType: "person", sourceUrl: diff --git a/src/de/stnr.ts b/src/de/stnr.ts index 2aa46f2..868bba7 100644 --- a/src/de/stnr.ts +++ b/src/de/stnr.ts @@ -26,7 +26,10 @@ const generate = (): string => { * @see https://de.wikipedia.org/wiki/Steuernummer */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -194,12 +197,13 @@ const charCat = (ch: string): string => { }; /** German Tax Number (Steuernummer). */ -const stnr: Validator = { +const stnr: CountryValidator<"DE"> = { name: "German Tax Number", localName: "Steuernummer", abbreviation: "StNr", aliases: ["Steuernummer", "St.Nr."] as const, candidatePattern: "\\d{2,4}/\\d{3,4}/\\d{4,5}", + scope: "country", country: "DE", entityType: "any", description: diff --git a/src/de/svnr.ts b/src/de/svnr.ts index aede413..d45bff8 100644 --- a/src/de/svnr.ts +++ b/src/de/svnr.ts @@ -9,7 +9,10 @@ * @see https://de.wikipedia.org/wiki/Sozialversicherungsnummer */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { @@ -137,7 +140,7 @@ const generate = (): string => { }; /** German Social Insurance Number. */ -const svnr: Validator = { +const svnr: CountryValidator<"DE"> = { name: "German Social Insurance Number", localName: "Sozialversicherungsnummer", abbreviation: "SVNR", @@ -147,6 +150,7 @@ const svnr: Validator = { "Versicherungsnummer", ] as const, candidatePattern: "\\d{2}\\s?\\d{6}\\s?[A-Z]\\s?\\d{3}", + scope: "country", country: "DE", entityType: "person", description: diff --git a/src/de/vat.ts b/src/de/vat.ts index 335b999..817431c 100644 --- a/src/de/vat.ts +++ b/src/de/vat.ts @@ -9,7 +9,10 @@ * @see https://www.bzst.de/SharedDocs/Downloads/DE/Merkblaetter/ust_idnr_aufbau.pdf */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { mod1110checkDigit, @@ -70,7 +73,7 @@ const generate = (): string => { }; /** German VAT Identification Number. */ -const vat: Validator = { +const vat: CountryValidator<"DE"> = { name: "German VAT Number", localName: "Umsatzsteuer-Identifikationsnummer", abbreviation: "USt-IdNr.", @@ -80,6 +83,7 @@ const vat: Validator = { "VAT DE", ] as const, candidatePattern: "DE\\d{9}", + scope: "country", country: "DE", entityType: "company", description: diff --git a/src/dk/cpr.ts b/src/dk/cpr.ts index f092c0b..16ca5de 100644 --- a/src/dk/cpr.ts +++ b/src/dk/cpr.ts @@ -11,7 +11,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { clean } from "#util/clean"; @@ -114,12 +114,13 @@ const generate = (): string => { }; /** Danish Personal Identification Number. */ -const cpr: Validator = { +const cpr: CountryValidator<"DK", ParsedPersonId> = { name: "Danish Personal ID", localName: "Det Centrale Personregister", abbreviation: "CPR", aliases: ["CPR-nummer", "personnummer", "CPR"] as const, candidatePattern: "\\d{6}-?\\d{4}", + scope: "country", country: "DK", entityType: "person", sourceUrl: "https://cpr.dk/", diff --git a/src/dk/cvr.ts b/src/dk/cvr.ts index ac48abc..884cb5c 100644 --- a/src/dk/cvr.ts +++ b/src/dk/cvr.ts @@ -13,7 +13,10 @@ * for CVR. */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -67,12 +70,13 @@ const generate = (): string => { }; /** Danish Central Business Register Number. */ -const cvr: Validator = { +const cvr: CountryValidator<"DK"> = { name: "Danish Business Register Number", localName: "CVR-nummer", abbreviation: "CVR", aliases: ["CVR-nummer", "CVR"] as const, candidatePattern: "\\d{8}", + scope: "country", country: "DK", entityType: "company", sourceUrl: "https://erhvervsstyrelsen.dk/", diff --git a/src/dk/vat.ts b/src/dk/vat.ts index bae6950..4ddd7ba 100644 --- a/src/dk/vat.ts +++ b/src/dk/vat.ts @@ -11,7 +11,10 @@ * for CVR. */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -71,12 +74,13 @@ const generate = (): string => { }; /** Danish VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"DK"> = { name: "Danish VAT Number", localName: "Momsregistreringsnummer", abbreviation: "CVR", aliases: ["momsnummer", "SE-nummer"] as const, candidatePattern: "DK\\d{8}", + scope: "country", country: "DK", entityType: "company", sourceUrl: "https://erhvervsstyrelsen.dk/", diff --git a/src/do/rnc.ts b/src/do/rnc.ts index f5e31ef..c1ed378 100644 --- a/src/do/rnc.ts +++ b/src/do/rnc.ts @@ -14,7 +14,10 @@ * @see https://dgii.gov.do/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { luhnValidate } from "#checksums/luhn"; import { clean } from "#util/clean"; @@ -102,7 +105,7 @@ const generate = (): string => { * * Examples sourced from python-stdnum test suite. */ -const rnc: Validator = { +const rnc: CountryValidator<"DO"> = { name: "Dominican Republic Tax ID", localName: "Registro Nacional del Contribuyente", abbreviation: "RNC", @@ -111,6 +114,7 @@ const rnc: Validator = { "Registro Nacional del Contribuyente", ] as const, candidatePattern: "\\d{9}", + scope: "country", country: "DO", entityType: "any", lengths: [9, 11] as const, diff --git a/src/ec/ruc.ts b/src/ec/ruc.ts index f63f153..b5d2c47 100644 --- a/src/ec/ruc.ts +++ b/src/ec/ruc.ts @@ -17,7 +17,10 @@ * @see https://www.sri.gob.ec/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -169,7 +172,7 @@ const generate = (): string => { }; /** Ecuadorian tax identification number. */ -const ruc: Validator = { +const ruc: CountryValidator<"EC"> = { name: "Registro Único de Contribuyentes", localName: "Registro Único de Contribuyentes", abbreviation: "RUC", @@ -178,6 +181,7 @@ const ruc: Validator = { "Registro Único de Contribuyentes", ] as const, candidatePattern: "\\d{13}", + scope: "country", country: "EC", entityType: "any", description: diff --git a/src/ee/ik.ts b/src/ee/ik.ts index b7988ee..6921b8c 100644 --- a/src/ee/ik.ts +++ b/src/ee/ik.ts @@ -20,7 +20,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { weightedSum } from "#checksums/weighted-sum"; @@ -144,12 +144,13 @@ const generate = (): string => { }; /** Estonian Personal Identification Code. */ -const ik: Validator = { +const ik: CountryValidator<"EE", ParsedPersonId> = { name: "Estonian Personal ID", localName: "Isikukood", abbreviation: "IK", aliases: ["isikukood", "IK"] as const, candidatePattern: "[1-6]\\d{10}", + scope: "country", country: "EE", entityType: "person", sourceUrl: diff --git a/src/ee/registrikood.ts b/src/ee/registrikood.ts index d618308..872cbb8 100644 --- a/src/ee/registrikood.ts +++ b/src/ee/registrikood.ts @@ -7,7 +7,10 @@ * @see https://www.rik.ee/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { twoPassCheck } from "./ik"; import { clean } from "#util/clean"; @@ -62,12 +65,13 @@ const generate = (): string => { }; /** Estonian Company Registration Code. */ -const registrikood: Validator = { +const registrikood: CountryValidator<"EE"> = { name: "Estonian Company Registration Code", localName: "Registrikood", abbreviation: "Registrikood", aliases: ["registrikood"] as const, candidatePattern: "\\d{8}", + scope: "country", country: "EE", entityType: "company", sourceUrl: "https://www.rik.ee/", diff --git a/src/ee/vat.ts b/src/ee/vat.ts index 6001cf8..7bf689e 100644 --- a/src/ee/vat.ts +++ b/src/ee/vat.ts @@ -8,7 +8,10 @@ * @see https://www.emta.ee/en */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -62,7 +65,7 @@ const generate = (): string => { }; /** Estonian VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"EE"> = { name: "Estonian VAT Number", localName: "Käibemaksukohustuslase number", abbreviation: "KMKR", @@ -71,6 +74,7 @@ const vat: Validator = { "KMKR", ] as const, candidatePattern: "EE\\d{9}", + scope: "country", country: "EE", entityType: "company", sourceUrl: "https://www.emta.ee/en", diff --git a/src/eg/tn.ts b/src/eg/tn.ts index 3b53f79..2dc1a2a 100644 --- a/src/eg/tn.ts +++ b/src/eg/tn.ts @@ -11,7 +11,10 @@ const generate = (): string => randomDigits(9); * @see https://www.eta.gov.eg/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -81,12 +84,13 @@ const format = (value: string): string => { }; /** Egyptian Tax Registration Number. */ -const tn: Validator = { +const tn: CountryValidator<"EG"> = { name: "Egyptian Tax Registration Number", localName: "الرقم الضريبي", abbreviation: "TN", aliases: ["الرقم الضريبي", "tax number"] as const, candidatePattern: "\\d{9}", + scope: "country", country: "EG", entityType: "any", compact, diff --git a/src/es/cif.ts b/src/es/cif.ts index fa0c90f..79b9e47 100644 --- a/src/es/cif.ts +++ b/src/es/cif.ts @@ -9,7 +9,10 @@ * @see https://www.agenciatributaria.es/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { cifChecksum } from "./vat"; import { clean } from "#util/clean"; @@ -81,7 +84,7 @@ const generate = (): string => { }; /** Spanish Company Tax ID (CIF). */ -const cif: Validator = { +const cif: CountryValidator<"ES"> = { name: "Spanish Company Tax ID", localName: "Código de Identificación Fiscal", abbreviation: "CIF", @@ -90,6 +93,7 @@ const cif: Validator = { "código de identificación fiscal", ] as const, candidatePattern: "[A-HJNP-SUVW]\\d{7}[\\dA-J]", + scope: "country", country: "ES", entityType: "company", sourceUrl: "https://www.agenciatributaria.es/", diff --git a/src/es/dni.ts b/src/es/dni.ts index 9323aa5..26abc2a 100644 --- a/src/es/dni.ts +++ b/src/es/dni.ts @@ -8,7 +8,10 @@ * @see https://www.interior.gob.es/opencms/es/servicios-al-ciudadano/tramites-y-gestiones/dni/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -59,7 +62,7 @@ const generate = (): string => { }; /** Spanish National Identity Document. */ -const dni: Validator = { +const dni: CountryValidator<"ES"> = { name: "Spanish National ID", localName: "Documento Nacional de Identidad", abbreviation: "DNI", @@ -69,6 +72,7 @@ const dni: Validator = { "documento nacional de identidad", ] as const, candidatePattern: "\\d{1,2}\\.?\\d{3}\\.?\\d{3}-?[A-Z]", + scope: "country", country: "ES", entityType: "person", sourceUrl: diff --git a/src/es/nie.ts b/src/es/nie.ts index 3f97030..8325daa 100644 --- a/src/es/nie.ts +++ b/src/es/nie.ts @@ -8,7 +8,10 @@ * @see https://www.interior.gob.es/opencms/es/servicios-al-ciudadano/tramites-y-gestiones/nie/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { CHECK_LETTERS } from "./dni"; import { clean } from "#util/clean"; @@ -82,7 +85,7 @@ const generate = (): string => { }; /** Spanish Foreigner Identification Number. */ -const nie: Validator = { +const nie: CountryValidator<"ES"> = { name: "Spanish Foreigner ID", localName: "Número de Identidad de Extranjero", abbreviation: "NIE", @@ -92,6 +95,7 @@ const nie: Validator = { "número de identidad de extranjero", ] as const, candidatePattern: "[XYZ]-?\\d{7}-?[A-Z]", + scope: "country", country: "ES", entityType: "person", sourceUrl: diff --git a/src/es/nss.ts b/src/es/nss.ts index 49a3569..65f8044 100644 --- a/src/es/nss.ts +++ b/src/es/nss.ts @@ -15,7 +15,10 @@ * @see https://intervia.com/doc/validar-numeros-de-la-seguridad-social/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -85,12 +88,13 @@ const generate = (): string => { }; /** Spanish Social Security Number. */ -const nss: Validator = { +const nss: CountryValidator<"ES"> = { name: "Spanish Social Security Number", localName: "Número de la Seguridad Social", abbreviation: "NSS", aliases: ["NSS", "número de seguridad social"] as const, candidatePattern: "\\d{12}", + scope: "country", country: "ES", entityType: "person", description: diff --git a/src/es/vat.ts b/src/es/vat.ts index d61b2ca..31cf17d 100644 --- a/src/es/vat.ts +++ b/src/es/vat.ts @@ -8,7 +8,10 @@ * @see https://www.agenciatributaria.es/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -158,7 +161,7 @@ const generate = (): string => { }; /** Spanish VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"ES"> = { name: "Spanish VAT Number", localName: "Número de Identificación Fiscal", abbreviation: "NIF", @@ -168,6 +171,7 @@ const vat: Validator = { "número de identificación fiscal", ] as const, candidatePattern: "ES[A-Z]\\d{7}[A-Z\\d]", + scope: "country", country: "ES", entityType: "any", sourceUrl: "https://www.agenciatributaria.es/", diff --git a/src/eu/vat.ts b/src/eu/vat.ts index 1b77200..bf2e72c 100644 --- a/src/eu/vat.ts +++ b/src/eu/vat.ts @@ -40,7 +40,10 @@ import roVat from "../ro/vat"; import seVat from "../se/vat"; import siVat from "../si/vat"; import skDic from "../sk/dic"; -import type { Validator, ValidateResult } from "../types"; +import type { + GlobalValidator, + ValidateResult, +} from "../types"; import { clean } from "#util/clean"; import { randomInt } from "#util/generate"; @@ -197,7 +200,8 @@ const generate = (): string => { }; /** European Union VAT Number. */ -const euVat: Validator = { +const euVat: GlobalValidator = { + scope: "global", name: "EU VAT Number", localName: "EU VAT Number", abbreviation: "EU VAT", diff --git a/src/fi/hetu.ts b/src/fi/hetu.ts index 87b5fec..a9817f3 100644 --- a/src/fi/hetu.ts +++ b/src/fi/hetu.ts @@ -11,7 +11,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { clean } from "#util/clean"; @@ -173,7 +173,7 @@ const generate = (): string => { }; /** Finnish Personal Identity Code. */ -const hetu: Validator = { +const hetu: CountryValidator<"FI", ParsedPersonId> = { name: "Finnish Personal ID", localName: "Henkilötunnus", abbreviation: "HETU", @@ -183,6 +183,7 @@ const hetu: Validator = { "sosiaaliturvatunnus", ] as const, candidatePattern: "\\d{6}[-+A]\\d{3}[\\dA-Z]", + scope: "country", country: "FI", entityType: "person", sourceUrl: "https://dvv.fi/en/personal-identity-code", diff --git a/src/fi/vat.ts b/src/fi/vat.ts index 0040ef2..a769f26 100644 --- a/src/fi/vat.ts +++ b/src/fi/vat.ts @@ -8,7 +8,10 @@ * @see https://www.ytj.fi/en/index/businessid.html */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -62,12 +65,13 @@ const generate = (): string => { }; /** Finnish VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"FI"> = { name: "Finnish VAT Number", localName: "Arvonlisäveronumero", abbreviation: "ALV nro", aliases: ["ALV-numero", "Y-tunnus"] as const, candidatePattern: "FI\\d{8}", + scope: "country", country: "FI", entityType: "company", sourceUrl: "https://www.ytj.fi/en/index/businessid.html", diff --git a/src/fi/ytunnus.ts b/src/fi/ytunnus.ts index df6a23a..49c817e 100644 --- a/src/fi/ytunnus.ts +++ b/src/fi/ytunnus.ts @@ -8,7 +8,10 @@ * @see https://www.ytj.fi/en/index/businessid.html */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -59,7 +62,7 @@ const generate = (): string => { }; /** Finnish Business ID. */ -const ytunnus: Validator = { +const ytunnus: CountryValidator<"FI"> = { name: "Finnish Business ID", localName: "Y-tunnus", abbreviation: "Y-tunnus", @@ -69,6 +72,7 @@ const ytunnus: Validator = { "FO-nummer", ] as const, candidatePattern: "\\d{7}-\\d", + scope: "country", country: "FI", entityType: "company", sourceUrl: "https://www.ytj.fi/en/index/businessid.html", diff --git a/src/fr/nif.ts b/src/fr/nif.ts index 883f5e6..2759a4c 100644 --- a/src/fr/nif.ts +++ b/src/fr/nif.ts @@ -8,7 +8,10 @@ * @see https://www.impots.gouv.fr/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -69,7 +72,7 @@ const generate = (): string => { }; /** French Tax Identification Number. */ -const nif: Validator = { +const nif: CountryValidator<"FR"> = { name: "French Tax ID", localName: "Numéro d'Identification Fiscale", abbreviation: "NIF", @@ -79,6 +82,7 @@ const nif: Validator = { "numéro d'identification fiscale", ] as const, candidatePattern: "\\d{13}", + scope: "country", country: "FR", entityType: "person", sourceUrl: "https://www.impots.gouv.fr/", diff --git a/src/fr/nir.ts b/src/fr/nir.ts index 17181d1..ddc71fd 100644 --- a/src/fr/nir.ts +++ b/src/fr/nir.ts @@ -15,7 +15,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { clean } from "#util/clean"; @@ -165,7 +165,7 @@ const generate = (): string => { }; /** French Social Security Number. */ -const nir: Validator = { +const nir: CountryValidator<"FR", ParsedPersonId> = { name: "French Social Security Number", localName: "Numero d'Inscription au Repertoire", abbreviation: "NIR", @@ -177,6 +177,7 @@ const nir: Validator = { ] as const, candidatePattern: "[12]\\s?\\d{2}\\s?\\d{2}\\s?\\d{2}\\s?\\d{3}\\s?\\d{3}\\s?\\d{2}", + scope: "country", country: "FR", entityType: "person", description: diff --git a/src/fr/siren.ts b/src/fr/siren.ts index d10517c..c0206a2 100644 --- a/src/fr/siren.ts +++ b/src/fr/siren.ts @@ -8,7 +8,10 @@ * @see https://www.insee.fr/fr/information/2549588 */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { luhnValidate, @@ -58,13 +61,14 @@ const generate = (): string => { }; /** French Company Identification Number. */ -const siren: Validator = { +const siren: CountryValidator<"FR"> = { name: "French Company ID", localName: "Système d'Identification du Répertoire des Entreprises", abbreviation: "SIREN", aliases: ["SIREN", "numéro SIREN"] as const, candidatePattern: "\\d{3}\\s?\\d{3}\\s?\\d{3}", + scope: "country", country: "FR", entityType: "company", sourceUrl: "https://www.insee.fr/fr/information/2549588", diff --git a/src/fr/siret.ts b/src/fr/siret.ts index 762aba0..da77074 100644 --- a/src/fr/siret.ts +++ b/src/fr/siret.ts @@ -9,7 +9,10 @@ * @see https://www.insee.fr/fr/information/2549588 */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { luhnValidate, @@ -101,13 +104,14 @@ const generate = (): string => { }; /** French Establishment Identification Number. */ -const siret: Validator = { +const siret: CountryValidator<"FR"> = { name: "French Establishment ID", localName: "Système d'Identification du Répertoire des Établissements", abbreviation: "SIRET", aliases: ["SIRET", "numéro SIRET"] as const, candidatePattern: "\\d{3}\\s?\\d{3}\\s?\\d{3}\\s?\\d{5}", + scope: "country", country: "FR", entityType: "company", sourceUrl: "https://www.insee.fr/fr/information/2549588", diff --git a/src/fr/tva.ts b/src/fr/tva.ts index 7c96d48..15764b0 100644 --- a/src/fr/tva.ts +++ b/src/fr/tva.ts @@ -10,7 +10,10 @@ * @see https://www.economie.gouv.fr/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { luhnValidate, @@ -122,7 +125,7 @@ const generate = (): string => { }; /** French VAT Number. */ -const tva: Validator = { +const tva: CountryValidator<"FR"> = { name: "French VAT Number", localName: "Numéro de TVA intracommunautaire", abbreviation: "TVA", @@ -132,6 +135,7 @@ const tva: Validator = { "FR VAT", ] as const, candidatePattern: "FR[A-Z0-9]{2}\\d{9}", + scope: "country", country: "FR", entityType: "company", sourceUrl: "https://www.economie.gouv.fr/", diff --git a/src/gb/nino.ts b/src/gb/nino.ts index 77e8c7f..e86f4ff 100644 --- a/src/gb/nino.ts +++ b/src/gb/nino.ts @@ -28,7 +28,10 @@ const generate = (): string => { * @see https://www.gov.uk/hmrc-internal-manuals/national-insurance-manual/nim39110 */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomChar, randomDigits } from "#util/generate"; @@ -124,7 +127,7 @@ const format = (value: string): string => { }; /** UK National Insurance Number. */ -const nino: Validator = { +const nino: CountryValidator<"GB"> = { name: "UK National Insurance Number", localName: "National Insurance Number", abbreviation: "NINO", @@ -134,6 +137,7 @@ const nino: Validator = { "NI number", ] as const, candidatePattern: "[A-Z]{2}\\d{6}[A-Z]", + scope: "country", country: "GB", entityType: "person", description: diff --git a/src/gb/sedol.ts b/src/gb/sedol.ts index 31c8d9e..857696e 100644 --- a/src/gb/sedol.ts +++ b/src/gb/sedol.ts @@ -10,7 +10,10 @@ * @see https://en.wikipedia.org/wiki/SEDOL */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomChar } from "#util/generate"; @@ -109,7 +112,7 @@ const generate = (): string => { }; /** Stock Exchange Daily Official List number. */ -const sedol: Validator = { +const sedol: CountryValidator<"GB"> = { name: "Stock Exchange Daily Official List number", localName: "Stock Exchange Daily Official List number", abbreviation: "SEDOL", @@ -118,6 +121,7 @@ const sedol: Validator = { "Stock Exchange Daily Official List", ] as const, candidatePattern: "[B-DF-HJ-NP-TV-Z0-9]{6}\\d", + scope: "country", country: "GB", entityType: "any", sourceUrl: "https://en.wikipedia.org/wiki/SEDOL", diff --git a/src/gb/utr.ts b/src/gb/utr.ts index 6691c7a..b4ffc44 100644 --- a/src/gb/utr.ts +++ b/src/gb/utr.ts @@ -8,7 +8,10 @@ * @see https://www.gov.uk/find-utr-number */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -61,12 +64,13 @@ const generate = (): string => { }; /** UK Unique Taxpayer Reference. */ -const utr: Validator = { +const utr: CountryValidator<"GB"> = { name: "UK Unique Taxpayer Reference", localName: "Unique Taxpayer Reference", abbreviation: "UTR", aliases: ["Unique Taxpayer Reference", "UTR"] as const, candidatePattern: "\\d{10}", + scope: "country", country: "GB", entityType: "any", sourceUrl: "https://www.gov.uk/find-utr-number", diff --git a/src/gb/vat.ts b/src/gb/vat.ts index 4eb3d5a..79d0f78 100644 --- a/src/gb/vat.ts +++ b/src/gb/vat.ts @@ -9,7 +9,10 @@ * @see https://www.gov.uk/vat-registration */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -135,7 +138,7 @@ const generate = (): string => { }; /** UK VAT Registration Number. */ -const vat: Validator = { +const vat: CountryValidator<"GB"> = { name: "UK VAT Number", localName: "VAT Registration Number", abbreviation: "VAT", @@ -144,6 +147,7 @@ const vat: Validator = { "VAT number", ] as const, candidatePattern: "GB\\d{9,12}", + scope: "country", country: "GB", entityType: "company", sourceUrl: "https://www.gov.uk/vat-registration", diff --git a/src/ge/pin.ts b/src/ge/pin.ts index 0120195..2a1438d 100644 --- a/src/ge/pin.ts +++ b/src/ge/pin.ts @@ -14,7 +14,10 @@ const generate = (): string => randomDigits(11); * @see https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Georgia-TIN.pdf */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -47,12 +50,13 @@ const validate = (value: string): ValidateResult => { const format = (value: string): string => compact(value); /** Georgian Personal Identification Number. */ -const pin: Validator = { +const pin: CountryValidator<"GE"> = { name: "Georgian Personal ID", localName: "პირადი ნომერი", abbreviation: "PIN", aliases: ["პირადი ნომერი", "PIN"] as const, candidatePattern: "\\d{11}", + scope: "country", country: "GE", entityType: "any", lengths: [9, 11] as const, diff --git a/src/gh/tin.ts b/src/gh/tin.ts index d55829e..cd6ff05 100644 --- a/src/gh/tin.ts +++ b/src/gh/tin.ts @@ -14,7 +14,10 @@ * @see https://gra.gov.gh/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomPick } from "#util/generate"; @@ -79,12 +82,13 @@ const generate = (): string => { }; /** Ghanaian Tax Identification Number. */ -const tin: Validator = { +const tin: CountryValidator<"GH"> = { name: "Ghanaian Tax Identification Number", localName: "Tax Identification Number", abbreviation: "TIN", aliases: ["TIN", "Tax Identification Number"] as const, candidatePattern: "[A-Z]\\d{9,10}", + scope: "country", country: "GH", entityType: "any", compact, diff --git a/src/gr/amka.ts b/src/gr/amka.ts index a54a20e..a4a8a35 100644 --- a/src/gr/amka.ts +++ b/src/gr/amka.ts @@ -8,7 +8,10 @@ * @see https://www.amka.gr/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { luhnValidate, @@ -80,7 +83,7 @@ const generate = (): string => { }; /** Greek Social Security Number. */ -const amka: Validator = { +const amka: CountryValidator<"GR"> = { name: "Greek Social Security Number", localName: "Αριθμός Μητρώου Κοινωνικής Ασφάλισης", abbreviation: "ΑΜΚΑ", @@ -90,6 +93,7 @@ const amka: Validator = { "AMKA", ] as const, candidatePattern: "\\d{11}", + scope: "country", country: "GR", entityType: "person", sourceUrl: "https://www.amka.gr/", diff --git a/src/gr/vat.ts b/src/gr/vat.ts index d4c5894..b69fbb6 100644 --- a/src/gr/vat.ts +++ b/src/gr/vat.ts @@ -9,7 +9,10 @@ * @see https://www.aade.gr/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -72,7 +75,7 @@ const generate = (): string => { }; /** Greek VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"GR"> = { name: "Greek VAT Number", localName: "Αριθμός Φορολογικού Μητρώου", abbreviation: "ΑΦΜ", @@ -82,6 +85,7 @@ const vat: Validator = { "AFM", ] as const, candidatePattern: "EL\\d{9}", + scope: "country", country: "GR", entityType: "any", sourceUrl: "https://www.aade.gr/", diff --git a/src/gt/nit.ts b/src/gt/nit.ts index a147f69..fb8cca3 100644 --- a/src/gt/nit.ts +++ b/src/gt/nit.ts @@ -11,7 +11,10 @@ * @see https://portal.sat.gob.gt/portal/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -97,12 +100,13 @@ const generate = (): string => { }; /** Guatemala tax identification number. */ -const nit: Validator = { +const nit: CountryValidator<"GT"> = { name: "Tax Identification Number", localName: "Número de Identificación Tributaria", abbreviation: "NIT", aliases: ["NIT"] as const, candidatePattern: "\\d{7,8}-?\\d", + scope: "country", country: "GT", entityType: "any", description: "Tax identifier issued by Guatemala's SAT", diff --git a/src/hk/hkid.ts b/src/hk/hkid.ts index ebd55c4..89d61ad 100644 --- a/src/hk/hkid.ts +++ b/src/hk/hkid.ts @@ -9,7 +9,10 @@ * @see https://en.wikipedia.org/wiki/Hong_Kong_identity_card */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -106,12 +109,13 @@ const generate = (): string => { }; /** Hong Kong Identity Card number. */ -const hkid: Validator = { +const hkid: CountryValidator<"HK"> = { name: "Hong Kong Identity Card Number", localName: "Hong Kong Identity Card Number", abbreviation: "HKID", aliases: ["HKID", "香港身份證"] as const, candidatePattern: "[A-Z]{1,2}\\d{6}[\\dA]", + scope: "country", country: "HK", entityType: "person", lengths: [8, 9], diff --git a/src/hr/vat.ts b/src/hr/vat.ts index 833369c..bead121 100644 --- a/src/hr/vat.ts +++ b/src/hr/vat.ts @@ -7,7 +7,10 @@ * @see https://www.porezna-uprava.hr/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { mod1110validate, @@ -59,12 +62,13 @@ const generate = (): string => { }; /** Croatian VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"HR"> = { name: "Croatian VAT Number", localName: "Osobni identifikacijski broj", abbreviation: "OIB", aliases: ["OIB", "osobni identifikacijski broj"] as const, candidatePattern: "HR\\d{11}", + scope: "country", country: "HR", entityType: "any", sourceUrl: "https://www.porezna-uprava.hr/", diff --git a/src/hu/vat.ts b/src/hu/vat.ts index 963d403..95641e1 100644 --- a/src/hu/vat.ts +++ b/src/hu/vat.ts @@ -8,7 +8,10 @@ * @see https://www.oecd.org/content/dam/oecd/en/topics/policy-issue-focus/aeoi/hungary-tin.pdf */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -62,12 +65,13 @@ const generate = (): string => { }; /** Hungarian VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"HU"> = { name: "Hungarian VAT Number", localName: "Adószám", abbreviation: "ANUM", aliases: ["adószám", "adóazonosító jel"] as const, candidatePattern: "\\d{8}-\\d-\\d{2}", + scope: "country", country: "HU", entityType: "company", sourceUrl: "https://nav.gov.hu/", diff --git a/src/iban.ts b/src/iban.ts index ba83925..559558e 100644 --- a/src/iban.ts +++ b/src/iban.ts @@ -6,7 +6,10 @@ * characters. Validated using ISO 7064 Mod 97-10. */ -import type { ValidateResult, Validator } from "./types"; +import type { + ValidateResult, + GlobalValidator, +} from "./types"; import { mod97 } from "#checksums/mod97"; import { clean } from "#util/clean"; @@ -314,7 +317,8 @@ const generate = (): string => { }; /** International Bank Account Number. */ -const iban: Validator = { +const iban: GlobalValidator = { + scope: "global", name: "IBAN", localName: "IBAN", abbreviation: "IBAN", diff --git a/src/id/npwp.ts b/src/id/npwp.ts index ef8426d..8a27f05 100644 --- a/src/id/npwp.ts +++ b/src/id/npwp.ts @@ -10,7 +10,10 @@ * @see https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Indonesia-TIN.pdf */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { luhnValidate, @@ -160,13 +163,14 @@ const generate = (): string => { }; /** Indonesian Taxpayer Identification Number. */ -const npwp: Validator = { +const npwp: CountryValidator<"ID"> = { name: "Indonesian Taxpayer Identification Number", localName: "Nomor Pokok Wajib Pajak", abbreviation: "NPWP", aliases: ["NPWP", "Nomor Pokok Wajib Pajak"] as const, candidatePattern: "\\d{2}\\.?\\d{3}\\.?\\d{3}\\.?\\d-?\\d{3}\\.?\\d{3}", + scope: "country", country: "ID", entityType: "any", lengths: [15, 16], diff --git a/src/ie/pps.ts b/src/ie/pps.ts index fbc466e..637fe60 100644 --- a/src/ie/pps.ts +++ b/src/ie/pps.ts @@ -9,7 +9,10 @@ * @see https://www.gov.ie/en/service/12e6de-get-a-personal-public-service-pps-number/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -84,12 +87,13 @@ const generate = (): string => { }; /** Irish Personal Public Service Number. */ -const pps: Validator = { +const pps: CountryValidator<"IE"> = { name: "Irish Personal ID", localName: "Personal Public Service Number", abbreviation: "PPS", aliases: ["PPS number", "PPSN", "RSI number"] as const, candidatePattern: "\\d{7}[A-Z]{1,2}", + scope: "country", country: "IE", entityType: "person", sourceUrl: diff --git a/src/ie/vat.ts b/src/ie/vat.ts index 995ee6e..f262085 100644 --- a/src/ie/vat.ts +++ b/src/ie/vat.ts @@ -8,7 +8,10 @@ * @see https://www.revenue.ie/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -118,12 +121,13 @@ const generate = (): string => { }; /** Irish VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"IE"> = { name: "Irish VAT Number", localName: "Value Added Tax Number", abbreviation: "VAT", aliases: ["VAT number IE"] as const, candidatePattern: "IE\\d[A-Z+*]\\d{5}[A-Z]", + scope: "country", country: "IE", entityType: "any", sourceUrl: "https://www.revenue.ie/", diff --git a/src/il/idnr.ts b/src/il/idnr.ts index 64456be..120e230 100644 --- a/src/il/idnr.ts +++ b/src/il/idnr.ts @@ -7,7 +7,10 @@ * @see https://en.wikipedia.org/wiki/Israeli_identity_card */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { luhnValidate, @@ -58,7 +61,7 @@ const generate = (): string => { }; /** Israeli Identity Number (Mispar Zehut). */ -const idnr: Validator = { +const idnr: CountryValidator<"IL"> = { name: "Israeli Identity Number", localName: "מספר זהות", abbreviation: "ת.ז.", @@ -68,6 +71,7 @@ const idnr: Validator = { "ID number", ] as const, candidatePattern: "\\d{9}", + scope: "country", country: "IL", entityType: "person", compact, diff --git a/src/in/aadhaar.ts b/src/in/aadhaar.ts index 177390b..aa1e2fa 100644 --- a/src/in/aadhaar.ts +++ b/src/in/aadhaar.ts @@ -10,7 +10,10 @@ * @see https://uidai.gov.in/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { verhoeffValidate, @@ -73,12 +76,13 @@ const generate = (): string => { }; /** Indian Unique Identity Number. */ -const aadhaar: Validator = { +const aadhaar: CountryValidator<"IN"> = { name: "Indian Unique Identity Number", localName: "Aadhaar", abbreviation: "Aadhaar", aliases: ["Aadhaar", "आधार"] as const, candidatePattern: "\\d{4}\\s?\\d{4}\\s?\\d{4}", + scope: "country", country: "IN", entityType: "person", lengths: [12], diff --git a/src/in/gstin.ts b/src/in/gstin.ts index 94bc2d4..17f7123 100644 --- a/src/in/gstin.ts +++ b/src/in/gstin.ts @@ -9,7 +9,10 @@ * @see https://en.wikipedia.org/wiki/Goods_and_Services_Tax_Identification_Number */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -146,13 +149,14 @@ const generate = (): string => { }; /** Indian Goods and Services Tax ID. */ -const gstin: Validator = { +const gstin: CountryValidator<"IN"> = { name: "Indian Goods and Services Tax ID", localName: "Goods and Services Tax Identification Number", abbreviation: "GSTIN", aliases: ["GSTIN", "GST number"] as const, candidatePattern: "\\d{2}[A-Z]{5}\\d{4}[A-Z][A-Z\\d][Z][A-Z\\d]", + scope: "country", country: "IN", entityType: "company", lengths: [15], diff --git a/src/in/pan.ts b/src/in/pan.ts index 566377e..fcb4d4b 100644 --- a/src/in/pan.ts +++ b/src/in/pan.ts @@ -25,7 +25,10 @@ const generate = (): string => { * @see https://en.wikipedia.org/wiki/Permanent_account_number */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { @@ -70,12 +73,13 @@ const validate = (value: string): ValidateResult => { const format = (value: string): string => compact(value); /** Indian Permanent Account Number. */ -const pan: Validator = { +const pan: CountryValidator<"IN"> = { name: "Indian Permanent Account Number", localName: "Permanent Account Number", abbreviation: "PAN", aliases: ["PAN", "Permanent Account Number"] as const, candidatePattern: "[A-Z]{5}\\d{4}[A-Z]", + scope: "country", country: "IN", entityType: "any", lengths: [10], diff --git a/src/index.ts b/src/index.ts index 174a486..ecea666 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,8 @@ export type { + CountryValidator, CountryCode, ErrorCode, + GlobalValidator, ParsedBirthDate, ParsedIdentifier, ParsedPersonId, @@ -8,6 +10,7 @@ export type { StdnumError, ValidateResult, Validator, + ValidatorScope, } from "./types"; export { default as bic } from "./bic"; export { diff --git a/src/iq/nid.ts b/src/iq/nid.ts index 551cd41..35669b4 100644 --- a/src/iq/nid.ts +++ b/src/iq/nid.ts @@ -16,7 +16,10 @@ const generate = (): string => randomDigits(12); * @see https://mofa.gov.iq/the-civil-status-id/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { normalizeArabicDigits } from "#util/arabic"; import { clean } from "#util/clean"; @@ -48,12 +51,13 @@ const validate = (value: string): ValidateResult => { const format = (value: string): string => compact(value); /** Iraqi National Identification Number. */ -const nid: Validator = { +const nid: CountryValidator<"IQ"> = { name: "Iraqi National ID", localName: "البطاقة الوطنية الموحدة", abbreviation: "NID", aliases: ["NID", "البطاقة الوطنية الموحدة"] as const, candidatePattern: "\\d{12}", + scope: "country", country: "IQ", entityType: "person", sourceUrl: "https://mofa.gov.iq/the-civil-status-id/", diff --git a/src/ir/nid.ts b/src/ir/nid.ts index 5fd2a0c..a1d8953 100644 --- a/src/ir/nid.ts +++ b/src/ir/nid.ts @@ -22,7 +22,10 @@ * @see https://persian-tools.js.org/functions/verifyIranianNationalId.html */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { normalizeArabicDigits } from "#util/arabic"; import { clean } from "#util/clean"; @@ -97,12 +100,13 @@ const generate = (): string => { }; /** Iranian National Identification Number. */ -const nid: Validator = { +const nid: CountryValidator<"IR"> = { name: "Iranian National ID", localName: "کد ملی", abbreviation: "NID", aliases: ["NID", "کد ملی", "national code"] as const, candidatePattern: "\\d{10}", + scope: "country", country: "IR", entityType: "person", sourceUrl: "https://www.sabteahval.ir/", diff --git a/src/is/kennitala.ts b/src/is/kennitala.ts index 84324e0..6b55950 100644 --- a/src/is/kennitala.ts +++ b/src/is/kennitala.ts @@ -11,7 +11,10 @@ * @see https://www.skra.is/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { isValidDate } from "#util/date"; @@ -105,12 +108,13 @@ const generate = (): string => { }; /** Icelandic Identification Number. */ -const kennitala: Validator = { +const kennitala: CountryValidator<"IS"> = { name: "Icelandic ID Number", localName: "Kennitala", abbreviation: "kt.", aliases: ["kennitala", "kt."] as const, candidatePattern: "\\d{6}-?\\d{4}", + scope: "country", country: "IS", entityType: "any", sourceUrl: "https://www.skra.is/", diff --git a/src/is/vsk.ts b/src/is/vsk.ts index 6c64e4f..bdfa0cd 100644 --- a/src/is/vsk.ts +++ b/src/is/vsk.ts @@ -12,7 +12,10 @@ const generate = (): string => { * @see https://www.rsk.is/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -43,12 +46,13 @@ const validate = (value: string): ValidateResult => { const format = (value: string): string => compact(value); /** Icelandic VAT Number. */ -const vsk: Validator = { +const vsk: CountryValidator<"IS"> = { name: "Icelandic VAT Number", localName: "Virðisaukaskattur", abbreviation: "VSK", aliases: ["VSK-númer", "virðisaukaskattur"] as const, candidatePattern: "IS\\d{5,6}", + scope: "country", country: "IS", entityType: "company", sourceUrl: "https://www.rsk.is/", diff --git a/src/isin.ts b/src/isin.ts index ee8d6c2..e3779db 100644 --- a/src/isin.ts +++ b/src/isin.ts @@ -10,7 +10,10 @@ * @see https://www.isin.org/ */ -import type { ValidateResult, Validator } from "./types"; +import type { + ValidateResult, + GlobalValidator, +} from "./types"; import { luhnChecksum } from "#checksums/luhn"; import { clean } from "#util/clean"; @@ -97,7 +100,8 @@ const generate = (): string => { }; /** International Securities Identification Number. */ -const isin: Validator = { +const isin: GlobalValidator = { + scope: "global", name: "International Securities Identification Number", localName: "International Securities Identification Number", diff --git a/src/it/codicefiscale.ts b/src/it/codicefiscale.ts index 60b464c..f357f7f 100644 --- a/src/it/codicefiscale.ts +++ b/src/it/codicefiscale.ts @@ -23,7 +23,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { validate as validateIva } from "./iva"; @@ -297,7 +297,10 @@ const generate = (): string => { }; /** Italian Tax Code. */ -const codiceFiscale: Validator = { +const codiceFiscale: CountryValidator< + "IT", + ParsedPersonId +> = { name: "Italian Tax Code", localName: "Codice Fiscale", abbreviation: "CF", @@ -310,6 +313,7 @@ const codiceFiscale: Validator = { ] as const, candidatePattern: "[A-Z]{6}\\d{2}[A-Z]\\d{2}[A-Z]\\d{3}[A-Z]", + scope: "country", country: "IT", entityType: "person", description: diff --git a/src/it/iva.ts b/src/it/iva.ts index 362ab08..bcd0ab7 100644 --- a/src/it/iva.ts +++ b/src/it/iva.ts @@ -7,7 +7,10 @@ * @see https://www.agenziaentrate.gov.it/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { luhnValidate, @@ -90,7 +93,7 @@ const generate = (): string => { }; /** Italian VAT Number. */ -const iva: Validator = { +const iva: CountryValidator<"IT"> = { name: "Italian VAT Number", localName: "Partita IVA", abbreviation: "P.IVA", @@ -101,6 +104,7 @@ const iva: Validator = { "VAT IT", ] as const, candidatePattern: "IT\\d{11}", + scope: "country", country: "IT", entityType: "company", sourceUrl: "https://www.agenziaentrate.gov.it/", diff --git a/src/jp/cn.ts b/src/jp/cn.ts index 5dc81d3..f9baacf 100644 --- a/src/jp/cn.ts +++ b/src/jp/cn.ts @@ -8,7 +8,10 @@ * @see https://en.wikipedia.org/wiki/Corporate_Number_(Japan) */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -67,12 +70,13 @@ const generate = (): string => { }; /** Japanese Corporate Number. */ -const cn: Validator = { +const cn: CountryValidator<"JP"> = { name: "Japanese Corporate Number", localName: "法人番号", abbreviation: "CN", aliases: ["法人番号", "Corporate Number"] as const, candidatePattern: "\\d{13}", + scope: "country", country: "JP", entityType: "company", description: diff --git a/src/jp/mynumber.ts b/src/jp/mynumber.ts index 47e1bda..3774f96 100644 --- a/src/jp/mynumber.ts +++ b/src/jp/mynumber.ts @@ -9,7 +9,10 @@ * @see https://en.wikipedia.org/wiki/Individual_Number */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -74,7 +77,7 @@ const generate = (): string => { }; /** Japanese Individual Number (My Number). */ -const mynumber: Validator = { +const mynumber: CountryValidator<"JP"> = { name: "Japanese Individual Number", localName: "マイナンバー", abbreviation: "My Number", @@ -84,6 +87,7 @@ const mynumber: Validator = { "個人番号", ] as const, candidatePattern: "\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}", + scope: "country", country: "JP", entityType: "person", description: diff --git a/src/kr/brn.ts b/src/kr/brn.ts index 7c2d018..cce1818 100644 --- a/src/kr/brn.ts +++ b/src/kr/brn.ts @@ -23,7 +23,10 @@ const generate = (): string => { * @see https://en.wikipedia.org/wiki/Business_registration_number_(South_Korea) */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -77,12 +80,13 @@ const format = (value: string): string => { }; /** Korean Business Registration Number. */ -const brn: Validator = { +const brn: CountryValidator<"KR"> = { name: "Korean Business Registration Number", localName: "사업자등록번호", abbreviation: "BRN", aliases: ["사업자등록번호", "BRN"] as const, candidatePattern: "\\d{3}-?\\d{2}-?\\d{5}", + scope: "country", country: "KR", entityType: "company", description: diff --git a/src/kr/rrn.ts b/src/kr/rrn.ts index 79340b0..3120f97 100644 --- a/src/kr/rrn.ts +++ b/src/kr/rrn.ts @@ -12,7 +12,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { clean } from "#util/clean"; @@ -157,7 +157,7 @@ const generate = (): string => { }; /** Korean Resident Registration Number. */ -const rrn: Validator = { +const rrn: CountryValidator<"KR", ParsedPersonId> = { name: "Korean Resident Registration Number", localName: "주민등록번호", abbreviation: "RRN", @@ -167,6 +167,7 @@ const rrn: Validator = { "Resident Registration Number", ] as const, candidatePattern: "\\d{6}[\\s-]?\\d{7}", + scope: "country", country: "KR", entityType: "person", description: diff --git a/src/kw/civil.ts b/src/kw/civil.ts index 7762ab5..080ac29 100644 --- a/src/kw/civil.ts +++ b/src/kw/civil.ts @@ -15,7 +15,7 @@ import type { ParsedBirthDate, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { clean } from "#util/clean"; @@ -135,12 +135,13 @@ const generate = (): string => { }; /** Kuwait Civil Number (الرقم المدني). */ -const civil: Validator = { +const civil: CountryValidator<"KW", ParsedBirthDate> = { name: "Civil Number", localName: "الرقم المدني", abbreviation: "Civil ID", aliases: ["Civil ID", "الرقم المدني"] as const, candidatePattern: "\\d{12}", + scope: "country", country: "KW", entityType: "person", lengths: [12] as const, diff --git a/src/kz/iin.ts b/src/kz/iin.ts index 3dcfcdd..e1cae85 100644 --- a/src/kz/iin.ts +++ b/src/kz/iin.ts @@ -17,7 +17,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { weightedSum } from "#checksums/weighted-sum"; @@ -154,7 +154,7 @@ const generate = (): string => { * * Examples sourced from identique/idnumbers test suite. */ -const iin: Validator = { +const iin: CountryValidator<"KZ", ParsedPersonId> = { name: "Kazakhstan Individual ID", localName: "Жеке сәйкестендіру нөмірі", abbreviation: "IIN", @@ -164,6 +164,7 @@ const iin: Validator = { "индивидуальный идентификационный номер", ] as const, candidatePattern: "\\d{12}", + scope: "country", country: "KZ", entityType: "person", lengths: [12] as const, diff --git a/src/lei.ts b/src/lei.ts index 36d9c37..fb8a221 100644 --- a/src/lei.ts +++ b/src/lei.ts @@ -9,7 +9,10 @@ * @see https://www.gleif.org/ */ -import type { ValidateResult, Validator } from "./types"; +import type { + ValidateResult, + GlobalValidator, +} from "./types"; import { mod97 } from "#checksums/mod97"; import { clean } from "#util/clean"; @@ -79,7 +82,8 @@ const generate = (): string => { }; /** Legal Entity Identifier. */ -const lei: Validator = { +const lei: GlobalValidator = { + scope: "global", name: "Legal Entity Identifier", localName: "Legal Entity Identifier", abbreviation: "LEI", diff --git a/src/li/peid.ts b/src/li/peid.ts index 872004e..8057556 100644 --- a/src/li/peid.ts +++ b/src/li/peid.ts @@ -15,7 +15,10 @@ const generate = (): string => { * @see https://www.oera.li/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -45,12 +48,13 @@ const validate = (value: string): ValidateResult => { const format = (value: string): string => compact(value); /** Liechtenstein Person Identification Number. */ -const peid: Validator = { +const peid: CountryValidator<"LI"> = { name: "Liechtenstein Person Identification Number", localName: "Personenidentifikationsnummer", abbreviation: "PEID", aliases: ["PEID", "Personenidentifikation"] as const, candidatePattern: "\\d{6}", + scope: "country", country: "LI", entityType: "any", lengths: [4, 5, 6, 7, 8, 9, 10, 11, 12] as const, diff --git a/src/lk/nic.ts b/src/lk/nic.ts index 2eca404..6a381f9 100644 --- a/src/lk/nic.ts +++ b/src/lk/nic.ts @@ -15,7 +15,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { clean } from "#util/clean"; @@ -205,12 +205,13 @@ const generate = (): string => { }; /** Sri Lankan National Identity Card. */ -const nic: Validator = { +const nic: CountryValidator<"LK", ParsedPersonId> = { name: "National Identity Card", localName: "ජාතික හැඳුනුම්පත", abbreviation: "NIC", aliases: ["NIC", "ජාතික හැඳුනුම්පත"] as const, candidatePattern: "\\d{9}[VXvx]|\\d{12}", + scope: "country", country: "LK", entityType: "person", description: diff --git a/src/lt/asmens.ts b/src/lt/asmens.ts index 5c7852d..5f9cf8a 100644 --- a/src/lt/asmens.ts +++ b/src/lt/asmens.ts @@ -11,7 +11,10 @@ */ import { twoPassCheck } from "../ee/ik"; -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { isValidDate } from "#util/date"; @@ -100,12 +103,13 @@ const generate = (): string => { }; /** Lithuanian Personal Code. */ -const asmens: Validator = { +const asmens: CountryValidator<"LT"> = { name: "Lithuanian Personal ID", localName: "Asmens kodas", abbreviation: "AK", aliases: ["asmens kodas", "AK"] as const, candidatePattern: "[3-6]\\d{10}", + scope: "country", country: "LT", entityType: "person", sourceUrl: "https://www.registrucentras.lt/", diff --git a/src/lt/vat.ts b/src/lt/vat.ts index ebc46ad..282e7e4 100644 --- a/src/lt/vat.ts +++ b/src/lt/vat.ts @@ -9,7 +9,10 @@ * @see https://www.vmi.lt/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -89,12 +92,13 @@ const generate = (): string => { }; /** Lithuanian VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"LT"> = { name: "Lithuanian VAT Number", localName: "PVM mokėtojo kodas", abbreviation: "PVM kodas", aliases: ["PVM mokėtojo kodas", "PVM"] as const, candidatePattern: "LT\\d{9,12}", + scope: "country", country: "LT", entityType: "any", sourceUrl: "https://www.vmi.lt/", diff --git a/src/lu/vat.ts b/src/lu/vat.ts index cc0d665..2269383 100644 --- a/src/lu/vat.ts +++ b/src/lu/vat.ts @@ -7,7 +7,10 @@ * @see https://www.oecd.org/content/dam/oecd/en/topics/policy-issue-focus/aeoi/luxembourg-tin.pdf */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -60,12 +63,13 @@ const generate = (): string => { }; /** Luxembourg VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"LU"> = { name: "Luxembourg VAT Number", localName: "Numéro de TVA", abbreviation: "TVA", aliases: ["TVA", "numéro d'identification TVA"] as const, candidatePattern: "LU\\d{8}", + scope: "country", country: "LU", entityType: "company", sourceUrl: "https://pfi.public.lu/", diff --git a/src/luhn.ts b/src/luhn.ts index 5b5a12d..eed8590 100644 --- a/src/luhn.ts +++ b/src/luhn.ts @@ -7,7 +7,10 @@ * (13-19 digits), use `creditcard` instead. */ -import type { ValidateResult, Validator } from "./types"; +import type { + ValidateResult, + GlobalValidator, +} from "./types"; import { luhnChecksum, @@ -56,7 +59,8 @@ const generate = (length = 16): string => { }; /** Generic Luhn Validator. */ -const luhn: Validator = { +const luhn: GlobalValidator = { + scope: "global", name: "Luhn", localName: "Luhn", abbreviation: "Luhn", diff --git a/src/lv/vat.ts b/src/lv/vat.ts index f3a1b8a..c59df5a 100644 --- a/src/lv/vat.ts +++ b/src/lv/vat.ts @@ -26,7 +26,10 @@ * @see https://www.pmlp.gov.lv/en/change-personal-identity-number */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -144,12 +147,13 @@ const generate = (): string => { }; /** Latvian VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"LV"> = { name: "Latvian VAT Number", localName: "PVN reģistrācijas numurs", abbreviation: "PVN", aliases: ["PVN reģistrācijas numurs", "PVN"] as const, candidatePattern: "LV\\d{11}", + scope: "country", country: "LV", entityType: "any", sourceUrl: diff --git a/src/ma/ice.ts b/src/ma/ice.ts index c0b665d..b0208c3 100644 --- a/src/ma/ice.ts +++ b/src/ma/ice.ts @@ -9,7 +9,10 @@ * @see https://www.ice.gov.ma/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { mod97 } from "#checksums/mod97"; import { clean } from "#util/clean"; @@ -54,7 +57,7 @@ const generate = (): string => { }; /** Moroccan Company Identification Number. */ -const ice: Validator = { +const ice: CountryValidator<"MA"> = { name: "Moroccan Company Identification Number", localName: "Identifiant Commun de l'Entreprise", abbreviation: "ICE", @@ -63,6 +66,7 @@ const ice: Validator = { "Identifiant Commun de l'Entreprise", ] as const, candidatePattern: "\\d{15}", + scope: "country", country: "MA", entityType: "company", compact, diff --git a/src/mc/tva.ts b/src/mc/tva.ts index 7491d4e..0becaa4 100644 --- a/src/mc/tva.ts +++ b/src/mc/tva.ts @@ -14,7 +14,10 @@ import { compact as frCompact, validate as frValidate, } from "../fr/tva"; -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { randomDigits } from "#util/generate"; import { err } from "#util/result"; @@ -54,12 +57,13 @@ const generate = (): string => { }; /** Monacan VAT Number. */ -const tva: Validator = { +const tva: CountryValidator<"MC"> = { name: "Monacan VAT Number", localName: "Numéro de TVA", abbreviation: "TVA", aliases: ["numéro de TVA", "TVA"] as const, candidatePattern: "FR\\d{11}", + scope: "country", country: "MC", entityType: "company", sourceUrl: "https://www.economie.gouv.fr/", diff --git a/src/md/idno.ts b/src/md/idno.ts index d29ad46..992b192 100644 --- a/src/md/idno.ts +++ b/src/md/idno.ts @@ -9,7 +9,10 @@ * @see https://www.idno.md */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { err } from "#util/result"; @@ -65,12 +68,13 @@ const generate = (): string => { }; /** Moldavian Company Identification Number. */ -const idno: Validator = { +const idno: CountryValidator<"MD"> = { name: "Moldavian Company Identification Number", localName: "IDNO", abbreviation: "IDNO", aliases: ["IDNO", "cod de identificare"] as const, candidatePattern: "\\d{13}", + scope: "country", country: "MD", entityType: "company", lengths: [13] as const, diff --git a/src/me/pib.ts b/src/me/pib.ts index d6e8e9a..6328843 100644 --- a/src/me/pib.ts +++ b/src/me/pib.ts @@ -8,7 +8,10 @@ * @see https://www.tax.gov.me/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -58,12 +61,13 @@ const generate = (): string => { }; /** Montenegrin Tax Identification Number. */ -const pib: Validator = { +const pib: CountryValidator<"ME"> = { name: "Montenegrin Tax ID", localName: "Poreski identifikacioni broj", abbreviation: "PIB", aliases: ["PIB"] as const, candidatePattern: "\\d{8}", + scope: "country", country: "ME", entityType: "any", lengths: [8] as const, diff --git a/src/mk/edb.ts b/src/mk/edb.ts index 9599896..0cab044 100644 --- a/src/mk/edb.ts +++ b/src/mk/edb.ts @@ -9,7 +9,10 @@ * @see https://www.ujp.gov.mk/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -66,7 +69,7 @@ const generate = (): string => { }; /** North Macedonian Tax Identification Number. */ -const edb: Validator = { +const edb: CountryValidator<"MK"> = { name: "North Macedonian Tax ID", localName: "Edinstven danocen broj", abbreviation: "EDB", @@ -76,6 +79,7 @@ const edb: Validator = { "EDB", ] as const, candidatePattern: "MK\\d{13}", + scope: "country", country: "MK", entityType: "any", lengths: [13] as const, diff --git a/src/mt/vat.ts b/src/mt/vat.ts index c806ba9..3f6223d 100644 --- a/src/mt/vat.ts +++ b/src/mt/vat.ts @@ -8,7 +8,10 @@ * @see https://www.oecd.org/content/dam/oecd/en/topics/policy-issue-focus/aeoi/malta-tin.pdf */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -68,12 +71,13 @@ const generate = (): string => { }; /** Maltese VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"MT"> = { name: "Maltese VAT Number", localName: "VAT Registration Number", abbreviation: "VAT", aliases: ["VAT number MT"] as const, candidatePattern: "MT\\d{8}", + scope: "country", country: "MT", entityType: "company", sourceUrl: "https://cfr.gov.mt/", diff --git a/src/mu/brn.ts b/src/mu/brn.ts index b82d637..be86d6e 100644 --- a/src/mu/brn.ts +++ b/src/mu/brn.ts @@ -29,7 +29,10 @@ const generate = (): string => { * @see https://www.oecd.org/content/dam/oecd/en/topics/policy-issue-focus/aeoi/mauritius-tin.pdf */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -78,12 +81,13 @@ const validate = (value: string): ValidateResult => { const format = (value: string): string => compact(value); /** Mauritius Business Registration Number. */ -const brn: Validator = { +const brn: CountryValidator<"MU"> = { name: "Mauritius Business Registration Number", localName: "Business Registration Number", abbreviation: "BRN", aliases: ["BRN", "Business Registration Number"] as const, candidatePattern: "[A-Z]\\d{8}", + scope: "country", country: "MU", entityType: "any", compact, diff --git a/src/mx/clabe.ts b/src/mx/clabe.ts index def559b..17568f5 100644 --- a/src/mx/clabe.ts +++ b/src/mx/clabe.ts @@ -13,7 +13,10 @@ * @see https://en.wikipedia.org/wiki/CLABE */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -87,7 +90,7 @@ const generate = (): string => { * * Example sourced from Wikipedia CLABE article. */ -const clabe: Validator = { +const clabe: CountryValidator<"MX"> = { name: "Mexican Bank Account", localName: "Clave Bancaria Estandarizada", abbreviation: "CLABE", @@ -96,6 +99,7 @@ const clabe: Validator = { "Clave Bancaria Estandarizada", ] as const, candidatePattern: "\\d{18}", + scope: "country", country: "MX", entityType: "any", lengths: [18] as const, diff --git a/src/mx/curp.ts b/src/mx/curp.ts index 3437da8..0a5371c 100644 --- a/src/mx/curp.ts +++ b/src/mx/curp.ts @@ -17,7 +17,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { clean } from "#util/clean"; @@ -221,7 +221,7 @@ const generate = (): string => { * * Example sourced from python-stdnum test suite. */ -const curp: Validator = { +const curp: CountryValidator<"MX", ParsedPersonId> = { name: "Mexican Personal ID", localName: "Clave Única de Registro de Población", abbreviation: "CURP", @@ -230,6 +230,7 @@ const curp: Validator = { "Clave Única de Registro de Población", ] as const, candidatePattern: "[A-Z]{4}\\d{6}[HM][A-Z]{5}[A-Z\\d]\\d", + scope: "country", country: "MX", entityType: "person", lengths: [18] as const, diff --git a/src/mx/rfc.ts b/src/mx/rfc.ts index c98459e..ed902c6 100644 --- a/src/mx/rfc.ts +++ b/src/mx/rfc.ts @@ -16,7 +16,10 @@ * @see https://en.wikipedia.org/wiki/Tax_Identification_Number_(Mexico) */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { isValidDate } from "#util/date"; @@ -150,7 +153,7 @@ const generate = (): string => { * * Examples sourced from python-stdnum test suite. */ -const rfc: Validator = { +const rfc: CountryValidator<"MX"> = { name: "Mexican Tax ID", localName: "Registro Federal de Contribuyentes", abbreviation: "RFC", @@ -159,6 +162,7 @@ const rfc: Validator = { "Registro Federal de Contribuyentes", ] as const, candidatePattern: "[A-ZÑ&]{3,4}\\d{6}[A-Z\\d]{3}", + scope: "country", country: "MX", entityType: "any", lengths: [12, 13] as const, diff --git a/src/my/nric.ts b/src/my/nric.ts index 109ac28..9bad58f 100644 --- a/src/my/nric.ts +++ b/src/my/nric.ts @@ -15,7 +15,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { clean } from "#util/clean"; @@ -234,12 +234,13 @@ const generate = (): string => { }; /** Malaysian National Registration Identity Card. */ -const nric: Validator = { +const nric: CountryValidator<"MY", ParsedPersonId> = { name: "Malaysian National Registration Identity Card Number", localName: "Nombor Kad Pengenalan", abbreviation: "NRIC", aliases: ["NRIC", "MyKad", "kad pengenalan"] as const, candidatePattern: "\\d{6}-?\\d{2}-?\\d{4}", + scope: "country", country: "MY", entityType: "person", description: diff --git a/src/ng/nin.ts b/src/ng/nin.ts index 8fd8ed1..cda2373 100644 --- a/src/ng/nin.ts +++ b/src/ng/nin.ts @@ -13,7 +13,10 @@ const generate = (): string => randomDigits(11); * @see https://nimc.gov.ng/about-nin/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -46,7 +49,7 @@ const format = (value: string): string => { }; /** Nigerian National Identification Number. */ -const nin: Validator = { +const nin: CountryValidator<"NG"> = { name: "National Identification Number", localName: "National Identification Number", abbreviation: "NIN", @@ -55,6 +58,7 @@ const nin: Validator = { "National Identification Number", ] as const, candidatePattern: "\\d{11}", + scope: "country", country: "NG", entityType: "person", lengths: [11] as const, diff --git a/src/ni/ruc.ts b/src/ni/ruc.ts index 5fea425..ed94dc2 100644 --- a/src/ni/ruc.ts +++ b/src/ni/ruc.ts @@ -22,7 +22,10 @@ * @see https://www.dgi.gob.ni/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -154,12 +157,13 @@ const format = (value: string): string => { const generate = (): string => "J" + randomDigits(13); /** Nicaragua tax identification number. */ -const ruc: Validator = { +const ruc: CountryValidator<"NI"> = { name: "Tax Identification Number", localName: "Registro Único de Contribuyente", abbreviation: "RUC", aliases: ["RUC"] as const, candidatePattern: "[JKME]\\d{13}", + scope: "country", country: "NI", entityType: "any", description: "Tax identifier issued by Nicaragua's DGI", diff --git a/src/nl/bsn.ts b/src/nl/bsn.ts index 2560c8b..f2068b5 100644 --- a/src/nl/bsn.ts +++ b/src/nl/bsn.ts @@ -8,7 +8,10 @@ * @see https://www.government.nl/topics/personal-data/citizen-service-number-bsn */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -62,7 +65,7 @@ const generate = (): string => { }; /** Dutch Citizen Service Number. */ -const bsn: Validator = { +const bsn: CountryValidator<"NL"> = { name: "Dutch Citizen Service Number", localName: "Burgerservicenummer", abbreviation: "BSN", @@ -72,6 +75,7 @@ const bsn: Validator = { "sofinummer", ] as const, candidatePattern: "\\d{9}", + scope: "country", country: "NL", entityType: "person", sourceUrl: diff --git a/src/nl/kvk.ts b/src/nl/kvk.ts index 452aa14..5f63f5e 100644 --- a/src/nl/kvk.ts +++ b/src/nl/kvk.ts @@ -9,7 +9,10 @@ const generate = (): string => randomDigits(8); * @see https://www.kvk.nl/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -39,12 +42,13 @@ const validate = (value: string): ValidateResult => { const format = (value: string): string => compact(value); /** Dutch Chamber of Commerce Number. */ -const kvk: Validator = { +const kvk: CountryValidator<"NL"> = { name: "Dutch Chamber of Commerce Number", localName: "KvK-nummer", abbreviation: "KvK", aliases: ["KVK-nummer", "Kamer van Koophandel"] as const, candidatePattern: "\\d{8}", + scope: "country", country: "NL", entityType: "company", sourceUrl: "https://www.kvk.nl/", diff --git a/src/nl/vat.ts b/src/nl/vat.ts index efc1836..e300dda 100644 --- a/src/nl/vat.ts +++ b/src/nl/vat.ts @@ -12,7 +12,10 @@ * @see https://business.gov.nl/regulations/using-checking-vat-numbers/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -70,12 +73,13 @@ const generate = (): string => `${randomDigits(9)}B${randomDigits(2)}`; /** Dutch VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"NL"> = { name: "Dutch VAT Number", localName: "BTW-identificatienummer", abbreviation: "BTW", aliases: ["BTW-nummer", "BTW-id"] as const, candidatePattern: "NL\\d{9}B\\d{2}", + scope: "country", country: "NL", entityType: "company", sourceUrl: diff --git a/src/no/fodselsnummer.ts b/src/no/fodselsnummer.ts index 2c2f8f9..91fb5fe 100644 --- a/src/no/fodselsnummer.ts +++ b/src/no/fodselsnummer.ts @@ -11,7 +11,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { clean } from "#util/clean"; @@ -172,12 +172,16 @@ const generate = (): string => { }; /** Norwegian Birth Number. */ -const fodselsnummer: Validator = { +const fodselsnummer: CountryValidator< + "NO", + ParsedPersonId +> = { name: "Norwegian Birth Number", localName: "Fødselsnummer", abbreviation: "Fødselsnr", aliases: ["fødselsnummer", "personnummer"] as const, candidatePattern: "\\d{11}", + scope: "country", country: "NO", entityType: "person", sourceUrl: "https://www.skatteetaten.no/", diff --git a/src/no/mva.ts b/src/no/mva.ts index 5206c3d..79e3a76 100644 --- a/src/no/mva.ts +++ b/src/no/mva.ts @@ -7,7 +7,10 @@ * @see https://www.skatteetaten.no/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { validate as validateOrgnr, generate as generateOrgnr, @@ -53,12 +56,13 @@ const format = (value: string): string => { const generate = (): string => generateOrgnr() + "MVA"; /** Norwegian VAT Number. */ -const mva: Validator = { +const mva: CountryValidator<"NO"> = { name: "Norwegian VAT Number", localName: "Merverdiavgift", abbreviation: "MVA", aliases: ["MVA-nummer", "organisasjonsnummer"] as const, candidatePattern: "NO\\d{9}MVA", + scope: "country", country: "NO", entityType: "company", sourceUrl: "https://www.skatteetaten.no/", diff --git a/src/no/orgnr.ts b/src/no/orgnr.ts index df66a84..3fd9916 100644 --- a/src/no/orgnr.ts +++ b/src/no/orgnr.ts @@ -6,7 +6,10 @@ * @see https://www.brreg.no/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -59,12 +62,13 @@ const generate = (): string => { }; /** Norwegian Organization Number. */ -const orgnr: Validator = { +const orgnr: CountryValidator<"NO"> = { name: "Norwegian Organization Number", localName: "Organisasjonsnummer", abbreviation: "Orgnr", aliases: ["organisasjonsnummer", "org.nr"] as const, candidatePattern: "\\d{9}", + scope: "country", country: "NO", entityType: "company", sourceUrl: "https://www.brreg.no/", diff --git a/src/nz/ird.ts b/src/nz/ird.ts index d7c885a..649dbb5 100644 --- a/src/nz/ird.ts +++ b/src/nz/ird.ts @@ -9,7 +9,10 @@ * @see https://www.ird.govt.nz/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -105,12 +108,13 @@ const generate = (): string => { }; /** New Zealand IRD Number. */ -const ird: Validator = { +const ird: CountryValidator<"NZ"> = { name: "IRD Number", localName: "IRD Number", abbreviation: "IRD", aliases: ["IRD number", "tax number NZ"] as const, candidatePattern: "\\d{8,9}", + scope: "country", country: "NZ", entityType: "any", compact, diff --git a/src/pa/ruc.ts b/src/pa/ruc.ts index 3369f2c..4fac071 100644 --- a/src/pa/ruc.ts +++ b/src/pa/ruc.ts @@ -17,7 +17,10 @@ * @see https://dgi.mef.gob.pa/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomInt } from "#util/generate"; @@ -359,12 +362,13 @@ const generate = (): string => { }; /** Panama tax identification number. */ -const ruc: Validator = { +const ruc: CountryValidator<"PA"> = { name: "Tax Identification Number", localName: "Registro Único de Contribuyente", abbreviation: "RUC", aliases: ["RUC"] as const, candidatePattern: "\\d{1,2}-?\\d{1,4}-?\\d{1,6}", + scope: "country", country: "PA", entityType: "any", description: "Tax identifier issued by Panama's DGI", diff --git a/src/patterns.ts b/src/patterns.ts index 1e76b60..51d1e99 100644 --- a/src/patterns.ts +++ b/src/patterns.ts @@ -27,13 +27,19 @@ * ``` */ -import type { CountryCode, Validator } from "./types"; +import type { + CountryCode, + CountryValidator, + Validator, +} from "./types"; // ─── Pattern type ───────────────────────────── -export type ValidatorPattern = { +export type ValidatorPattern< + TValidator extends Validator = Validator, +> = { /** The validator this pattern was derived from. */ - validator: Validator; + validator: TValidator; /** Loose regex matching candidates in text. */ regex: RegExp; }; @@ -314,9 +320,9 @@ export const toRegex = (v: Validator): RegExp => { /** * Build patterns for a list of validators. */ -export const toPatterns = ( - validators: readonly Validator[], -): ValidatorPattern[] => +export const toPatterns = ( + validators: readonly TValidator[], +): ValidatorPattern[] => validators.map((v) => ({ validator: v, regex: toRegex(v), @@ -326,22 +332,47 @@ export const toPatterns = ( * Filter validators by country code and build * patterns. */ -export const byCountry = ( - country: CountryCode, - validators: readonly Validator[], -): ValidatorPattern[] => - toPatterns( - validators.filter((v) => v.country === country), +type CountryScopedValidator< + TValidator extends Validator, + TCountry extends CountryCode, +> = + TValidator extends CountryValidator< + infer TValidatorCountry, + infer TParsed + > + ? TCountry extends TValidatorCountry + ? TValidator & CountryValidator + : TValidatorCountry extends TCountry + ? TValidator + : never + : never; + +export const byCountry = < + TCountry extends CountryCode, + TValidator extends Validator, +>( + country: TCountry, + validators: readonly TValidator[], +): ValidatorPattern< + CountryScopedValidator +>[] => { + const countryValidators = validators.filter( + ( + v, + ): v is CountryScopedValidator => + v.scope === "country" && v.country === country, ); + return toPatterns(countryValidators); +}; /** * Filter validators by entity type and build * patterns. */ -export const byEntityType = ( +export const byEntityType = ( entityType: "person" | "company" | "any", - validators: readonly Validator[], -): ValidatorPattern[] => + validators: readonly TValidator[], +): ValidatorPattern[] => toPatterns( validators.filter( (v) => @@ -354,6 +385,6 @@ export const byEntityType = ( /** * Build patterns for ALL provided validators. */ -export const allPatterns = ( - validators: readonly Validator[], -): ValidatorPattern[] => toPatterns(validators); +export const allPatterns = ( + validators: readonly TValidator[], +): ValidatorPattern[] => toPatterns(validators); diff --git a/src/pe/ruc.ts b/src/pe/ruc.ts index f9774f2..f4e28c7 100644 --- a/src/pe/ruc.ts +++ b/src/pe/ruc.ts @@ -14,7 +14,10 @@ * @see https://en.wikipedia.org/wiki/Tax_identification_number#Peru */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomPick } from "#util/generate"; @@ -99,12 +102,13 @@ const generate = (): string => { * Examples sourced from python-stdnum test suite * (pe.ruc module). */ -const ruc: Validator = { +const ruc: CountryValidator<"PE"> = { name: "Peruvian Tax ID", localName: "Registro Único de Contribuyentes", abbreviation: "RUC", aliases: ["RUC"] as const, candidatePattern: "\\d{11}", + scope: "country", country: "PE", entityType: "any", compact, diff --git a/src/ph/philid.ts b/src/ph/philid.ts index e1724ff..64ad04e 100644 --- a/src/ph/philid.ts +++ b/src/ph/philid.ts @@ -14,7 +14,10 @@ const generate = (): string => randomDigits(12); * @see https://philsys.gov.ph/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -50,12 +53,13 @@ const format = (value: string): string => { }; /** Philippine Identification System Number. */ -const philid: Validator = { +const philid: CountryValidator<"PH"> = { name: "Philippine Identification System Number", localName: "PhilSys Card Number", abbreviation: "PhilID", aliases: ["PhilID", "PhilSys", "Philippine ID"] as const, candidatePattern: "\\d{4}-\\d{4}-\\d{4}-\\d{4}", + scope: "country", country: "PH", entityType: "person", description: diff --git a/src/pk/cnic.ts b/src/pk/cnic.ts index 283ec84..de169ed 100644 --- a/src/pk/cnic.ts +++ b/src/pk/cnic.ts @@ -20,7 +20,10 @@ const generate = (): string => { * @see https://en.wikipedia.org/wiki/CNIC_(Pakistan) */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -81,12 +84,13 @@ const format = (value: string): string => { }; /** Pakistan Computerized National Identity Card. */ -const cnic: Validator = { +const cnic: CountryValidator<"PK"> = { name: "Computerized National Identity Card", localName: "Computerized National Identity Card", abbreviation: "CNIC", aliases: ["CNIC", "شناختی کارڈ"] as const, candidatePattern: "\\d{5}-?\\d{7}-?\\d", + scope: "country", country: "PK", entityType: "person", lengths: [13], diff --git a/src/pl/nip.ts b/src/pl/nip.ts index bb216af..c78387f 100644 --- a/src/pl/nip.ts +++ b/src/pl/nip.ts @@ -8,7 +8,10 @@ * @see https://www.oecd.org/content/dam/oecd/en/topics/policy-issue-focus/aeoi/poland-tin.pdf */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -73,7 +76,7 @@ const generate = (): string => { }; /** Polish VAT Number. */ -const nip: Validator = { +const nip: CountryValidator<"PL"> = { name: "Polish VAT Number", localName: "Numer Identyfikacji Podatkowej", abbreviation: "NIP", @@ -82,6 +85,7 @@ const nip: Validator = { "numer identyfikacji podatkowej", ] as const, candidatePattern: "\\d{3}-?\\d{3}-?\\d{2}-?\\d{2}", + scope: "country", country: "PL", entityType: "company", sourceUrl: "https://www.biznes.gov.pl/en/portal/004124", diff --git a/src/pl/pesel.ts b/src/pl/pesel.ts index 6bbc115..6ac14c7 100644 --- a/src/pl/pesel.ts +++ b/src/pl/pesel.ts @@ -13,7 +13,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { weightedSum } from "#checksums/weighted-sum"; @@ -131,13 +131,14 @@ const generate = (): string => { }; /** Polish National Identification Number. */ -const pesel: Validator = { +const pesel: CountryValidator<"PL", ParsedPersonId> = { name: "Polish National ID", localName: "Powszechny Elektroniczny System Ewidencji Ludności", abbreviation: "PESEL", aliases: ["PESEL"] as const, candidatePattern: "\\d{11}", + scope: "country", country: "PL", entityType: "person", sourceUrl: diff --git a/src/pl/regon.ts b/src/pl/regon.ts index dc2c36e..81571c3 100644 --- a/src/pl/regon.ts +++ b/src/pl/regon.ts @@ -9,7 +9,10 @@ * @see https://bip.stat.gov.pl/en/regon/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -78,12 +81,13 @@ const generate = (): string => { }; /** Polish Statistical Identification Number. */ -const regon: Validator = { +const regon: CountryValidator<"PL"> = { name: "Polish Business Register Number", localName: "Rejestr Gospodarki Narodowej", abbreviation: "REGON", aliases: ["REGON", "numer statystyczny"] as const, candidatePattern: "\\d{9,14}", + scope: "country", country: "PL", entityType: "company", sourceUrl: "https://bip.stat.gov.pl/en/regon/", diff --git a/src/pt/cc.ts b/src/pt/cc.ts index 531464c..727d54f 100644 --- a/src/pt/cc.ts +++ b/src/pt/cc.ts @@ -8,7 +8,10 @@ * @see https://pt.wikipedia.org/wiki/Cartão_de_cidadão */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomChar, randomDigits } from "#util/generate"; @@ -80,7 +83,7 @@ const generate = (): string => { }; /** Portuguese Identity Card number. */ -const cc: Validator = { +const cc: CountryValidator<"PT"> = { name: "Portuguese Identity Card", localName: "Cartão de Cidadão", abbreviation: "CC", @@ -90,6 +93,7 @@ const cc: Validator = { "número de identificação civil", ] as const, candidatePattern: "\\d{8}\\s?\\d\\s?[A-Z]{2}\\d", + scope: "country", country: "PT", entityType: "person", description: diff --git a/src/pt/vat.ts b/src/pt/vat.ts index b7122a2..de01ee8 100644 --- a/src/pt/vat.ts +++ b/src/pt/vat.ts @@ -9,7 +9,10 @@ * @see https://www.portaldasfinancas.gov.pt/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -69,7 +72,7 @@ const generate = (): string => { }; /** Portuguese VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"PT"> = { name: "Portuguese VAT Number", localName: "Número de Identificação Fiscal", abbreviation: "NIF", @@ -79,6 +82,7 @@ const vat: Validator = { "contribuinte", ] as const, candidatePattern: "PT\\d{9}", + scope: "country", country: "PT", entityType: "any", sourceUrl: "https://www.portaldasfinancas.gov.pt/", diff --git a/src/ro/cnp.ts b/src/ro/cnp.ts index f249487..73a601c 100644 --- a/src/ro/cnp.ts +++ b/src/ro/cnp.ts @@ -12,7 +12,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { weightedSum } from "#checksums/weighted-sum"; @@ -155,13 +155,14 @@ const generate = (): string => { }; /** Romanian Personal Identification Number. */ -const cnp: Validator = { +const cnp: CountryValidator<"RO", ParsedPersonId> = { name: "Romanian Personal ID", localName: "Cod Numeric Personal", abbreviation: "CNP", aliases: ["CNP", "cod numeric personal"] as const, candidatePattern: "[1-8]\\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\\d|3[01])\\d{6}", + scope: "country", country: "RO", entityType: "person", sourceUrl: "https://www.cnp.ro/", diff --git a/src/ro/vat.ts b/src/ro/vat.ts index ddba269..1684f89 100644 --- a/src/ro/vat.ts +++ b/src/ro/vat.ts @@ -9,7 +9,10 @@ * @see https://www.anaf.ro/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -69,7 +72,7 @@ const generate = (): string => { }; /** Romanian VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"RO"> = { name: "Romanian VAT Number", localName: "Cod de Identificare Fiscală", abbreviation: "CIF", @@ -80,6 +83,7 @@ const vat: Validator = { "cod fiscal", ] as const, candidatePattern: "RO\\d{2,10}", + scope: "country", country: "RO", entityType: "any", sourceUrl: "https://www.anaf.ro/", diff --git a/src/rs/pib.ts b/src/rs/pib.ts index d41004b..159792f 100644 --- a/src/rs/pib.ts +++ b/src/rs/pib.ts @@ -8,7 +8,10 @@ * @see https://www.purs.gov.rs/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -62,12 +65,13 @@ const generate = (): string => { }; /** Serbian Tax Identification Number. */ -const pib: Validator = { +const pib: CountryValidator<"RS"> = { name: "Serbian Tax ID", localName: "Poreski identifikacioni broj", abbreviation: "PIB", aliases: ["PIB", "poreski identifikacioni broj"] as const, candidatePattern: "\\d{9}", + scope: "country", country: "RS", entityType: "any", lengths: [9] as const, diff --git a/src/ru/inn.ts b/src/ru/inn.ts index 6ea1e75..90197dd 100644 --- a/src/ru/inn.ts +++ b/src/ru/inn.ts @@ -10,7 +10,10 @@ * @see https://www.nalog.gov.ru/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -88,12 +91,13 @@ const generate = (): string => { }; /** Russian Taxpayer Identification Number. */ -const inn: Validator = { +const inn: CountryValidator<"RU"> = { name: "Russian Tax ID", localName: "Идентификационный номер налогоплательщика", abbreviation: "ИНН", aliases: ["ИНН", "INN"] as const, candidatePattern: "\\d{10,12}", + scope: "country", country: "RU", entityType: "any", lengths: [10, 12] as const, diff --git a/src/se/orgnr.ts b/src/se/orgnr.ts index 3b4f917..2218541 100644 --- a/src/se/orgnr.ts +++ b/src/se/orgnr.ts @@ -7,7 +7,10 @@ * @see https://www.skatteverket.se/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { luhnValidate, @@ -57,7 +60,7 @@ const generate = (): string => { }; /** Swedish Organization Number. */ -const orgnr: Validator = { +const orgnr: CountryValidator<"SE"> = { name: "Swedish Organization Number", localName: "Organisationsnummer", abbreviation: "Orgnr", @@ -67,6 +70,7 @@ const orgnr: Validator = { "org nr", ] as const, candidatePattern: "\\d{6}-\\d{4}", + scope: "country", country: "SE", entityType: "company", sourceUrl: "https://www.skatteverket.se/", diff --git a/src/se/personnummer.ts b/src/se/personnummer.ts index adb4c39..82a9611 100644 --- a/src/se/personnummer.ts +++ b/src/se/personnummer.ts @@ -11,7 +11,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { @@ -154,28 +154,30 @@ const generate = (): string => { }; /** Swedish Personal Identity Number. */ -const personnummer: Validator = { - name: "Swedish Personal ID", - localName: "Personnummer", - abbreviation: "PN", - aliases: [ - "personnummer", - "personnr", - "pers.nr", - "personal identity number", - ] as const, - candidatePattern: "\\d{6,8}-\\d{4}", - country: "SE", - entityType: "person", - sourceUrl: - "https://www.skatteverket.se/privat/folkbokforing/personnummer.4.3810a01c150939e893f18c29.html", - examples: ["880320-0016"] as const, - compact, - format, - parse, - validate, - generate, -}; +const personnummer: CountryValidator<"SE", ParsedPersonId> = + { + name: "Swedish Personal ID", + localName: "Personnummer", + abbreviation: "PN", + aliases: [ + "personnummer", + "personnr", + "pers.nr", + "personal identity number", + ] as const, + candidatePattern: "\\d{6,8}-\\d{4}", + scope: "country", + country: "SE", + entityType: "person", + sourceUrl: + "https://www.skatteverket.se/privat/folkbokforing/personnummer.4.3810a01c150939e893f18c29.html", + examples: ["880320-0016"] as const, + compact, + format, + parse, + validate, + generate, + }; export default personnummer; export { compact, format, parse, validate, generate }; diff --git a/src/se/vat.ts b/src/se/vat.ts index f07f2a5..1327782 100644 --- a/src/se/vat.ts +++ b/src/se/vat.ts @@ -8,7 +8,10 @@ * @see https://www.skatteverket.se/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { luhnValidate, @@ -67,7 +70,7 @@ const generate = (): string => { }; /** Swedish VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"SE"> = { name: "Swedish VAT Number", localName: "Momsregistreringsnummer", abbreviation: "Momsnr.", @@ -78,6 +81,7 @@ const vat: Validator = { "SE VAT", ] as const, candidatePattern: "SE\\s?\\d{10}01", + scope: "country", country: "SE", entityType: "company", sourceUrl: "https://www.skatteverket.se/", diff --git a/src/sg/uen.ts b/src/sg/uen.ts index 8b536c5..b15f72b 100644 --- a/src/sg/uen.ts +++ b/src/sg/uen.ts @@ -14,7 +14,10 @@ * @see https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Singapore-TIN.pdf */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -257,12 +260,13 @@ const generate = (): string => { }; /** Singapore Unique Entity Number. */ -const uen: Validator = { +const uen: CountryValidator<"SG"> = { name: "Singapore Unique Entity Number", localName: "Unique Entity Number", abbreviation: "UEN", aliases: ["UEN", "Unique Entity Number"] as const, candidatePattern: "[\\dSTR]\\d{7}[A-Z]", + scope: "country", country: "SG", entityType: "company", description: diff --git a/src/si/emso.ts b/src/si/emso.ts index c196722..bb29d59 100644 --- a/src/si/emso.ts +++ b/src/si/emso.ts @@ -18,7 +18,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { weightedSum } from "#checksums/weighted-sum"; @@ -152,7 +152,7 @@ const generate = (): string => { }; /** Slovenian Unique Master Citizen Number. */ -const emso: Validator = { +const emso: CountryValidator<"SI", ParsedPersonId> = { name: "Slovenian Personal ID", localName: "Enotna matična številka občana", abbreviation: "EMŠO", @@ -161,6 +161,7 @@ const emso: Validator = { "enotna matična številka občana", ] as const, candidatePattern: "\\d{13}", + scope: "country", country: "SI", entityType: "person", sourceUrl: diff --git a/src/si/vat.ts b/src/si/vat.ts index 5437908..04b1670 100644 --- a/src/si/vat.ts +++ b/src/si/vat.ts @@ -10,7 +10,10 @@ * @see https://spot.gov.si/en/info/taxes/value-added-tax-vat */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { weightedSum } from "#checksums/weighted-sum"; import { clean } from "#util/clean"; @@ -85,7 +88,7 @@ const generate = (): string => { }; /** Slovenian VAT Number. */ -const vat: Validator = { +const vat: CountryValidator<"SI"> = { name: "Slovenian VAT Number", localName: "Davčna številka", abbreviation: "DDV", @@ -94,6 +97,7 @@ const vat: Validator = { "identifikacijska številka za DDV", ] as const, candidatePattern: "SI\\d{8}", + scope: "country", country: "SI", entityType: "company", sourceUrl: "https://www.fu.gov.si/", diff --git a/src/sk/dic.ts b/src/sk/dic.ts index 265d566..4dc53dc 100644 --- a/src/sk/dic.ts +++ b/src/sk/dic.ts @@ -10,7 +10,10 @@ */ import { validate as validateRc } from "../cz/rc"; -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -85,13 +88,14 @@ const generate = (): string => { }; /** Slovak VAT Number. */ -const dic: Validator = { +const dic: CountryValidator<"SK"> = { name: "Slovak VAT Number", localName: "Identifikačné číslo pre daň z pridanej hodnoty", abbreviation: "IČ DPH", aliases: ["DIČ", "daňové identifikačné číslo"] as const, candidatePattern: "SK\\d{10}", + scope: "country", country: "SK", entityType: "company", sourceUrl: "https://www.financnasprava.sk/", diff --git a/src/sk/ico.ts b/src/sk/ico.ts index 605c2b2..4b05efe 100644 --- a/src/sk/ico.ts +++ b/src/sk/ico.ts @@ -13,10 +13,10 @@ import { generate, validate, } from "../cz/ico"; -import type { Validator } from "../types"; +import type { CountryValidator } from "../types"; /** Slovak Company Identification Number. */ -const ico: Validator = { +const ico: CountryValidator<"SK"> = { name: "Slovak Company ID", localName: "Identifikačné číslo organizácie", abbreviation: "IČO", @@ -25,6 +25,7 @@ const ico: Validator = { "identifikačné číslo organizácie", ] as const, candidatePattern: "\\d{8}", + scope: "country", country: "SK", entityType: "company", sourceUrl: "https://www.statistics.sk/", diff --git a/src/sk/rc.ts b/src/sk/rc.ts index e5c81a2..e0c2722 100644 --- a/src/sk/rc.ts +++ b/src/sk/rc.ts @@ -15,15 +15,19 @@ import { parse, validate, } from "../cz/rc"; -import type { ParsedPersonId, Validator } from "../types"; +import type { + ParsedPersonId, + CountryValidator, +} from "../types"; /** Slovak Birth Number. */ -const rc: Validator = { +const rc: CountryValidator<"SK", ParsedPersonId> = { name: "Slovak Birth Number", localName: "Rodné číslo", abbreviation: "RČ", aliases: ["rodné číslo", "RČ"] as const, candidatePattern: "\\d{6}/\\d{3,4}", + scope: "country", country: "SK", entityType: "person", sourceUrl: "https://www.minv.sk/", diff --git a/src/th/tin.ts b/src/th/tin.ts index 529d5cb..338ced5 100644 --- a/src/th/tin.ts +++ b/src/th/tin.ts @@ -10,7 +10,10 @@ * @see https://en.wikipedia.org/wiki/Thai_identity_card */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -79,12 +82,13 @@ const generate = (): string => { }; /** Thai Tax Identification Number. */ -const tin: Validator = { +const tin: CountryValidator<"TH"> = { name: "Thai Tax Identification Number", localName: "เลขประจำตัวผู้เสียภาษี", abbreviation: "TIN", aliases: ["เลขประจำตัวผู้เสียภาษี", "TIN"] as const, candidatePattern: "\\d{13}", + scope: "country", country: "TH", entityType: "any", description: diff --git a/src/tr/tckimlik.ts b/src/tr/tckimlik.ts index 7e00fea..73b9990 100644 --- a/src/tr/tckimlik.ts +++ b/src/tr/tckimlik.ts @@ -19,7 +19,10 @@ * @see https://www.turkiye.gov.tr/nvi-tckn-dogrulama */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -88,7 +91,7 @@ const generate = (): string => { }; /** Turkish Personal Identification Number. */ -const tckimlik: Validator = { +const tckimlik: CountryValidator<"TR"> = { name: "Turkish Personal ID", localName: "T.C. Kimlik Numarası", abbreviation: "T.C. Kimlik", @@ -97,6 +100,7 @@ const tckimlik: Validator = { "T.C. Kimlik Numarası", ] as const, candidatePattern: "[1-9]\\d{10}", + scope: "country", country: "TR", entityType: "person", sourceUrl: "https://www.nvi.gov.tr/", diff --git a/src/tr/vkn.ts b/src/tr/vkn.ts index 1634829..e73fa00 100644 --- a/src/tr/vkn.ts +++ b/src/tr/vkn.ts @@ -19,7 +19,10 @@ * @see https://www.gib.gov.tr/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -77,12 +80,13 @@ const generate = (): string => { }; /** Turkish Tax Identification Number. */ -const vkn: Validator = { +const vkn: CountryValidator<"TR"> = { name: "Turkish Tax ID", localName: "Vergi Kimlik Numarası", abbreviation: "VKN", aliases: ["VKN", "Vergi Kimlik Numarası"] as const, candidatePattern: "\\d{10}", + scope: "country", country: "TR", entityType: "company", sourceUrl: "https://www.gib.gov.tr/", diff --git a/src/tw/ubn.ts b/src/tw/ubn.ts index ba27329..5a2222a 100644 --- a/src/tw/ubn.ts +++ b/src/tw/ubn.ts @@ -10,7 +10,10 @@ * @see https://zh.wikipedia.org/wiki/統一編號 */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -84,12 +87,13 @@ const generate = (): string => { }; /** Taiwanese Unified Business Number. */ -const ubn: Validator = { +const ubn: CountryValidator<"TW"> = { name: "Unified Business Number", localName: "統一編號", abbreviation: "UBN", aliases: ["統一編號", "UBN"] as const, candidatePattern: "\\d{8}", + scope: "country", country: "TW", entityType: "company", description: diff --git a/src/types.ts b/src/types.ts index 87b7163..555c237 100644 --- a/src/types.ts +++ b/src/types.ts @@ -135,7 +135,20 @@ export type ParsedIdentifier = | ParsedBirthDate | ParsedPersonId; -export type Validator< +/** + * Whether an identifier is scoped to a single + * country (e.g. Czech IČO) or is cross-border by + * design (e.g. IBAN, ISIN, BIC, LEI, EU VAT). + * + * Modeled as a discriminated union so consumers + * can group, filter, and exhaustively switch + * without null-checking `country`. + */ +export type ValidatorScope = + | { scope: "country"; country: CountryCode } + | { scope: "global" }; + +type ValidatorBase< TParsed extends ParsedIdentifier | undefined = undefined, > = { /** English name. */ @@ -144,8 +157,6 @@ export type Validator< localName: string; /** Common abbreviation (e.g. "IČO"). */ abbreviation: string; - /** Country this identifier belongs to. */ - country?: CountryCode; /** What kind of entity this identifies. */ entityType: "person" | "company" | "any"; @@ -226,6 +237,26 @@ export type Validator< ? unknown : { parse: (value: string) => TParsed | null }); +export type CountryValidator< + TCountry extends CountryCode = CountryCode, + TParsed extends ParsedIdentifier | undefined = undefined, +> = ValidatorBase & { + scope: "country"; + country: TCountry; +}; + +export type GlobalValidator< + TParsed extends ParsedIdentifier | undefined = undefined, +> = ValidatorBase & { + scope: "global"; +}; + +export type Validator< + TParsed extends ParsedIdentifier | undefined = undefined, +> = + | CountryValidator + | GlobalValidator; + export type ParsableValidator< TParsed extends ParsedIdentifier = ParsedIdentifier, > = Validator; diff --git a/src/ua/edrpou.ts b/src/ua/edrpou.ts index af41795..0f0a851 100644 --- a/src/ua/edrpou.ts +++ b/src/ua/edrpou.ts @@ -10,7 +10,10 @@ * @see https://usr.minjust.gov.ua/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits } from "#util/generate"; @@ -83,12 +86,13 @@ const generate = (): string => { }; /** Ukrainian Company Register Number. */ -const edrpou: Validator = { +const edrpou: CountryValidator<"UA"> = { name: "Ukrainian Company Register Number", localName: "ЄДРПОУ", abbreviation: "ЄДРПОУ", aliases: ["ЄДРПОУ", "EDRPOU"] as const, candidatePattern: "\\d{8}", + scope: "country", country: "UA", entityType: "company", lengths: [8] as const, diff --git a/src/us/ein.ts b/src/us/ein.ts index 5f1525f..e298ef1 100644 --- a/src/us/ein.ts +++ b/src/us/ein.ts @@ -101,7 +101,10 @@ const generate = (): string => { * @see https://www.irs.gov/businesses/small-businesses-self-employed/how-eins-are-assigned-and-valid-ein-prefixes */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomPick } from "#util/generate"; @@ -232,7 +235,7 @@ const format = (value: string): string => { }; /** U.S. Employer Identification Number. */ -const ein: Validator = { +const ein: CountryValidator<"US"> = { name: "Employer Identification Number", localName: "Employer Identification Number", abbreviation: "EIN", @@ -242,6 +245,7 @@ const ein: Validator = { "Federal Tax ID", ] as const, candidatePattern: "\\d{2}-?\\d{7}", + scope: "country", country: "US", entityType: "company", sourceUrl: diff --git a/src/us/itin.ts b/src/us/itin.ts index 76daa68..8fdd7e2 100644 --- a/src/us/itin.ts +++ b/src/us/itin.ts @@ -23,7 +23,10 @@ const generate = (): string => { * @see https://www.irs.gov/individuals/individual-taxpayer-identification-number */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomPick } from "#util/generate"; @@ -99,7 +102,7 @@ const format = (value: string): string => { /** * U.S. Individual Taxpayer Identification Number. */ -const itin: Validator = { +const itin: CountryValidator<"US"> = { name: "Individual Taxpayer Identification Number", localName: "Individual Taxpayer Identification Number", abbreviation: "ITIN", @@ -108,6 +111,7 @@ const itin: Validator = { "Individual Taxpayer Identification Number", ] as const, candidatePattern: "9\\d{2}[\\s-]?\\d{2}[\\s-]?\\d{4}", + scope: "country", country: "US", entityType: "person", sourceUrl: diff --git a/src/us/rtn.ts b/src/us/rtn.ts index 9232d49..dfd0e96 100644 --- a/src/us/rtn.ts +++ b/src/us/rtn.ts @@ -15,7 +15,10 @@ * @see https://www.frbservices.org/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { @@ -107,7 +110,7 @@ const generate = (): string => { }; /** U.S. Routing Transit Number. */ -const rtn: Validator = { +const rtn: CountryValidator<"US"> = { name: "Routing Transit Number", localName: "Routing Transit Number", abbreviation: "RTN", @@ -119,6 +122,7 @@ const rtn: Validator = { "Routing Transit Number", ] as const, candidatePattern: "\\d{9}", + scope: "country", country: "US", entityType: "company", sourceUrl: diff --git a/src/us/ssn.ts b/src/us/ssn.ts index 049cf18..e0201f7 100644 --- a/src/us/ssn.ts +++ b/src/us/ssn.ts @@ -27,7 +27,10 @@ const generate = (): string => { * @see https://www.ssa.gov/employer/verifySSN.htm */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomInt } from "#util/generate"; @@ -97,12 +100,13 @@ const format = (value: string): string => { }; /** U.S. Social Security Number. */ -const ssn: Validator = { +const ssn: CountryValidator<"US"> = { name: "Social Security Number", localName: "Social Security Number", abbreviation: "SSN", aliases: ["SSN", "Social Security Number"] as const, candidatePattern: "\\d{3}-?\\d{2}-?\\d{4}", + scope: "country", country: "US", entityType: "person", sourceUrl: "https://www.ssa.gov/employer/verifySSN.htm", diff --git a/src/uy/rut.ts b/src/uy/rut.ts index 594416e..7a4e7df 100644 --- a/src/uy/rut.ts +++ b/src/uy/rut.ts @@ -13,7 +13,10 @@ * @see https://www.agesic.gub.uy/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -125,12 +128,13 @@ const generate = (): string => { * * Examples sourced from python-stdnum test suite. */ -const rut: Validator = { +const rut: CountryValidator<"UY"> = { name: "Uruguayan Tax ID", localName: "Registro Único Tributario", abbreviation: "RUT", aliases: ["RUT", "Registro Único Tributario"] as const, candidatePattern: "\\d{12}", + scope: "country", country: "UY", entityType: "any", lengths: [12] as const, diff --git a/src/ve/rif.ts b/src/ve/rif.ts index dea930b..3b3858a 100644 --- a/src/ve/rif.ts +++ b/src/ve/rif.ts @@ -13,7 +13,10 @@ * @see https://en.wikipedia.org/wiki/Tax_Identification_Number#Venezuela */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomPick } from "#util/generate"; @@ -118,7 +121,7 @@ const generate = (): string => { * * Examples sourced from python-stdnum test suite. */ -const rif: Validator = { +const rif: CountryValidator<"VE"> = { name: "Venezuelan Tax ID", localName: "Registro de Información Fiscal", abbreviation: "RIF", @@ -127,6 +130,7 @@ const rif: Validator = { "Registro de Información Fiscal", ] as const, candidatePattern: "[VEJPG]-?\\d{8}-?\\d", + scope: "country", country: "VE", entityType: "any", lengths: [10] as const, diff --git a/src/vn/mst.ts b/src/vn/mst.ts index ded0337..f42a2cc 100644 --- a/src/vn/mst.ts +++ b/src/vn/mst.ts @@ -11,7 +11,10 @@ * @see https://easyinvoice.vn/ma-so-thue/ */ -import type { ValidateResult, Validator } from "../types"; +import type { + ValidateResult, + CountryValidator, +} from "../types"; import { clean } from "#util/clean"; import { randomDigits, randomInt } from "#util/generate"; @@ -104,12 +107,13 @@ const generate = (): string => { }; /** Vietnamese Tax Number. */ -const mst: Validator = { +const mst: CountryValidator<"VN"> = { name: "Vietnamese Tax Number", localName: "Mã số thuế", abbreviation: "MST", aliases: ["MST", "mã số thuế"] as const, candidatePattern: "\\d{10}(-\\d{3})?", + scope: "country", country: "VN", entityType: "company", description: diff --git a/src/za/idnr.ts b/src/za/idnr.ts index 7ff2658..3d6480c 100644 --- a/src/za/idnr.ts +++ b/src/za/idnr.ts @@ -16,7 +16,7 @@ import type { ParsedPersonId, ValidateResult, - Validator, + CountryValidator, } from "../types"; import { @@ -132,12 +132,13 @@ const generate = (): string => { }; /** South African Identity Number. */ -const idnr: Validator = { +const idnr: CountryValidator<"ZA", ParsedPersonId> = { name: "South African Identity Number", localName: "South African Identity Number", abbreviation: "SA ID", aliases: ["ID number", "RSA ID"] as const, candidatePattern: "\\d{13}", + scope: "country", country: "ZA", entityType: "person", compact,