@qinisolabs/qiniso 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/{chunk-I6MBL33Q.js → chunk-RMLPG7ZB.js} +433 -1
- package/dist/http.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +27 -1
- package/dist/server.js +1 -1
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
*Verified, trustworthy data tools for AI agents. "Qiniso" means "truth" in Zulu.*
|
|
10
10
|
|
|
11
|
-
[Website](https://qinisolabs.github.io/qiniso/) · [GitHub](https://github.com/qinisolabs/qiniso) · [MCP Registry](https://registry.modelcontextprotocol.io/v0/servers?search=qiniso)
|
|
11
|
+
[Website](https://qinisolabs.github.io/qiniso/) · [npm](https://www.npmjs.com/package/@qinisolabs/qiniso) · [GitHub](https://github.com/qinisolabs/qiniso) · [MCP Registry](https://registry.modelcontextprotocol.io/v0/servers?search=qiniso)
|
|
12
12
|
|
|
13
13
|
</div>
|
|
14
14
|
|
|
@@ -48,7 +48,7 @@ https://qiniso.qinisolabs.workers.dev/mcp
|
|
|
48
48
|
|
|
49
49
|
Or run it locally over stdio: `npx -p @qinisolabs/qiniso qiniso-mcp`.
|
|
50
50
|
|
|
51
|
-
## What it verifies —
|
|
51
|
+
## What it verifies — 47 tools across 8 domains
|
|
52
52
|
|
|
53
53
|
| Domain | Checks |
|
|
54
54
|
| --- | --- |
|
|
@@ -56,7 +56,7 @@ Or run it locally over stdio: `npx -p @qinisolabs/qiniso qiniso-mcp`.
|
|
|
56
56
|
| **Web / network** | TLD & domain (IANA root zone), IP, UUID, URL, email |
|
|
57
57
|
| **Finance** | ISIN, CUSIP, SEDOL, LEI, US ABA routing |
|
|
58
58
|
| **Crypto** | Ethereum (EIP-55), Bitcoin (Base58Check / Bech32) addresses |
|
|
59
|
-
| **National & tax IDs** | Brazil CPF/CNPJ, South Africa ID, Spain DNI/NIE, India Aadhaar, EU/UK VAT |
|
|
59
|
+
| **National & tax IDs** | Brazil CPF/CNPJ, South Africa ID, Spain DNI/NIE, India Aadhaar, Italy Codice Fiscale, Poland PESEL, Netherlands BSN, Belgium NRN, Sweden personnummer, Norway fødselsnummer, Finland HETU, Portugal NIF, Turkey TCKN, China Resident ID, EU/UK VAT |
|
|
60
60
|
| **Academic** | ISBN-10, ISSN, ORCID |
|
|
61
61
|
| **Locale** | Phone (global), date parsing, currency, holidays (~200 countries), UK VAT-by-date |
|
|
62
62
|
| **Addresses** | UK/US address parsing |
|
|
@@ -629,6 +629,115 @@ function validateGtin(input) {
|
|
|
629
629
|
return result;
|
|
630
630
|
}
|
|
631
631
|
|
|
632
|
+
// ../identifiers/dist/imei.js
|
|
633
|
+
function validateImei(input) {
|
|
634
|
+
const normalized = (input ?? "").replace(/[\s-]/g, "");
|
|
635
|
+
const result = {
|
|
636
|
+
input,
|
|
637
|
+
normalized,
|
|
638
|
+
valid: false,
|
|
639
|
+
type: null,
|
|
640
|
+
tac: null,
|
|
641
|
+
checkDigit: null,
|
|
642
|
+
expectedCheckDigit: null,
|
|
643
|
+
errors: []
|
|
644
|
+
};
|
|
645
|
+
if (!/^\d+$/.test(normalized)) {
|
|
646
|
+
result.errors.push("An IMEI must contain digits only (spaces and dashes are ignored).");
|
|
647
|
+
return result;
|
|
648
|
+
}
|
|
649
|
+
if (normalized.length === 16) {
|
|
650
|
+
result.type = "IMEISV";
|
|
651
|
+
result.tac = normalized.slice(0, 8);
|
|
652
|
+
result.valid = true;
|
|
653
|
+
result.note = "IMEISV (software-version form) has no check digit; format validated only.";
|
|
654
|
+
return result;
|
|
655
|
+
}
|
|
656
|
+
if (normalized.length !== 15) {
|
|
657
|
+
result.errors.push(`An IMEI must be 15 digits (or 16 for IMEISV); got ${normalized.length}.`);
|
|
658
|
+
return result;
|
|
659
|
+
}
|
|
660
|
+
result.type = "IMEI";
|
|
661
|
+
result.tac = normalized.slice(0, 8);
|
|
662
|
+
const expected = luhnCheckDigit(normalized.slice(0, 14));
|
|
663
|
+
result.checkDigit = normalized[14];
|
|
664
|
+
result.expectedCheckDigit = expected;
|
|
665
|
+
if (!luhnValid(normalized)) {
|
|
666
|
+
result.errors.push(`Luhn check digit failed: expected ${expected}, got ${normalized[14]}.`);
|
|
667
|
+
return result;
|
|
668
|
+
}
|
|
669
|
+
result.valid = true;
|
|
670
|
+
return result;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// ../identifiers/dist/gln.js
|
|
674
|
+
function validateGln(input) {
|
|
675
|
+
const normalized = (input ?? "").replace(/[\s-]/g, "");
|
|
676
|
+
const result = {
|
|
677
|
+
input,
|
|
678
|
+
normalized,
|
|
679
|
+
valid: false,
|
|
680
|
+
checkDigit: null,
|
|
681
|
+
gs1Prefix: null,
|
|
682
|
+
gs1Country: null,
|
|
683
|
+
errors: []
|
|
684
|
+
};
|
|
685
|
+
if (!/^\d+$/.test(normalized)) {
|
|
686
|
+
result.errors.push("A GLN must contain digits only (spaces and dashes are ignored).");
|
|
687
|
+
return result;
|
|
688
|
+
}
|
|
689
|
+
if (normalized.length !== 13) {
|
|
690
|
+
result.errors.push(`A GLN must be 13 digits; got ${normalized.length}.`);
|
|
691
|
+
return result;
|
|
692
|
+
}
|
|
693
|
+
const prefix3 = normalized.slice(0, 3);
|
|
694
|
+
result.gs1Prefix = prefix3;
|
|
695
|
+
result.gs1Country = gs1Country(prefix3);
|
|
696
|
+
const expected = gtinCheckDigit(normalized.slice(0, 12));
|
|
697
|
+
result.checkDigit = expected;
|
|
698
|
+
if (expected !== normalized[12]) {
|
|
699
|
+
result.errors.push(`Check digit failed: expected ${expected}, got ${normalized[12]}.`);
|
|
700
|
+
return result;
|
|
701
|
+
}
|
|
702
|
+
result.valid = true;
|
|
703
|
+
return result;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
// ../identifiers/dist/sscc.js
|
|
707
|
+
function validateSscc(input) {
|
|
708
|
+
const normalized = (input ?? "").replace(/[\s-]/g, "");
|
|
709
|
+
const result = {
|
|
710
|
+
input,
|
|
711
|
+
normalized,
|
|
712
|
+
valid: false,
|
|
713
|
+
extensionDigit: null,
|
|
714
|
+
checkDigit: null,
|
|
715
|
+
gs1Prefix: null,
|
|
716
|
+
gs1Country: null,
|
|
717
|
+
errors: []
|
|
718
|
+
};
|
|
719
|
+
if (!/^\d+$/.test(normalized)) {
|
|
720
|
+
result.errors.push("An SSCC must contain digits only (spaces and dashes are ignored).");
|
|
721
|
+
return result;
|
|
722
|
+
}
|
|
723
|
+
if (normalized.length !== 18) {
|
|
724
|
+
result.errors.push(`An SSCC must be 18 digits; got ${normalized.length}.`);
|
|
725
|
+
return result;
|
|
726
|
+
}
|
|
727
|
+
result.extensionDigit = normalized[0];
|
|
728
|
+
const prefix3 = normalized.slice(1, 4);
|
|
729
|
+
result.gs1Prefix = prefix3;
|
|
730
|
+
result.gs1Country = gs1Country(prefix3);
|
|
731
|
+
const expected = gtinCheckDigit(normalized.slice(0, 17));
|
|
732
|
+
result.checkDigit = expected;
|
|
733
|
+
if (expected !== normalized[17]) {
|
|
734
|
+
result.errors.push(`Check digit failed: expected ${expected}, got ${normalized[17]}.`);
|
|
735
|
+
return result;
|
|
736
|
+
}
|
|
737
|
+
result.valid = true;
|
|
738
|
+
return result;
|
|
739
|
+
}
|
|
740
|
+
|
|
632
741
|
// ../network/dist/data/tlds.json
|
|
633
742
|
var tlds_default = ["aaa", "aarp", "abb", "abbott", "abbvie", "abc", "able", "abogado", "abudhabi", "ac", "academy", "accenture", "accountant", "accountants", "aco", "actor", "ad", "ads", "adult", "ae", "aeg", "aero", "aetna", "af", "afl", "africa", "ag", "agakhan", "agency", "ai", "aig", "airbus", "airforce", "airtel", "akdn", "al", "alibaba", "alipay", "allfinanz", "allstate", "ally", "alsace", "alstom", "am", "amazon", "americanexpress", "americanfamily", "amex", "amfam", "amica", "amsterdam", "analytics", "android", "anquan", "anz", "ao", "aol", "apartments", "app", "apple", "aq", "aquarelle", "ar", "arab", "aramco", "archi", "army", "arpa", "art", "arte", "as", "asda", "asia", "associates", "at", "athleta", "attorney", "au", "auction", "audi", "audible", "audio", "auspost", "author", "auto", "autos", "aw", "aws", "ax", "axa", "az", "azure", "ba", "baby", "baidu", "banamex", "band", "bank", "bar", "barcelona", "barclaycard", "barclays", "barefoot", "bargains", "baseball", "basketball", "bauhaus", "bayern", "bb", "bbc", "bbt", "bbva", "bcg", "bcn", "bd", "be", "beats", "beauty", "beer", "berlin", "best", "bestbuy", "bet", "bf", "bg", "bh", "bharti", "bi", "bible", "bid", "bike", "bing", "bingo", "bio", "biz", "bj", "black", "blackfriday", "blockbuster", "blog", "bloomberg", "blue", "bm", "bms", "bmw", "bn", "bnpparibas", "bo", "boats", "boehringer", "bofa", "bom", "bond", "boo", "book", "booking", "bosch", "bostik", "boston", "bot", "boutique", "box", "br", "bradesco", "bridgestone", "broadway", "broker", "brother", "brussels", "bs", "bt", "build", "builders", "business", "buy", "buzz", "bv", "bw", "by", "bz", "bzh", "ca", "cab", "cafe", "cal", "call", "calvinklein", "cam", "camera", "camp", "canon", "capetown", "capital", "capitalone", "car", "caravan", "cards", "care", "career", "careers", "cars", "casa", "case", "cash", "casino", "cat", "catering", "catholic", "cba", "cbn", "cbre", "cc", "cd", "center", "ceo", "cern", "cf", "cfa", "cfd", "cg", "ch", "chanel", "channel", "charity", "chase", "chat", "cheap", "chintai", "christmas", "chrome", "church", "ci", "cipriani", "circle", "cisco", "citadel", "citi", "citic", "city", "ck", "cl", "claims", "cleaning", "click", "clinic", "clinique", "clothing", "cloud", "club", "clubmed", "cm", "cn", "co", "coach", "codes", "coffee", "college", "cologne", "com", "commbank", "community", "company", "compare", "computer", "comsec", "condos", "construction", "consulting", "contact", "contractors", "cooking", "cool", "coop", "corsica", "country", "coupon", "coupons", "courses", "cpa", "cr", "credit", "creditcard", "creditunion", "cricket", "crown", "crs", "cruise", "cruises", "cu", "cuisinella", "cv", "cw", "cx", "cy", "cymru", "cyou", "cz", "dad", "dance", "data", "date", "dating", "datsun", "day", "dclk", "dds", "de", "deal", "dealer", "deals", "degree", "delivery", "dell", "deloitte", "delta", "democrat", "dental", "dentist", "desi", "design", "dev", "dhl", "diamonds", "diet", "digital", "direct", "directory", "discount", "discover", "dish", "diy", "dj", "dk", "dm", "dnp", "do", "docs", "doctor", "dog", "domains", "dot", "download", "drive", "dtv", "dubai", "dupont", "durban", "dvag", "dvr", "dz", "earth", "eat", "ec", "eco", "edeka", "edu", "education", "ee", "eg", "email", "emerck", "energy", "engineer", "engineering", "enterprises", "epson", "equipment", "er", "ericsson", "erni", "es", "esq", "estate", "et", "eu", "eurovision", "eus", "events", "exchange", "expert", "exposed", "express", "extraspace", "fage", "fail", "fairwinds", "faith", "family", "fan", "fans", "farm", "farmers", "fashion", "fast", "fedex", "feedback", "ferrari", "ferrero", "fi", "fidelity", "fido", "film", "final", "finance", "financial", "fire", "firestone", "firmdale", "fish", "fishing", "fit", "fitness", "fj", "fk", "flickr", "flights", "flir", "florist", "flowers", "fly", "fm", "fo", "foo", "food", "football", "ford", "forex", "forsale", "forum", "foundation", "fox", "fr", "free", "fresenius", "frl", "frogans", "frontier", "ftr", "fujitsu", "fun", "fund", "furniture", "futbol", "fyi", "ga", "gal", "gallery", "gallo", "gallup", "game", "games", "gap", "garden", "gay", "gb", "gbiz", "gd", "gdn", "ge", "gea", "gent", "genting", "george", "gf", "gg", "ggee", "gh", "gi", "gift", "gifts", "gives", "giving", "gl", "glass", "gle", "global", "globo", "gm", "gmail", "gmbh", "gmo", "gmx", "gn", "godaddy", "gold", "goldpoint", "golf", "goodyear", "goog", "google", "gop", "got", "gov", "gp", "gq", "gr", "grainger", "graphics", "gratis", "green", "gripe", "grocery", "group", "gs", "gt", "gu", "gucci", "guge", "guide", "guitars", "guru", "gw", "gy", "hair", "hamburg", "hangout", "haus", "hbo", "hdfc", "hdfcbank", "health", "healthcare", "help", "helsinki", "here", "hermes", "hiphop", "hisamitsu", "hitachi", "hiv", "hk", "hkt", "hm", "hn", "hockey", "holdings", "holiday", "homedepot", "homegoods", "homes", "homesense", "honda", "horse", "hospital", "host", "hosting", "hot", "hotels", "hotmail", "house", "how", "hr", "hsbc", "ht", "hu", "hughes", "hyatt", "hyundai", "ibm", "icbc", "ice", "icu", "id", "ie", "ieee", "ifm", "ikano", "il", "im", "imamat", "imdb", "immo", "immobilien", "in", "inc", "industries", "infiniti", "info", "ing", "ink", "institute", "insurance", "insure", "int", "international", "intuit", "investments", "io", "ipiranga", "iq", "ir", "irish", "is", "ismaili", "ist", "istanbul", "it", "itau", "itv", "jaguar", "java", "jcb", "je", "jeep", "jetzt", "jewelry", "jio", "jll", "jm", "jmp", "jnj", "jo", "jobs", "joburg", "jot", "joy", "jp", "jpmorgan", "jprs", "juegos", "juniper", "kaufen", "kddi", "ke", "kerryhotels", "kerryproperties", "kfh", "kg", "kh", "ki", "kia", "kids", "kim", "kindle", "kitchen", "kiwi", "km", "kn", "koeln", "komatsu", "kosher", "kp", "kpmg", "kpn", "kr", "krd", "kred", "kuokgroup", "kw", "ky", "kyoto", "kz", "la", "lacaixa", "lamborghini", "lamer", "land", "landrover", "lanxess", "lasalle", "lat", "latino", "latrobe", "law", "lawyer", "lb", "lc", "lds", "lease", "leclerc", "lefrak", "legal", "lego", "lexus", "lgbt", "li", "lidl", "life", "lifeinsurance", "lifestyle", "lighting", "like", "lilly", "limited", "limo", "lincoln", "link", "live", "living", "lk", "llc", "llp", "loan", "loans", "locker", "locus", "lol", "london", "lotte", "lotto", "love", "lpl", "lplfinancial", "lr", "ls", "lt", "ltd", "ltda", "lu", "lundbeck", "luxe", "luxury", "lv", "ly", "ma", "madrid", "maif", "maison", "makeup", "man", "management", "mango", "map", "market", "marketing", "markets", "marriott", "marshalls", "mattel", "mba", "mc", "mckinsey", "md", "me", "med", "media", "meet", "melbourne", "meme", "memorial", "men", "menu", "merck", "merckmsd", "mg", "mh", "miami", "microsoft", "mil", "mini", "mint", "mit", "mitsubishi", "mk", "ml", "mlb", "mls", "mm", "mma", "mn", "mo", "mobi", "mobile", "moda", "moe", "moi", "mom", "monash", "money", "monster", "mormon", "mortgage", "moscow", "moto", "motorcycles", "mov", "movie", "mp", "mq", "mr", "ms", "msd", "mt", "mtn", "mtr", "mu", "museum", "music", "mv", "mw", "mx", "my", "mz", "na", "nab", "nagoya", "name", "navy", "nba", "nc", "ne", "nec", "net", "netbank", "netflix", "network", "neustar", "new", "news", "next", "nextdirect", "nexus", "nf", "nfl", "ng", "ngo", "nhk", "ni", "nico", "nike", "nikon", "ninja", "nissan", "nissay", "nl", "no", "nokia", "norton", "now", "nowruz", "nowtv", "np", "nr", "nra", "nrw", "ntt", "nu", "nyc", "nz", "obi", "observer", "office", "okinawa", "olayan", "olayangroup", "ollo", "om", "omega", "one", "ong", "onl", "online", "ooo", "open", "oracle", "orange", "org", "organic", "origins", "osaka", "otsuka", "ott", "ovh", "pa", "page", "panasonic", "paris", "pars", "partners", "parts", "party", "pay", "pccw", "pe", "pet", "pf", "pfizer", "pg", "ph", "pharmacy", "phd", "philips", "phone", "photo", "photography", "photos", "physio", "pics", "pictet", "pictures", "pid", "pin", "ping", "pink", "pioneer", "pizza", "pk", "pl", "place", "play", "playstation", "plumbing", "plus", "pm", "pn", "pnc", "pohl", "poker", "politie", "porn", "post", "pr", "praxi", "press", "prime", "pro", "prod", "productions", "prof", "progressive", "promo", "properties", "property", "protection", "pru", "prudential", "ps", "pt", "pub", "pw", "pwc", "py", "qa", "qpon", "quebec", "quest", "racing", "radio", "re", "read", "realestate", "realtor", "realty", "recipes", "red", "redumbrella", "rehab", "reise", "reisen", "reit", "reliance", "ren", "rent", "rentals", "repair", "report", "republican", "rest", "restaurant", "review", "reviews", "rexroth", "rich", "richardli", "ricoh", "ril", "rio", "rip", "ro", "rocks", "rodeo", "rogers", "room", "rs", "rsvp", "ru", "rugby", "ruhr", "run", "rw", "rwe", "ryukyu", "sa", "saarland", "safe", "safety", "sakura", "sale", "salon", "samsclub", "samsung", "sandvik", "sandvikcoromant", "sanofi", "sap", "sarl", "sas", "save", "saxo", "sb", "sbi", "sbs", "sc", "scb", "schaeffler", "schmidt", "scholarships", "school", "schule", "schwarz", "science", "scot", "sd", "se", "search", "seat", "secure", "security", "seek", "select", "sener", "services", "seven", "sew", "sex", "sexy", "sfr", "sg", "sh", "shangrila", "sharp", "shell", "shia", "shiksha", "shoes", "shop", "shopping", "shouji", "show", "si", "silk", "sina", "singles", "site", "sj", "sk", "ski", "skin", "sky", "skype", "sl", "sling", "sm", "smart", "smile", "sn", "sncf", "so", "soccer", "social", "softbank", "software", "sohu", "solar", "solutions", "song", "sony", "soy", "spa", "space", "sport", "spot", "sr", "srl", "ss", "st", "stada", "staples", "star", "statebank", "statefarm", "stc", "stcgroup", "stockholm", "storage", "store", "stream", "studio", "study", "style", "su", "sucks", "supplies", "supply", "support", "surf", "surgery", "suzuki", "sv", "swatch", "swiss", "sx", "sy", "sydney", "systems", "sz", "tab", "taipei", "talk", "taobao", "target", "tatamotors", "tatar", "tattoo", "tax", "taxi", "tc", "tci", "td", "tdk", "team", "tech", "technology", "tel", "temasek", "tennis", "teva", "tf", "tg", "th", "thd", "theater", "theatre", "tiaa", "tickets", "tienda", "tips", "tires", "tirol", "tj", "tjmaxx", "tjx", "tk", "tkmaxx", "tl", "tm", "tmall", "tn", "to", "today", "tokyo", "tools", "top", "toray", "toshiba", "total", "tours", "town", "toyota", "toys", "tr", "trade", "trading", "training", "travel", "travelers", "travelersinsurance", "trust", "trv", "tt", "tube", "tui", "tunes", "tushu", "tv", "tvs", "tw", "tz", "ua", "ubank", "ubs", "ug", "uk", "unicom", "university", "uno", "uol", "ups", "us", "uy", "uz", "va", "vacations", "vana", "vanguard", "vc", "ve", "vegas", "ventures", "verisign", "versicherung", "vet", "vg", "vi", "viajes", "video", "vig", "viking", "villas", "vin", "vip", "virgin", "visa", "vision", "viva", "vivo", "vlaanderen", "vn", "vodka", "volvo", "vote", "voting", "voto", "voyage", "vu", "wales", "walmart", "walter", "wang", "wanggou", "watch", "watches", "weather", "weatherchannel", "webcam", "weber", "website", "wed", "wedding", "weibo", "weir", "wf", "whoswho", "wien", "wiki", "williamhill", "win", "windows", "wine", "winners", "wme", "woodside", "work", "works", "world", "wow", "ws", "wtc", "wtf", "xbox", "xerox", "xihuan", "xin", "xn--11b4c3d", "xn--1ck2e1b", "xn--1qqw23a", "xn--2scrj9c", "xn--30rr7y", "xn--3bst00m", "xn--3ds443g", "xn--3e0b707e", "xn--3hcrj9c", "xn--3pxu8k", "xn--42c2d9a", "xn--45br5cyl", "xn--45brj9c", "xn--45q11c", "xn--4dbrk0ce", "xn--4gbrim", "xn--54b7fta0cc", "xn--55qw42g", "xn--55qx5d", "xn--5su34j936bgsg", "xn--5tzm5g", "xn--6frz82g", "xn--6qq986b3xl", "xn--80adxhks", "xn--80ao21a", "xn--80aqecdr1a", "xn--80asehdb", "xn--80aswg", "xn--8y0a063a", "xn--90a3ac", "xn--90ae", "xn--90ais", "xn--9dbq2a", "xn--9et52u", "xn--9krt00a", "xn--b4w605ferd", "xn--bck1b9a5dre4c", "xn--c1avg", "xn--c2br7g", "xn--cck2b3b", "xn--cckwcxetd", "xn--cg4bki", "xn--clchc0ea0b2g2a9gcd", "xn--czr694b", "xn--czrs0t", "xn--czru2d", "xn--d1acj3b", "xn--d1alf", "xn--e1a4c", "xn--eckvdtc9d", "xn--efvy88h", "xn--fct429k", "xn--fhbei", "xn--fiq228c5hs", "xn--fiq64b", "xn--fiqs8s", "xn--fiqz9s", "xn--fjq720a", "xn--flw351e", "xn--fpcrj9c3d", "xn--fzc2c9e2c", "xn--fzys8d69uvgm", "xn--g2xx48c", "xn--gckr3f0f", "xn--gecrj9c", "xn--gk3at1e", "xn--h2breg3eve", "xn--h2brj9c", "xn--h2brj9c8c", "xn--hxt814e", "xn--i1b6b1a6a2e", "xn--imr513n", "xn--io0a7i", "xn--j1aef", "xn--j1amh", "xn--j6w193g", "xn--jlq480n2rg", "xn--jvr189m", "xn--kcrx77d1x4a", "xn--kprw13d", "xn--kpry57d", "xn--kput3i", "xn--l1acc", "xn--lgbbat1ad8j", "xn--mgb9awbf", "xn--mgba3a3ejt", "xn--mgba3a4f16a", "xn--mgba7c0bbn0a", "xn--mgbaam7a8h", "xn--mgbab2bd", "xn--mgbah1a3hjkrd", "xn--mgbai9azgqp6j", "xn--mgbayh7gpa", "xn--mgbbh1a", "xn--mgbbh1a71e", "xn--mgbc0a9azcg", "xn--mgbca7dzdo", "xn--mgbcpq6gpa1a", "xn--mgberp4a5d4ar", "xn--mgbgu82a", "xn--mgbi4ecexp", "xn--mgbpl2fh", "xn--mgbt3dhd", "xn--mgbtx2b", "xn--mgbx4cd0ab", "xn--mix891f", "xn--mk1bu44c", "xn--mxtq1m", "xn--ngbc5azd", "xn--ngbe9e0a", "xn--ngbrx", "xn--node", "xn--nqv7f", "xn--nqv7fs00ema", "xn--nyqy26a", "xn--o3cw4h", "xn--ogbpf8fl", "xn--otu796d", "xn--p1acf", "xn--p1ai", "xn--pgbs0dh", "xn--pssy2u", "xn--q7ce6a", "xn--q9jyb4c", "xn--qcka1pmc", "xn--qxa6a", "xn--qxam", "xn--rhqv96g", "xn--rovu88b", "xn--rvc1e0am3e", "xn--s9brj9c", "xn--ses554g", "xn--t60b56a", "xn--tckwe", "xn--tiq49xqyj", "xn--unup4y", "xn--vermgensberater-ctb", "xn--vermgensberatung-pwb", "xn--vhquv", "xn--vuq861b", "xn--w4r85el8fhu5dnra", "xn--w4rs40l", "xn--wgbh1c", "xn--wgbl6a", "xn--xhq521b", "xn--xkc2al3hye2a", "xn--xkc2dl3a5ee0h", "xn--y9a3aq", "xn--yfro4i67o", "xn--ygbi2ammx", "xn--zfr164b", "xxx", "xyz", "yachts", "yahoo", "yamaxun", "yandex", "ye", "yodobashi", "yoga", "yokohama", "you", "youtube", "yt", "yun", "za", "zappos", "zara", "zero", "zip", "zm", "zone", "zuerich", "zw"];
|
|
634
743
|
|
|
@@ -1227,6 +1336,225 @@ function validateAadhaar(input) {
|
|
|
1227
1336
|
return { ...base, valid: ok, errors: ok ? [] : ["Checksum failed (Verhoeff)."] };
|
|
1228
1337
|
}
|
|
1229
1338
|
|
|
1339
|
+
// ../national-id/dist/italy.js
|
|
1340
|
+
var ODD = [1, 0, 5, 7, 9, 13, 15, 17, 19, 21, 2, 4, 18, 20, 11, 3, 6, 8, 12, 14, 16, 10, 22, 25, 24, 23];
|
|
1341
|
+
var cval = (c) => c >= "0" && c <= "9" ? c.charCodeAt(0) - 48 : c.charCodeAt(0) - 65;
|
|
1342
|
+
function validateCodiceFiscale(input) {
|
|
1343
|
+
const s = input.toUpperCase().replace(/\s/g, "");
|
|
1344
|
+
const base = {
|
|
1345
|
+
input,
|
|
1346
|
+
normalized: s,
|
|
1347
|
+
valid: false,
|
|
1348
|
+
country: "IT",
|
|
1349
|
+
idType: "Codice Fiscale",
|
|
1350
|
+
errors: []
|
|
1351
|
+
};
|
|
1352
|
+
if (!/^[A-Z0-9]{15}[A-Z]$/.test(s)) {
|
|
1353
|
+
return { ...base, errors: ["Codice Fiscale must be 15 alphanumerics followed by a letter check character."] };
|
|
1354
|
+
}
|
|
1355
|
+
let sum = 0;
|
|
1356
|
+
for (let i = 0; i < 15; i++) {
|
|
1357
|
+
const v = cval(s[i]);
|
|
1358
|
+
sum += i % 2 === 0 ? ODD[v] : v;
|
|
1359
|
+
}
|
|
1360
|
+
const expected = String.fromCharCode(65 + sum % 26);
|
|
1361
|
+
const ok = expected === s[15];
|
|
1362
|
+
return { ...base, valid: ok, errors: ok ? [] : [`Check character failed (mod-26): expected '${expected}'.`] };
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
// ../national-id/dist/poland.js
|
|
1366
|
+
function validatePesel(input) {
|
|
1367
|
+
const clean = input.replace(/\D/g, "");
|
|
1368
|
+
const base = { input, normalized: clean, valid: false, country: "PL", idType: "PESEL", errors: [] };
|
|
1369
|
+
if (clean.length !== 11)
|
|
1370
|
+
return { ...base, errors: ["PESEL must be 11 digits."] };
|
|
1371
|
+
const d = clean.split("").map(Number);
|
|
1372
|
+
const w = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3];
|
|
1373
|
+
let sum = 0;
|
|
1374
|
+
for (let i = 0; i < 10; i++)
|
|
1375
|
+
sum += w[i] * d[i];
|
|
1376
|
+
const check = (10 - sum % 10) % 10;
|
|
1377
|
+
const ok = check === d[10];
|
|
1378
|
+
return { ...base, valid: ok, errors: ok ? [] : ["Checksum failed (PESEL weighted mod-10)."] };
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
// ../national-id/dist/netherlands.js
|
|
1382
|
+
function validateBsn(input) {
|
|
1383
|
+
let clean = input.replace(/\D/g, "");
|
|
1384
|
+
if (clean.length === 8)
|
|
1385
|
+
clean = "0" + clean;
|
|
1386
|
+
const base = { input, normalized: clean, valid: false, country: "NL", idType: "BSN", errors: [] };
|
|
1387
|
+
if (!/^\d{9}$/.test(clean))
|
|
1388
|
+
return { ...base, errors: ["BSN must be 8 or 9 digits."] };
|
|
1389
|
+
const d = clean.split("").map(Number);
|
|
1390
|
+
if (d.every((x) => x === 0))
|
|
1391
|
+
return { ...base, errors: ["Invalid BSN (all zeros)."] };
|
|
1392
|
+
let sum = 0;
|
|
1393
|
+
for (let i = 0; i < 8; i++)
|
|
1394
|
+
sum += (9 - i) * d[i];
|
|
1395
|
+
sum -= d[8];
|
|
1396
|
+
const ok = sum % 11 === 0;
|
|
1397
|
+
return { ...base, valid: ok, errors: ok ? [] : ["Checksum failed (BSN 11-test)."] };
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
// ../national-id/dist/belgium.js
|
|
1401
|
+
function validateBeNrn(input) {
|
|
1402
|
+
const clean = input.replace(/\D/g, "");
|
|
1403
|
+
const base = {
|
|
1404
|
+
input,
|
|
1405
|
+
normalized: clean,
|
|
1406
|
+
valid: false,
|
|
1407
|
+
country: "BE",
|
|
1408
|
+
idType: "National Register Number",
|
|
1409
|
+
errors: []
|
|
1410
|
+
};
|
|
1411
|
+
if (clean.length !== 11)
|
|
1412
|
+
return { ...base, errors: ["Belgian NRN must be 11 digits."] };
|
|
1413
|
+
const d = clean.split("").map(Number);
|
|
1414
|
+
const last2 = d[9] * 10 + d[10];
|
|
1415
|
+
const baseNum = Number(clean.slice(0, 9));
|
|
1416
|
+
const c19 = 97 - baseNum % 97;
|
|
1417
|
+
const c20 = 97 - (2e9 + baseNum) % 97;
|
|
1418
|
+
const ok = last2 === c19 || last2 === c20;
|
|
1419
|
+
return { ...base, valid: ok, errors: ok ? [] : ["Checksum failed (NRN mod-97)."] };
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
// ../national-id/dist/portugal.js
|
|
1423
|
+
function validateNifPt(input) {
|
|
1424
|
+
const clean = input.replace(/\D/g, "");
|
|
1425
|
+
const base = { input, normalized: clean, valid: false, country: "PT", idType: "NIF", errors: [] };
|
|
1426
|
+
if (clean.length !== 9)
|
|
1427
|
+
return { ...base, errors: ["Portuguese NIF must be 9 digits."] };
|
|
1428
|
+
const d = clean.split("").map(Number);
|
|
1429
|
+
let sum = 0;
|
|
1430
|
+
for (let i = 0; i < 8; i++)
|
|
1431
|
+
sum += d[i] * (9 - i);
|
|
1432
|
+
const r = sum % 11;
|
|
1433
|
+
const check = r < 2 ? 0 : 11 - r;
|
|
1434
|
+
const ok = check === d[8];
|
|
1435
|
+
return { ...base, valid: ok, errors: ok ? [] : ["Checksum failed (NIF mod-11)."] };
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
// ../national-id/dist/turkey.js
|
|
1439
|
+
function validateTckn(input) {
|
|
1440
|
+
const clean = input.replace(/\D/g, "");
|
|
1441
|
+
const base = { input, normalized: clean, valid: false, country: "TR", idType: "TCKN", errors: [] };
|
|
1442
|
+
if (clean.length !== 11)
|
|
1443
|
+
return { ...base, errors: ["TCKN must be 11 digits."] };
|
|
1444
|
+
const d = clean.split("").map(Number);
|
|
1445
|
+
if (d[0] === 0)
|
|
1446
|
+
return { ...base, errors: ["TCKN cannot start with 0."] };
|
|
1447
|
+
const odd = d[0] + d[2] + d[4] + d[6] + d[8];
|
|
1448
|
+
const even = d[1] + d[3] + d[5] + d[7];
|
|
1449
|
+
const d10 = ((odd * 7 - even) % 10 + 10) % 10;
|
|
1450
|
+
let sum = 0;
|
|
1451
|
+
for (let i = 0; i < 10; i++)
|
|
1452
|
+
sum += d[i];
|
|
1453
|
+
const d11 = sum % 10;
|
|
1454
|
+
const ok = d10 === d[9] && d11 === d[10];
|
|
1455
|
+
return { ...base, valid: ok, errors: ok ? [] : ["Checksum failed (TCKN check digits)."] };
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
// ../national-id/dist/china.js
|
|
1459
|
+
function validateChinaRic(input) {
|
|
1460
|
+
const s = input.toUpperCase().replace(/\s/g, "");
|
|
1461
|
+
const base = {
|
|
1462
|
+
input,
|
|
1463
|
+
normalized: s,
|
|
1464
|
+
valid: false,
|
|
1465
|
+
country: "CN",
|
|
1466
|
+
idType: "Resident Identity Card",
|
|
1467
|
+
errors: []
|
|
1468
|
+
};
|
|
1469
|
+
if (!/^\d{17}[0-9X]$/.test(s)) {
|
|
1470
|
+
return { ...base, errors: ["Chinese ID must be 17 digits followed by a check character (0-9 or X)."] };
|
|
1471
|
+
}
|
|
1472
|
+
const w = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
|
|
1473
|
+
const map = "10X98765432";
|
|
1474
|
+
let sum = 0;
|
|
1475
|
+
for (let i = 0; i < 17; i++)
|
|
1476
|
+
sum += w[i] * (s.charCodeAt(i) - 48);
|
|
1477
|
+
const expected = map[sum % 11];
|
|
1478
|
+
const ok = expected === s[17];
|
|
1479
|
+
return { ...base, valid: ok, errors: ok ? [] : [`Check character failed (ISO 7064 MOD 11-2): expected '${expected}'.`] };
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
// ../national-id/dist/nordics.js
|
|
1483
|
+
function validatePersonnummer(input) {
|
|
1484
|
+
const digits2 = input.replace(/[+\-\s]/g, "");
|
|
1485
|
+
const base = {
|
|
1486
|
+
input,
|
|
1487
|
+
normalized: digits2,
|
|
1488
|
+
valid: false,
|
|
1489
|
+
country: "SE",
|
|
1490
|
+
idType: "Personnummer",
|
|
1491
|
+
errors: []
|
|
1492
|
+
};
|
|
1493
|
+
if (!/^\d{10}$|^\d{12}$/.test(digits2))
|
|
1494
|
+
return { ...base, errors: ["Personnummer must be 10 or 12 digits."] };
|
|
1495
|
+
const ten = digits2.length === 12 ? digits2.slice(2) : digits2;
|
|
1496
|
+
const d = ten.split("").map(Number);
|
|
1497
|
+
let sum = 0;
|
|
1498
|
+
let dbl = true;
|
|
1499
|
+
for (let i = 0; i < 10; i++) {
|
|
1500
|
+
let x = d[i];
|
|
1501
|
+
if (dbl) {
|
|
1502
|
+
x *= 2;
|
|
1503
|
+
if (x > 9)
|
|
1504
|
+
x -= 9;
|
|
1505
|
+
}
|
|
1506
|
+
sum += x;
|
|
1507
|
+
dbl = !dbl;
|
|
1508
|
+
}
|
|
1509
|
+
const ok = sum % 10 === 0;
|
|
1510
|
+
return { ...base, valid: ok, errors: ok ? [] : ["Checksum failed (Luhn)."] };
|
|
1511
|
+
}
|
|
1512
|
+
function validateFodselsnummer(input) {
|
|
1513
|
+
const clean = input.replace(/\D/g, "");
|
|
1514
|
+
const base = {
|
|
1515
|
+
input,
|
|
1516
|
+
normalized: clean,
|
|
1517
|
+
valid: false,
|
|
1518
|
+
country: "NO",
|
|
1519
|
+
idType: "F\xF8dselsnummer",
|
|
1520
|
+
errors: []
|
|
1521
|
+
};
|
|
1522
|
+
if (clean.length !== 11)
|
|
1523
|
+
return { ...base, errors: ["F\xF8dselsnummer must be 11 digits."] };
|
|
1524
|
+
const d = clean.split("").map(Number);
|
|
1525
|
+
const w1 = [3, 7, 6, 1, 8, 9, 4, 5, 2];
|
|
1526
|
+
let s1 = 0;
|
|
1527
|
+
for (let i = 0; i < 9; i++)
|
|
1528
|
+
s1 += w1[i] * d[i];
|
|
1529
|
+
let k1 = 11 - s1 % 11;
|
|
1530
|
+
if (k1 === 11)
|
|
1531
|
+
k1 = 0;
|
|
1532
|
+
if (k1 === 10 || k1 !== d[9])
|
|
1533
|
+
return { ...base, errors: ["First control digit failed (mod-11)."] };
|
|
1534
|
+
const w2 = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
|
|
1535
|
+
let s2 = 0;
|
|
1536
|
+
for (let i = 0; i < 9; i++)
|
|
1537
|
+
s2 += w2[i] * d[i];
|
|
1538
|
+
s2 += w2[9] * k1;
|
|
1539
|
+
let k2 = 11 - s2 % 11;
|
|
1540
|
+
if (k2 === 11)
|
|
1541
|
+
k2 = 0;
|
|
1542
|
+
const ok = k2 !== 10 && k2 === d[10];
|
|
1543
|
+
return { ...base, valid: ok, errors: ok ? [] : ["Second control digit failed (mod-11)."] };
|
|
1544
|
+
}
|
|
1545
|
+
var HETU = "0123456789ABCDEFHJKLMNPRSTUVWXY";
|
|
1546
|
+
function validateHetu(input) {
|
|
1547
|
+
const s = input.toUpperCase().trim();
|
|
1548
|
+
const base = { input, normalized: s, valid: false, country: "FI", idType: "Henkil\xF6tunnus", errors: [] };
|
|
1549
|
+
const m = s.match(/^(\d{6})([+\-A-FYXWVU])(\d{3})([0-9A-Y])$/);
|
|
1550
|
+
if (!m)
|
|
1551
|
+
return { ...base, errors: ["HETU must be DDMMYY + century sign + 3 digits + check character."] };
|
|
1552
|
+
const num = Number(m[1] + m[3]);
|
|
1553
|
+
const expected = HETU[num % 31];
|
|
1554
|
+
const ok = expected === m[4];
|
|
1555
|
+
return { ...base, valid: ok, errors: ok ? [] : [`Check character failed (mod-31): expected '${expected}'.`] };
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1230
1558
|
// ../academic/dist/isbn10.js
|
|
1231
1559
|
function validateIsbn10(input) {
|
|
1232
1560
|
const s = input.replace(/[\s-]/g, "").toUpperCase();
|
|
@@ -1758,6 +2086,27 @@ var TOOLS = [
|
|
|
1758
2086
|
argDescription: "The barcode digits (EAN-8/UPC-A/EAN-13/GTIN-14); spaces and hyphens are ignored.",
|
|
1759
2087
|
run: (v) => validateGtin(v)
|
|
1760
2088
|
},
|
|
2089
|
+
{
|
|
2090
|
+
name: "validate_imei",
|
|
2091
|
+
description: "USE THIS to verify a phone/device IMEI before relying on it \u2014 never assume a 15-digit string is valid or guess its check digit. Checks the Luhn check digit (and recognises the 16-digit IMEISV form), and returns the TAC (device-model code). Validates the number only \u2014 does NOT check whether the device is real, active, or blocklisted/stolen.",
|
|
2092
|
+
argName: "imei",
|
|
2093
|
+
argDescription: "The 15-digit IMEI (or 16-digit IMEISV); spaces and dashes are ignored.",
|
|
2094
|
+
run: (v) => validateImei(v)
|
|
2095
|
+
},
|
|
2096
|
+
{
|
|
2097
|
+
name: "validate_gln",
|
|
2098
|
+
description: "USE THIS to verify a GLN (GS1 Global Location Number \u2014 identifies a company/site/location in supply chains and EDI) before relying on it. Checks the 13-digit GS1 mod-10 check digit and returns the GS1 prefix's issuing country. Validates structure only; does not confirm the location is registered.",
|
|
2099
|
+
argName: "gln",
|
|
2100
|
+
argDescription: "The 13-digit GLN; spaces and dashes are ignored.",
|
|
2101
|
+
run: (v) => validateGln(v)
|
|
2102
|
+
},
|
|
2103
|
+
{
|
|
2104
|
+
name: "validate_sscc",
|
|
2105
|
+
description: "USE THIS to verify an SSCC (GS1 Serial Shipping Container Code \u2014 identifies a pallet/carton/logistics unit) from a shipping label before relying on it. Checks the 18-digit GS1 mod-10 check digit and returns the extension digit and GS1 prefix country. Validates structure only.",
|
|
2106
|
+
argName: "sscc",
|
|
2107
|
+
argDescription: "The 18-digit SSCC; spaces and dashes are ignored.",
|
|
2108
|
+
run: (v) => validateSscc(v)
|
|
2109
|
+
},
|
|
1761
2110
|
{
|
|
1762
2111
|
name: "validate_tld",
|
|
1763
2112
|
description: "USE THIS to check whether a top-level domain is real before trusting a domain or link \u2014 do NOT guess whether a TLD like .zip, .corp, .crypto or .web exists. Checks the suffix against the authoritative IANA root-zone list (kept current). Returns valid:false for TLDs that are not actually delegated.",
|
|
@@ -1884,6 +2233,76 @@ var TOOLS = [
|
|
|
1884
2233
|
argDescription: "The 12-digit Aadhaar number (spaces ignored).",
|
|
1885
2234
|
run: (v) => validateAadhaar(v)
|
|
1886
2235
|
},
|
|
2236
|
+
{
|
|
2237
|
+
name: "validate_codice_fiscale",
|
|
2238
|
+
description: "USE THIS to verify an Italian Codice Fiscale (personal tax code) before relying on it \u2014 do not guess the final check letter. Checks the 16-character format and the mod-26 check character. Validates structure only; does NOT confirm the code is registered with the Agenzia delle Entrate.",
|
|
2239
|
+
argName: "code",
|
|
2240
|
+
argDescription: "The 16-character Codice Fiscale (spaces ignored, case-insensitive).",
|
|
2241
|
+
run: (v) => validateCodiceFiscale(v)
|
|
2242
|
+
},
|
|
2243
|
+
{
|
|
2244
|
+
name: "validate_pesel",
|
|
2245
|
+
description: "USE THIS to verify a Polish PESEL (national identification number) before relying on it \u2014 never assume 11 digits are valid. Checks the weighted mod-10 check digit. Call this for KYC/onboarding of Polish individuals.",
|
|
2246
|
+
argName: "pesel",
|
|
2247
|
+
argDescription: "The 11-digit PESEL (spaces/dashes ignored).",
|
|
2248
|
+
run: (v) => validatePesel(v)
|
|
2249
|
+
},
|
|
2250
|
+
{
|
|
2251
|
+
name: "validate_bsn",
|
|
2252
|
+
description: "USE THIS to verify a Dutch BSN (burgerservicenummer / citizen service number) before relying on it. Checks the 8\u20139 digit form and the '11-test' (elfproef) checksum. Validates structure only; does NOT confirm the number is issued.",
|
|
2253
|
+
argName: "bsn",
|
|
2254
|
+
argDescription: "The 8- or 9-digit BSN (spaces/dots ignored).",
|
|
2255
|
+
run: (v) => validateBsn(v)
|
|
2256
|
+
},
|
|
2257
|
+
{
|
|
2258
|
+
name: "validate_be_nrn",
|
|
2259
|
+
description: "USE THIS to verify a Belgian National Register Number (Rijksregisternummer / Num\xE9ro de Registre National) before relying on it. Checks the 11-digit form and the mod-97 check (handling the born-from-2000 rule). Validates structure only.",
|
|
2260
|
+
argName: "nrn",
|
|
2261
|
+
argDescription: "The 11-digit Belgian National Register Number (punctuation ignored).",
|
|
2262
|
+
run: (v) => validateBeNrn(v)
|
|
2263
|
+
},
|
|
2264
|
+
{
|
|
2265
|
+
name: "validate_personnummer",
|
|
2266
|
+
description: "USE THIS to verify a Swedish personnummer (personal identity number) before relying on it \u2014 never assume the digits are valid. Accepts the 10- or 12-digit form and checks the Luhn check digit. Validates structure only; does NOT confirm the number is registered.",
|
|
2267
|
+
argName: "personnummer",
|
|
2268
|
+
argDescription: "The Swedish personnummer (10 or 12 digits; +/-/spaces ignored).",
|
|
2269
|
+
run: (v) => validatePersonnummer(v)
|
|
2270
|
+
},
|
|
2271
|
+
{
|
|
2272
|
+
name: "validate_fodselsnummer",
|
|
2273
|
+
description: "USE THIS to verify a Norwegian f\xF8dselsnummer (national identity number) before relying on it. Checks the 11-digit form and both mod-11 control digits. Validates structure only; does NOT confirm the number is registered.",
|
|
2274
|
+
argName: "fodselsnummer",
|
|
2275
|
+
argDescription: "The 11-digit Norwegian f\xF8dselsnummer (spaces ignored).",
|
|
2276
|
+
run: (v) => validateFodselsnummer(v)
|
|
2277
|
+
},
|
|
2278
|
+
{
|
|
2279
|
+
name: "validate_hetu",
|
|
2280
|
+
description: "USE THIS to verify a Finnish henkil\xF6tunnus (HETU / personal identity code) before relying on it \u2014 do not guess the check character. Checks the DDMMYY + century sign + individual number + mod-31 check character. Validates structure only.",
|
|
2281
|
+
argName: "hetu",
|
|
2282
|
+
argDescription: "The Finnish HETU, e.g. 131052-308T (case-insensitive).",
|
|
2283
|
+
run: (v) => validateHetu(v)
|
|
2284
|
+
},
|
|
2285
|
+
{
|
|
2286
|
+
name: "validate_nif_pt",
|
|
2287
|
+
description: "USE THIS to verify a Portuguese NIF (N\xFAmero de Identifica\xE7\xE3o Fiscal / tax number) before invoicing or onboarding \u2014 never assume 9 digits are valid. Checks the mod-11 check digit. For the Spanish tax ID use validate_dni.",
|
|
2288
|
+
argName: "nif",
|
|
2289
|
+
argDescription: "The 9-digit Portuguese NIF (spaces ignored).",
|
|
2290
|
+
run: (v) => validateNifPt(v)
|
|
2291
|
+
},
|
|
2292
|
+
{
|
|
2293
|
+
name: "validate_tckn",
|
|
2294
|
+
description: "USE THIS to verify a Turkish T.C. Kimlik No (TCKN / national identity number) before relying on it \u2014 never assume 11 digits are valid. Checks both algorithmic check digits and the leading-digit rule. Validates structure only; does NOT confirm the number is registered.",
|
|
2295
|
+
argName: "tckn",
|
|
2296
|
+
argDescription: "The 11-digit TCKN (spaces ignored).",
|
|
2297
|
+
run: (v) => validateTckn(v)
|
|
2298
|
+
},
|
|
2299
|
+
{
|
|
2300
|
+
name: "validate_china_ric",
|
|
2301
|
+
description: "USE THIS to verify a Chinese Resident Identity Card number (\u5C45\u6C11\u8EAB\u4EFD\u8BC1) before relying on it \u2014 do not guess the check character. Checks the 18-character form and the ISO 7064 MOD 11-2 check character (which may be 'X'). Validates structure only; does NOT confirm the number is registered.",
|
|
2302
|
+
argName: "id",
|
|
2303
|
+
argDescription: "The 18-character Chinese Resident ID (17 digits + check 0-9 or X).",
|
|
2304
|
+
run: (v) => validateChinaRic(v)
|
|
2305
|
+
},
|
|
1887
2306
|
{
|
|
1888
2307
|
name: "validate_isbn10",
|
|
1889
2308
|
description: "USE THIS to verify an ISBN-10 (older book identifier) instead of trusting 10 characters. Checks the mod-11 check digit (which may be 'X'). For 13-digit ISBNs use validate_isbn.",
|
|
@@ -1979,7 +2398,7 @@ var TOOLS = [
|
|
|
1979
2398
|
runArgs: (a) => validateVat(a.vat ?? "", a.country)
|
|
1980
2399
|
}
|
|
1981
2400
|
];
|
|
1982
|
-
var SERVER_INFO = { name: "qiniso", version: "0.
|
|
2401
|
+
var SERVER_INFO = { name: "qiniso", version: "0.4.0" };
|
|
1983
2402
|
var DEFAULT_PROTOCOL = "2025-06-18";
|
|
1984
2403
|
function argList(t) {
|
|
1985
2404
|
return t.args ?? [{ name: t.argName, description: t.argDescription }];
|
|
@@ -2070,6 +2489,9 @@ export {
|
|
|
2070
2489
|
gtinCheckDigit,
|
|
2071
2490
|
gs1Country,
|
|
2072
2491
|
validateGtin,
|
|
2492
|
+
validateImei,
|
|
2493
|
+
validateGln,
|
|
2494
|
+
validateSscc,
|
|
2073
2495
|
isKnownTld,
|
|
2074
2496
|
knownTldCount,
|
|
2075
2497
|
validateTld,
|
|
@@ -2094,6 +2516,16 @@ export {
|
|
|
2094
2516
|
verhoeffValid,
|
|
2095
2517
|
verhoeffGenerate,
|
|
2096
2518
|
validateAadhaar,
|
|
2519
|
+
validateCodiceFiscale,
|
|
2520
|
+
validatePesel,
|
|
2521
|
+
validateBsn,
|
|
2522
|
+
validateBeNrn,
|
|
2523
|
+
validateNifPt,
|
|
2524
|
+
validateTckn,
|
|
2525
|
+
validateChinaRic,
|
|
2526
|
+
validatePersonnummer,
|
|
2527
|
+
validateFodselsnummer,
|
|
2528
|
+
validateHetu,
|
|
2097
2529
|
validateIsbn10,
|
|
2098
2530
|
validateIssn,
|
|
2099
2531
|
validateOrcid,
|
package/dist/http.js
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -24,27 +24,40 @@ import {
|
|
|
24
24
|
supportedIbanCountries,
|
|
25
25
|
validateAadhaar,
|
|
26
26
|
validateAba,
|
|
27
|
+
validateBeNrn,
|
|
28
|
+
validateBsn,
|
|
27
29
|
validateBtcAddress,
|
|
28
30
|
validateCard,
|
|
31
|
+
validateChinaRic,
|
|
29
32
|
validateCnpj,
|
|
33
|
+
validateCodiceFiscale,
|
|
30
34
|
validateCpf,
|
|
31
35
|
validateCusip,
|
|
32
36
|
validateDni,
|
|
33
37
|
validateDomain,
|
|
34
38
|
validateEmail,
|
|
35
39
|
validateEthAddress,
|
|
40
|
+
validateFodselsnummer,
|
|
41
|
+
validateGln,
|
|
36
42
|
validateGtin,
|
|
43
|
+
validateHetu,
|
|
37
44
|
validateIban,
|
|
45
|
+
validateImei,
|
|
38
46
|
validateIp,
|
|
39
47
|
validateIsbn10,
|
|
40
48
|
validateIsbn13,
|
|
41
49
|
validateIsin,
|
|
42
50
|
validateIssn,
|
|
43
51
|
validateLei,
|
|
52
|
+
validateNifPt,
|
|
44
53
|
validateOrcid,
|
|
54
|
+
validatePersonnummer,
|
|
55
|
+
validatePesel,
|
|
45
56
|
validatePhone,
|
|
46
57
|
validateSaId,
|
|
47
58
|
validateSedol,
|
|
59
|
+
validateSscc,
|
|
60
|
+
validateTckn,
|
|
48
61
|
validateTld,
|
|
49
62
|
validateUrl,
|
|
50
63
|
validateUuid,
|
|
@@ -54,7 +67,7 @@ import {
|
|
|
54
67
|
verhoeffGenerate,
|
|
55
68
|
verhoeffValid,
|
|
56
69
|
vinCheckDigit
|
|
57
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-RMLPG7ZB.js";
|
|
58
71
|
export {
|
|
59
72
|
SERVER_INFO,
|
|
60
73
|
TOOLS,
|
|
@@ -81,27 +94,40 @@ export {
|
|
|
81
94
|
supportedIbanCountries,
|
|
82
95
|
validateAadhaar,
|
|
83
96
|
validateAba,
|
|
97
|
+
validateBeNrn,
|
|
98
|
+
validateBsn,
|
|
84
99
|
validateBtcAddress,
|
|
85
100
|
validateCard,
|
|
101
|
+
validateChinaRic,
|
|
86
102
|
validateCnpj,
|
|
103
|
+
validateCodiceFiscale,
|
|
87
104
|
validateCpf,
|
|
88
105
|
validateCusip,
|
|
89
106
|
validateDni,
|
|
90
107
|
validateDomain,
|
|
91
108
|
validateEmail,
|
|
92
109
|
validateEthAddress,
|
|
110
|
+
validateFodselsnummer,
|
|
111
|
+
validateGln,
|
|
93
112
|
validateGtin,
|
|
113
|
+
validateHetu,
|
|
94
114
|
validateIban,
|
|
115
|
+
validateImei,
|
|
95
116
|
validateIp,
|
|
96
117
|
validateIsbn10,
|
|
97
118
|
validateIsbn13,
|
|
98
119
|
validateIsin,
|
|
99
120
|
validateIssn,
|
|
100
121
|
validateLei,
|
|
122
|
+
validateNifPt,
|
|
101
123
|
validateOrcid,
|
|
124
|
+
validatePersonnummer,
|
|
125
|
+
validatePesel,
|
|
102
126
|
validatePhone,
|
|
103
127
|
validateSaId,
|
|
104
128
|
validateSedol,
|
|
129
|
+
validateSscc,
|
|
130
|
+
validateTckn,
|
|
105
131
|
validateTld,
|
|
106
132
|
validateUrl,
|
|
107
133
|
validateUuid,
|
package/dist/server.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qinisolabs/qiniso",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"mcpName": "io.github.qinisolabs/qiniso",
|
|
5
5
|
"description": "The deterministic fact-verification layer for AI agents — verify identifiers, locale and more against authoritative ground truth.",
|
|
6
6
|
"homepage": "https://qinisolabs.github.io/qiniso/",
|
|
@@ -48,7 +48,12 @@
|
|
|
48
48
|
"upc",
|
|
49
49
|
"ean",
|
|
50
50
|
"iban",
|
|
51
|
-
"vat"
|
|
51
|
+
"vat",
|
|
52
|
+
"national-id",
|
|
53
|
+
"kyc",
|
|
54
|
+
"pesel",
|
|
55
|
+
"codice-fiscale",
|
|
56
|
+
"tckn"
|
|
52
57
|
],
|
|
53
58
|
"license": "Apache-2.0",
|
|
54
59
|
"author": "Qiniso",
|