getPlaceByIranNationalId — city/province lookup by ID prefix
import { getPlaceByIranNationalId } from "@persian-tools/persian-tools";
// CommonJS
const { getPlaceByIranNationalId } = require("@persian-tools/persian-tools");
Public exports
getPlaceByIranNationalId(nationalId?: string): IPlaceByNationalId | null | undefined
interface IPlaceByNationalId {
codes: number[] | string[]; // all 3-digit codes that map to this city
city: string;
province: string;
}
interface IProvince { code: number | string; city: string }
interface INationalId extends IProvince { parentCode: number }
The lookup tables live in nationalId.skip.ts and provincesCodes.skip.ts (heavy datasets, kept under the .skip.ts convention so reviewers know they're data files).
Behaviour
import { getPlaceByIranNationalId } from "@persian-tools/persian-tools";
getPlaceByIranNationalId("0084575948");
// { codes: [...], city: "تهران مرکزی", province: "تهران" }
getPlaceByIranNationalId("0000000000");
// null — prefix "000" not in the dataset
getPlaceByIranNationalId(undefined);
// undefined — falsy short-circuit
getPlaceByIranNationalId("");
// undefined
Algorithm
- Falsy input →
undefined. - Length must be exactly 10 (
src/modules/getPlaceByIranNationalId/index.ts). Anything else → falls through, returnsundefined. - Slice the first 3 characters as the prefix.
- Filter
NationalIdJSONrows whose stringified code includes the prefix; pick the first match. - Resolve the parent province via
ProvincesJSON.code === match.parentCode. - Return
{ codes, city, province };provincefalls back to"unknown"if the parent code is not found.
Important caveats
This function does NOT validate the checksum. A nonsense ID like
"1234567890"(which failsverifyIranianNationalId) may still return a validIPlaceByNationalIdbecause the prefix"123"exists in the dataset. Always pair withverifyIranianNationalIdif validity matters.import { verifyIranianNationalId, getPlaceByIranNationalId } from "@persian-tools/persian-tools"; const safeLookup = (id: string) => verifyIranianNationalId(id) ? getPlaceByIranNationalId(id) : null;No digit normalization. Persian/Arabic digit input (
"۰۰۸۴۵۷۵۹۴۸") hits the.substring(0,3)directly and the resulting prefix ("۰۰۸"etc.) isn't in the English-digit-keyed dataset →null. Normalize withautoConvertDigitsToENfirst.Return type is
IPlaceByNationalId | null | undefined.undefined= couldn't even start (falsy input);null= ran, prefix not found.
Common pitfalls
- Don't use this as a validator. It's a lookup, not a check. Use
verifyIranianNationalIdfor validation. province === "unknown"is a real return, not an error — it means the prefix matched a city whose parent code is missing from the provinces table. Surface gracefully in UI.- Adding new prefixes: edit
nationalId.skip.tsandprovincesCodes.skip.ts, then re-run the test suite. Both the validator'svalidNationalIdPrefixesand this lookup should stay in sync — see thenationalIdskill.
References
- Tests:
test/getPlaceByIranNationalId.spec.ts - Related:
nationalIdskill (for the checksum validator)