iraqi-data 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Karam Al-Dulaimi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.ar.md ADDED
@@ -0,0 +1,159 @@
1
+ # iraqi-data
2
+
3
+ [English](README.md) | **العربية**
4
+
5
+ [![npm version](https://img.shields.io/npm/v/iraqi-data.svg)](https://www.npmjs.com/package/iraqi-data)
6
+ [![CI](https://github.com/karam-fikre/iraqi-data/actions/workflows/ci.yml/badge.svg)](https://github.com/karam-fikre/iraqi-data/actions/workflows/ci.yml)
7
+ [![license](https://img.shields.io/npm/l/iraqi-data.svg)](LICENSE)
8
+
9
+ محافظات العراق بالعربية والإنجليزية والكردية، جاهزة لنماذج العناوين والقوائم المنسدلة وتطبيقات التوصيل. البحث يفهم الطرق المختلفة التي يكتب بها الناس اسم المكان نفسه: `البصرة` و `البصره` و `Basrah` و `بەسرە` كلها تجد البصرة.
10
+
11
+ يعمل في **Node.js** و**المتصفح** و **React** و **React Native / Expo** و **Vue**، ويأتي مع أنواع TypeScript، وبلا أي اعتماديات.
12
+
13
+ ## التثبيت
14
+
15
+ ```bash
16
+ npm install iraqi-data
17
+ # أو
18
+ yarn add iraqi-data
19
+ ```
20
+
21
+ ## الاستخدام
22
+
23
+ ```ts
24
+ import { governorates, getGovernorate, searchGovernorates } from 'iraqi-data';
25
+ // CommonJS: const { governorates, getGovernorate } = require('iraqi-data');
26
+
27
+ getGovernorate('Basrah');
28
+ // {
29
+ // id: 'basra',
30
+ // iso: 'IQ-BA',
31
+ // ar: 'البصرة',
32
+ // en: 'Basra',
33
+ // ku: 'بەسرە',
34
+ // region: 'federal',
35
+ // capital: { ar: 'البصرة', en: 'Basra' },
36
+ // aliases: ['Basrah']
37
+ // }
38
+
39
+ getGovernorate('هولير')?.ar; // 'أربيل'
40
+ getGovernorate('IQ-NI')?.capital.ar; // 'الموصل'
41
+
42
+ searchGovernorates('نجف').map((g) => g.ar); // ['النجف']
43
+ searchGovernorates('ba').map((g) => g.ar); // ['بغداد', 'البصرة', 'بابل', 'الأنبار', 'كربلاء']
44
+ ```
45
+
46
+ ### مثال قائمة منسدلة (React)
47
+
48
+ ```tsx
49
+ import { governorates } from 'iraqi-data';
50
+
51
+ export function GovernorateSelect({ value, onChange }) {
52
+ return (
53
+ <select value={value} onChange={(e) => onChange(e.target.value)}>
54
+ {governorates.map((g) => (
55
+ <option key={g.id} value={g.id}>{g.ar}</option>
56
+ ))}
57
+ </select>
58
+ );
59
+ }
60
+ ```
61
+
62
+ احفظ الـ `id` ‏(`'baghdad'` و `'basra'` …) في قاعدة بياناتك، وليس الاسم المعروض. الـ `id` لا يتغير أبداً، أما تهجئة الاسم فقد تُصحَّح في إصدار لاحق.
63
+
64
+ ## الواجهة البرمجية (API)
65
+
66
+ ### `governorates: readonly Governorate[]`
67
+
68
+ كل المحافظات الـ 19: المحافظات الـ 15 في العراق الاتحادي، ثم المحافظات الـ 4 في إقليم كردستان. المصفوفة وعناصرها مجمّدة ولا يمكن تعديلها.
69
+
70
+ ```ts
71
+ interface Governorate {
72
+ id: string; // معرّف ثابت للحفظ: 'baghdad'
73
+ iso: string | null; // رمز ISO 3166-2: 'IQ-BG' (‏null لحلبجة لأنها بلا رمز بعد)
74
+ ar: string; // الاسم بالعربية
75
+ en: string; // الاسم بالإنجليزية
76
+ ku: string; // الاسم بالكردية (السورانية)
77
+ region: 'federal' | 'kurdistan';
78
+ capital: { ar: string; en: string }; // مركز المحافظة
79
+ aliases: string[]; // تهجئات أخرى: 'Basrah' و 'Arbil' و 'Hawler'
80
+ }
81
+ ```
82
+
83
+ ### `getGovernorate(query: string): Governorate | undefined`
84
+
85
+ تجد محافظة واحدة بالـ `id` أو رمز ISO أو اسمها الكامل بأي لغة، بما في ذلك التهجئات الأخرى. تُرجع `undefined` إذا لم تجد شيئاً. الأسماء الناقصة لا تُطابَق؛ استخدم `searchGovernorates` لها.
86
+
87
+ ### `searchGovernorates(query: string): Governorate[]`
88
+
89
+ تجد كل محافظة يحتوي اسمها على نص البحث، للإكمال التلقائي. المطابقات التامة أولاً، ثم الأسماء التي تبدأ بنص البحث، ثم البقية. البحث الفارغ يُرجع `[]`.
90
+
91
+ ### `getGovernoratesByRegion(region: 'federal' | 'kurdistan'): Governorate[]`
92
+
93
+ محافظات العراق الاتحادي أو محافظات إقليم كردستان.
94
+
95
+ ### `normalize(text: string): string`
96
+
97
+ الدالة التي يستخدمها البحث لمقارنة الأسماء. هي مُصدَّرة لتقارن بها قيمك المحفوظة بالطريقة نفسها.
98
+
99
+ | تتجاهل | مثال |
100
+ | --- | --- |
101
+ | أشكال الهمزة | `أ إ آ` ← `ا` |
102
+ | التاء المربوطة والألف المقصورة | `ة` ← `ه`، `ى` ← `ي` |
103
+ | التشكيل والتطويل | `البَصْرَة` ← `بصره` |
104
+ | أداة التعريف | `البصرة` و `Al-Basrah` و `As Sulaymaniyah` |
105
+ | الحروف الكردية المكتوبة بلوحة مفاتيح عربية | `سلێمانی` = `سليماني`، `دهۆک` = `دهوك` |
106
+ | حالة الأحرف والمسافات والشرطات | `Dhi Qar` = `dhiqar` |
107
+
108
+ ```ts
109
+ normalize('Al-Qadisiyyah'); // 'qadisiyyah'
110
+ normalize('البَصْرَة'); // 'بصره'
111
+ ```
112
+
113
+ ## البيانات
114
+
115
+ | العربية | الإنجليزية | الكردية | المركز | ISO | الإقليم |
116
+ | --- | --- | --- | --- | --- | --- |
117
+ | بغداد | Baghdad | بەغدا | بغداد | IQ-BG | اتحادي |
118
+ | البصرة | Basra | بەسرە | البصرة | IQ-BA | اتحادي |
119
+ | نينوى | Nineveh | نەینەوا | الموصل | IQ-NI | اتحادي |
120
+ | الأنبار | Anbar | ئەنبار | الرمادي | IQ-AN | اتحادي |
121
+ | صلاح الدين | Salah al-Din | سەلاحەدین | تكريت | IQ-SD | اتحادي |
122
+ | كركوك | Kirkuk | کەرکووک | كركوك | IQ-KI | اتحادي |
123
+ | ديالى | Diyala | دیالە | بعقوبة | IQ-DI | اتحادي |
124
+ | واسط | Wasit | واسیت | الكوت | IQ-WA | اتحادي |
125
+ | بابل | Babil | بابل | الحلة | IQ-BB | اتحادي |
126
+ | كربلاء | Karbala | کەربەلا | كربلاء | IQ-KA | اتحادي |
127
+ | النجف | Najaf | نەجەف | النجف | IQ-NA | اتحادي |
128
+ | القادسية | Al-Qadisiyyah | قادسیە | الديوانية | IQ-QA | اتحادي |
129
+ | المثنى | Muthanna | موسەننا | السماوة | IQ-MU | اتحادي |
130
+ | ذي قار | Dhi Qar | زیقار | الناصرية | IQ-DQ | اتحادي |
131
+ | ميسان | Maysan | مەیسان | العمارة | IQ-MA | اتحادي |
132
+ | أربيل | Erbil | هەولێر | أربيل | IQ-AR | كردستان |
133
+ | السليمانية | Sulaymaniyah | سلێمانی | السليمانية | IQ-SU | كردستان |
134
+ | دهوك | Duhok | دهۆک | دهوك | IQ-DA | كردستان |
135
+ | حلبجة | Halabja | هەڵەبجە | حلبجة | — | كردستان |
136
+
137
+ أقرّ مجلس النواب العراقي حلبجة محافظةً تاسعة عشرة للعراق عام 2025. ليس لها رمز ISO 3166-2 بعد، لذلك قيمة `iso` لها `null`.
138
+
139
+ ## الخطط القادمة
140
+
141
+ - الأقضية في كل محافظة
142
+ - النواحي
143
+
144
+ ## المساهمة
145
+
146
+ التصحيحات مرحّب بها جداً، خصوصاً التهجئات الكردية، والتهجئات الشائعة الأخرى التي يجب إضافتها إلى `aliases`. افتح issue أو pull request يعدّل الملف [`src/governorates.json`](src/governorates.json).
147
+
148
+ ### التطوير
149
+
150
+ ```bash
151
+ npm install
152
+ npm test # تشغيل الاختبارات
153
+ npm run typecheck # فحص الأنواع
154
+ npm run build # بناء dist/ ‏(CommonJS و ES modules)
155
+ ```
156
+
157
+ ## الترخيص
158
+
159
+ [MIT](LICENSE) © Karam Al-Dulaimi
package/README.md CHANGED
@@ -1,3 +1,159 @@
1
- # Temporary Holding Version
1
+ # iraqi-data
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **English** | [العربية](README.ar.md)
4
+
5
+ [![npm version](https://img.shields.io/npm/v/iraqi-data.svg)](https://www.npmjs.com/package/iraqi-data)
6
+ [![CI](https://github.com/karam-fikre/iraqi-data/actions/workflows/ci.yml/badge.svg)](https://github.com/karam-fikre/iraqi-data/actions/workflows/ci.yml)
7
+ [![license](https://img.shields.io/npm/l/iraqi-data.svg)](LICENSE)
8
+
9
+ The governorates of Iraq in Arabic, English and Kurdish, ready for address forms, dropdowns and delivery apps. Lookup and search understand the different ways people spell the same place: `البصرة`, `البصره`, `Basrah` and `بەسرە` all find Basra.
10
+
11
+ Works in **Node.js**, the **browser**, **React**, **React Native / Expo** and **Vue**, with TypeScript types included. No dependencies.
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npm install iraqi-data
17
+ # or
18
+ yarn add iraqi-data
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ```ts
24
+ import { governorates, getGovernorate, searchGovernorates } from 'iraqi-data';
25
+ // CommonJS: const { governorates, getGovernorate } = require('iraqi-data');
26
+
27
+ getGovernorate('Basrah');
28
+ // {
29
+ // id: 'basra',
30
+ // iso: 'IQ-BA',
31
+ // ar: 'البصرة',
32
+ // en: 'Basra',
33
+ // ku: 'بەسرە',
34
+ // region: 'federal',
35
+ // capital: { ar: 'البصرة', en: 'Basra' },
36
+ // aliases: ['Basrah']
37
+ // }
38
+
39
+ getGovernorate('هولير')?.en; // 'Erbil'
40
+ getGovernorate('IQ-NI')?.capital.en; // 'Mosul'
41
+
42
+ searchGovernorates('نجف').map((g) => g.en); // ['Najaf']
43
+ searchGovernorates('ba').map((g) => g.en); // ['Baghdad', 'Basra', 'Babil', 'Anbar', 'Karbala']
44
+ ```
45
+
46
+ ### Dropdown example (React)
47
+
48
+ ```tsx
49
+ import { governorates } from 'iraqi-data';
50
+
51
+ export function GovernorateSelect({ value, onChange }) {
52
+ return (
53
+ <select value={value} onChange={(e) => onChange(e.target.value)}>
54
+ {governorates.map((g) => (
55
+ <option key={g.id} value={g.id}>{g.ar}</option>
56
+ ))}
57
+ </select>
58
+ );
59
+ }
60
+ ```
61
+
62
+ Store the `id` (`'baghdad'`, `'basra'`, …) in your database, not the display name. Ids never change, while a name's spelling may be corrected in a later version.
63
+
64
+ ## API
65
+
66
+ ### `governorates: readonly Governorate[]`
67
+
68
+ All 19 governorates: the 15 of federal Iraq, then the 4 of the Kurdistan Region. The array and its objects are frozen.
69
+
70
+ ```ts
71
+ interface Governorate {
72
+ id: string; // stable id to store: 'baghdad'
73
+ iso: string | null; // ISO 3166-2 code: 'IQ-BG' (null for Halabja, which has none yet)
74
+ ar: string; // Arabic name
75
+ en: string; // English name
76
+ ku: string; // Kurdish (Sorani) name
77
+ region: 'federal' | 'kurdistan';
78
+ capital: { ar: string; en: string };
79
+ aliases: string[]; // other spellings: 'Basrah', 'Arbil', 'Hawler'
80
+ }
81
+ ```
82
+
83
+ ### `getGovernorate(query: string): Governorate | undefined`
84
+
85
+ Finds one governorate by its id, ISO code, or full name in any language, including the aliases. Returns `undefined` if nothing matches. Partial names don't match; use `searchGovernorates` for those.
86
+
87
+ ### `searchGovernorates(query: string): Governorate[]`
88
+
89
+ Finds every governorate whose name contains the query, for autocomplete. Exact matches come first, then names that start with the query, then the rest. An empty query returns `[]`.
90
+
91
+ ### `getGovernoratesByRegion(region: 'federal' | 'kurdistan'): Governorate[]`
92
+
93
+ The governorates of federal Iraq or of the Kurdistan Region.
94
+
95
+ ### `normalize(text: string): string`
96
+
97
+ The function lookup and search use to compare names. It's exported so you can compare your own stored values the same way.
98
+
99
+ | Ignores | Example |
100
+ | --- | --- |
101
+ | Hamza forms | `أ إ آ` → `ا` |
102
+ | Taa marbuta and alef maqsura | `ة` → `ه`, `ى` → `ي` |
103
+ | Tashkeel and tatweel | `البَصْرَة` → `بصره` |
104
+ | The article | `البصرة`, `Al-Basrah`, `As Sulaymaniyah` |
105
+ | Kurdish letters typed on an Arabic keyboard | `سلێمانی` = `سليماني`, `دهۆک` = `دهوك` |
106
+ | Case, spaces, hyphens | `Dhi Qar` = `dhiqar` |
107
+
108
+ ```ts
109
+ normalize('Al-Qadisiyyah'); // 'qadisiyyah'
110
+ normalize('البَصْرَة'); // 'بصره'
111
+ ```
112
+
113
+ ## Data
114
+
115
+ | Arabic | English | Kurdish | Capital | ISO | Region |
116
+ | --- | --- | --- | --- | --- | --- |
117
+ | بغداد | Baghdad | بەغدا | Baghdad | IQ-BG | federal |
118
+ | البصرة | Basra | بەسرە | Basra | IQ-BA | federal |
119
+ | نينوى | Nineveh | نەینەوا | Mosul | IQ-NI | federal |
120
+ | الأنبار | Anbar | ئەنبار | Ramadi | IQ-AN | federal |
121
+ | صلاح الدين | Salah al-Din | سەلاحەدین | Tikrit | IQ-SD | federal |
122
+ | كركوك | Kirkuk | کەرکووک | Kirkuk | IQ-KI | federal |
123
+ | ديالى | Diyala | دیالە | Baqubah | IQ-DI | federal |
124
+ | واسط | Wasit | واسیت | Kut | IQ-WA | federal |
125
+ | بابل | Babil | بابل | Hillah | IQ-BB | federal |
126
+ | كربلاء | Karbala | کەربەلا | Karbala | IQ-KA | federal |
127
+ | النجف | Najaf | نەجەف | Najaf | IQ-NA | federal |
128
+ | القادسية | Al-Qadisiyyah | قادسیە | Diwaniyah | IQ-QA | federal |
129
+ | المثنى | Muthanna | موسەننا | Samawah | IQ-MU | federal |
130
+ | ذي قار | Dhi Qar | زیقار | Nasiriyah | IQ-DQ | federal |
131
+ | ميسان | Maysan | مەیسان | Amarah | IQ-MA | federal |
132
+ | أربيل | Erbil | هەولێر | Erbil | IQ-AR | kurdistan |
133
+ | السليمانية | Sulaymaniyah | سلێمانی | Sulaymaniyah | IQ-SU | kurdistan |
134
+ | دهوك | Duhok | دهۆک | Duhok | IQ-DA | kurdistan |
135
+ | حلبجة | Halabja | هەڵەبجە | Halabja | — | kurdistan |
136
+
137
+ Halabja was approved as Iraq's 19th governorate by the Iraqi parliament in 2025. It doesn't have an ISO 3166-2 code yet, so its `iso` is `null`.
138
+
139
+ ## Roadmap
140
+
141
+ - Districts (أقضية) of each governorate
142
+ - Sub-districts (نواحي)
143
+
144
+ ## Contributing
145
+
146
+ Corrections are very welcome, especially Kurdish spellings and other common spellings that should be added as aliases. Open an issue or a pull request that edits [`src/governorates.json`](src/governorates.json).
147
+
148
+ ### Development
149
+
150
+ ```bash
151
+ npm install
152
+ npm test # run the tests
153
+ npm run typecheck # check the types
154
+ npm run build # build dist/ (CommonJS and ES modules)
155
+ ```
156
+
157
+ ## License
158
+
159
+ [MIT](LICENSE) © Karam Al-Dulaimi
@@ -0,0 +1,37 @@
1
+ type Region = "federal" | "kurdistan";
2
+ interface Governorate {
3
+ /** Stable id to store in a database, such as "baghdad" */
4
+ readonly id: string;
5
+ /** ISO 3166-2 code, or null for a governorate that doesn't have one yet (Halabja) */
6
+ readonly iso: string | null;
7
+ readonly ar: string;
8
+ readonly en: string;
9
+ /** Kurdish (Sorani) */
10
+ readonly ku: string;
11
+ /** Federal Iraq or the Kurdistan Region */
12
+ readonly region: Region;
13
+ readonly capital: {
14
+ readonly ar: string;
15
+ readonly en: string;
16
+ };
17
+ /** Other spellings people use: Basrah, Arbil, Hawler */
18
+ readonly aliases: readonly string[];
19
+ }
20
+ /** All 19 governorates: the 15 of federal Iraq, then the 4 of the Kurdistan Region */
21
+ declare const governorates: readonly Governorate[];
22
+ /** Reduces a name to the form used for comparing: "Al-Basrah" → "basrah", "البَصرة" → "بصره" */
23
+ declare function normalize(text: string): string;
24
+ /**
25
+ * Finds a governorate by its id, ISO code, or name in any language, ignoring
26
+ * spelling differences: "Basrah", "البصره" and "IQ-BA" all return Basra.
27
+ */
28
+ declare function getGovernorate(query: string): Governorate | undefined;
29
+ /**
30
+ * Finds every governorate whose name contains the query, for autocomplete.
31
+ * Exact matches come first, then names that start with the query.
32
+ */
33
+ declare function searchGovernorates(query: string): Governorate[];
34
+ /** Governorates in federal Iraq or in the Kurdistan Region */
35
+ declare function getGovernoratesByRegion(region: Region): Governorate[];
36
+
37
+ export { type Governorate, type Region, getGovernorate, getGovernoratesByRegion, governorates, normalize, searchGovernorates };
@@ -0,0 +1,37 @@
1
+ type Region = "federal" | "kurdistan";
2
+ interface Governorate {
3
+ /** Stable id to store in a database, such as "baghdad" */
4
+ readonly id: string;
5
+ /** ISO 3166-2 code, or null for a governorate that doesn't have one yet (Halabja) */
6
+ readonly iso: string | null;
7
+ readonly ar: string;
8
+ readonly en: string;
9
+ /** Kurdish (Sorani) */
10
+ readonly ku: string;
11
+ /** Federal Iraq or the Kurdistan Region */
12
+ readonly region: Region;
13
+ readonly capital: {
14
+ readonly ar: string;
15
+ readonly en: string;
16
+ };
17
+ /** Other spellings people use: Basrah, Arbil, Hawler */
18
+ readonly aliases: readonly string[];
19
+ }
20
+ /** All 19 governorates: the 15 of federal Iraq, then the 4 of the Kurdistan Region */
21
+ declare const governorates: readonly Governorate[];
22
+ /** Reduces a name to the form used for comparing: "Al-Basrah" → "basrah", "البَصرة" → "بصره" */
23
+ declare function normalize(text: string): string;
24
+ /**
25
+ * Finds a governorate by its id, ISO code, or name in any language, ignoring
26
+ * spelling differences: "Basrah", "البصره" and "IQ-BA" all return Basra.
27
+ */
28
+ declare function getGovernorate(query: string): Governorate | undefined;
29
+ /**
30
+ * Finds every governorate whose name contains the query, for autocomplete.
31
+ * Exact matches come first, then names that start with the query.
32
+ */
33
+ declare function searchGovernorates(query: string): Governorate[];
34
+ /** Governorates in federal Iraq or in the Kurdistan Region */
35
+ declare function getGovernoratesByRegion(region: Region): Governorate[];
36
+
37
+ export { type Governorate, type Region, getGovernorate, getGovernoratesByRegion, governorates, normalize, searchGovernorates };
package/dist/index.js ADDED
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ getGovernorate: () => getGovernorate,
24
+ getGovernoratesByRegion: () => getGovernoratesByRegion,
25
+ governorates: () => governorates,
26
+ normalize: () => normalize,
27
+ searchGovernorates: () => searchGovernorates
28
+ });
29
+ module.exports = __toCommonJS(index_exports);
30
+
31
+ // src/governorates.json
32
+ var governorates_default = [
33
+ { id: "baghdad", iso: "IQ-BG", ar: "\u0628\u063A\u062F\u0627\u062F", en: "Baghdad", ku: "\u0628\u06D5\u063A\u062F\u0627", region: "federal", capital: { ar: "\u0628\u063A\u062F\u0627\u062F", en: "Baghdad" }, aliases: [] },
34
+ { id: "basra", iso: "IQ-BA", ar: "\u0627\u0644\u0628\u0635\u0631\u0629", en: "Basra", ku: "\u0628\u06D5\u0633\u0631\u06D5", region: "federal", capital: { ar: "\u0627\u0644\u0628\u0635\u0631\u0629", en: "Basra" }, aliases: ["Basrah"] },
35
+ { id: "nineveh", iso: "IQ-NI", ar: "\u0646\u064A\u0646\u0648\u0649", en: "Nineveh", ku: "\u0646\u06D5\u06CC\u0646\u06D5\u0648\u0627", region: "federal", capital: { ar: "\u0627\u0644\u0645\u0648\u0635\u0644", en: "Mosul" }, aliases: ["Ninawa", "Ninewa"] },
36
+ { id: "anbar", iso: "IQ-AN", ar: "\u0627\u0644\u0623\u0646\u0628\u0627\u0631", en: "Anbar", ku: "\u0626\u06D5\u0646\u0628\u0627\u0631", region: "federal", capital: { ar: "\u0627\u0644\u0631\u0645\u0627\u062F\u064A", en: "Ramadi" }, aliases: [] },
37
+ { id: "salahaddin", iso: "IQ-SD", ar: "\u0635\u0644\u0627\u062D \u0627\u0644\u062F\u064A\u0646", en: "Salah al-Din", ku: "\u0633\u06D5\u0644\u0627\u062D\u06D5\u062F\u06CC\u0646", region: "federal", capital: { ar: "\u062A\u0643\u0631\u064A\u062A", en: "Tikrit" }, aliases: ["Salahuddin", "Salah ad Din", "Saladin"] },
38
+ { id: "kirkuk", iso: "IQ-KI", ar: "\u0643\u0631\u0643\u0648\u0643", en: "Kirkuk", ku: "\u06A9\u06D5\u0631\u06A9\u0648\u0648\u06A9", region: "federal", capital: { ar: "\u0643\u0631\u0643\u0648\u0643", en: "Kirkuk" }, aliases: [] },
39
+ { id: "diyala", iso: "IQ-DI", ar: "\u062F\u064A\u0627\u0644\u0649", en: "Diyala", ku: "\u062F\u06CC\u0627\u0644\u06D5", region: "federal", capital: { ar: "\u0628\u0639\u0642\u0648\u0628\u0629", en: "Baqubah" }, aliases: [] },
40
+ { id: "wasit", iso: "IQ-WA", ar: "\u0648\u0627\u0633\u0637", en: "Wasit", ku: "\u0648\u0627\u0633\u06CC\u062A", region: "federal", capital: { ar: "\u0627\u0644\u0643\u0648\u062A", en: "Kut" }, aliases: [] },
41
+ { id: "babil", iso: "IQ-BB", ar: "\u0628\u0627\u0628\u0644", en: "Babil", ku: "\u0628\u0627\u0628\u0644", region: "federal", capital: { ar: "\u0627\u0644\u062D\u0644\u0629", en: "Hillah" }, aliases: ["Babylon"] },
42
+ { id: "karbala", iso: "IQ-KA", ar: "\u0643\u0631\u0628\u0644\u0627\u0621", en: "Karbala", ku: "\u06A9\u06D5\u0631\u0628\u06D5\u0644\u0627", region: "federal", capital: { ar: "\u0643\u0631\u0628\u0644\u0627\u0621", en: "Karbala" }, aliases: [] },
43
+ { id: "najaf", iso: "IQ-NA", ar: "\u0627\u0644\u0646\u062C\u0641", en: "Najaf", ku: "\u0646\u06D5\u062C\u06D5\u0641", region: "federal", capital: { ar: "\u0627\u0644\u0646\u062C\u0641", en: "Najaf" }, aliases: [] },
44
+ { id: "qadisiyyah", iso: "IQ-QA", ar: "\u0627\u0644\u0642\u0627\u062F\u0633\u064A\u0629", en: "Al-Qadisiyyah", ku: "\u0642\u0627\u062F\u0633\u06CC\u06D5", region: "federal", capital: { ar: "\u0627\u0644\u062F\u064A\u0648\u0627\u0646\u064A\u0629", en: "Diwaniyah" }, aliases: ["Qadisiyah", "Diwaniyah"] },
45
+ { id: "muthanna", iso: "IQ-MU", ar: "\u0627\u0644\u0645\u062B\u0646\u0649", en: "Muthanna", ku: "\u0645\u0648\u0633\u06D5\u0646\u0646\u0627", region: "federal", capital: { ar: "\u0627\u0644\u0633\u0645\u0627\u0648\u0629", en: "Samawah" }, aliases: [] },
46
+ { id: "dhiqar", iso: "IQ-DQ", ar: "\u0630\u064A \u0642\u0627\u0631", en: "Dhi Qar", ku: "\u0632\u06CC\u0642\u0627\u0631", region: "federal", capital: { ar: "\u0627\u0644\u0646\u0627\u0635\u0631\u064A\u0629", en: "Nasiriyah" }, aliases: ["Thi Qar"] },
47
+ { id: "maysan", iso: "IQ-MA", ar: "\u0645\u064A\u0633\u0627\u0646", en: "Maysan", ku: "\u0645\u06D5\u06CC\u0633\u0627\u0646", region: "federal", capital: { ar: "\u0627\u0644\u0639\u0645\u0627\u0631\u0629", en: "Amarah" }, aliases: ["Missan"] },
48
+ { id: "erbil", iso: "IQ-AR", ar: "\u0623\u0631\u0628\u064A\u0644", en: "Erbil", ku: "\u0647\u06D5\u0648\u0644\u06CE\u0631", region: "kurdistan", capital: { ar: "\u0623\u0631\u0628\u064A\u0644", en: "Erbil" }, aliases: ["Arbil", "Hawler", "Hewler", "\u0647\u0648\u0644\u064A\u0631"] },
49
+ { id: "sulaymaniyah", iso: "IQ-SU", ar: "\u0627\u0644\u0633\u0644\u064A\u0645\u0627\u0646\u064A\u0629", en: "Sulaymaniyah", ku: "\u0633\u0644\u06CE\u0645\u0627\u0646\u06CC", region: "kurdistan", capital: { ar: "\u0627\u0644\u0633\u0644\u064A\u0645\u0627\u0646\u064A\u0629", en: "Sulaymaniyah" }, aliases: ["Slemani", "Sulaimani", "Sulaimaniya"] },
50
+ { id: "duhok", iso: "IQ-DA", ar: "\u062F\u0647\u0648\u0643", en: "Duhok", ku: "\u062F\u0647\u06C6\u06A9", region: "kurdistan", capital: { ar: "\u062F\u0647\u0648\u0643", en: "Duhok" }, aliases: ["Dohuk", "Dahuk"] },
51
+ { id: "halabja", iso: null, ar: "\u062D\u0644\u0628\u062C\u0629", en: "Halabja", ku: "\u0647\u06D5\u06B5\u06D5\u0628\u062C\u06D5", region: "kurdistan", capital: { ar: "\u062D\u0644\u0628\u062C\u0629", en: "Halabja" }, aliases: [] }
52
+ ];
53
+
54
+ // src/index.ts
55
+ var freeze = (g) => Object.freeze({ ...g, capital: Object.freeze({ ...g.capital }), aliases: Object.freeze([...g.aliases]) });
56
+ var governorates = Object.freeze(governorates_default.map(freeze));
57
+ var MARKS = /[ؐ-ًؚ-ٰٟـ]/g;
58
+ var LETTERS = {
59
+ \u0623: "\u0627",
60
+ \u0625: "\u0627",
61
+ \u0622: "\u0627",
62
+ \u0671: "\u0627",
63
+ \u0629: "\u0647",
64
+ \u0649: "\u064A",
65
+ \u06CC: "\u064A",
66
+ \u06A9: "\u0643",
67
+ \u06D5: "\u0647",
68
+ \u06CE: "\u064A",
69
+ \u06C6: "\u0648",
70
+ \u06B5: "\u0644",
71
+ \u0695: "\u0631"
72
+ };
73
+ var LETTER_VARIANTS = new RegExp(`[${Object.keys(LETTERS).join("")}]`, "g");
74
+ var ARABIC_ARTICLE = /(^|\s)ال/g;
75
+ var LATIN_ARTICLE = /(^|[\s-])a[ldnrstz][\s-]+/g;
76
+ var NOT_LETTER = /[^a-z0-9ؠ-ي٠-٩ٮ-ۓە]/g;
77
+ function normalize(text) {
78
+ return text.toLowerCase().replace(MARKS, "").replace(LETTER_VARIANTS, (c) => LETTERS[c]).replace(ARABIC_ARTICLE, "$1").replace(LATIN_ARTICLE, "$1").replace(NOT_LETTER, "");
79
+ }
80
+ var keys = governorates.map((g) => [...new Set([g.id, g.ar, g.en, g.ku, ...g.aliases].map(normalize))]);
81
+ function getGovernorate(query) {
82
+ const iso = query.trim().toUpperCase();
83
+ const byIso = governorates.find((g) => g.iso === iso);
84
+ if (byIso) return byIso;
85
+ const q = normalize(query);
86
+ if (!q) return void 0;
87
+ const index = keys.findIndex((k) => k.includes(q));
88
+ return index === -1 ? void 0 : governorates[index];
89
+ }
90
+ function searchGovernorates(query) {
91
+ const q = normalize(query);
92
+ if (!q) return [];
93
+ const rank = (k) => k.includes(q) ? 0 : k.some((key) => key.startsWith(q)) ? 1 : 2;
94
+ return governorates.map((g, i) => ({ g, k: keys[i] })).filter(({ k }) => k.some((key) => key.includes(q))).sort((a, b) => rank(a.k) - rank(b.k)).map(({ g }) => g);
95
+ }
96
+ function getGovernoratesByRegion(region) {
97
+ return governorates.filter((g) => g.region === region);
98
+ }
99
+ // Annotate the CommonJS export names for ESM import in node:
100
+ 0 && (module.exports = {
101
+ getGovernorate,
102
+ getGovernoratesByRegion,
103
+ governorates,
104
+ normalize,
105
+ searchGovernorates
106
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,75 @@
1
+ // src/governorates.json
2
+ var governorates_default = [
3
+ { id: "baghdad", iso: "IQ-BG", ar: "\u0628\u063A\u062F\u0627\u062F", en: "Baghdad", ku: "\u0628\u06D5\u063A\u062F\u0627", region: "federal", capital: { ar: "\u0628\u063A\u062F\u0627\u062F", en: "Baghdad" }, aliases: [] },
4
+ { id: "basra", iso: "IQ-BA", ar: "\u0627\u0644\u0628\u0635\u0631\u0629", en: "Basra", ku: "\u0628\u06D5\u0633\u0631\u06D5", region: "federal", capital: { ar: "\u0627\u0644\u0628\u0635\u0631\u0629", en: "Basra" }, aliases: ["Basrah"] },
5
+ { id: "nineveh", iso: "IQ-NI", ar: "\u0646\u064A\u0646\u0648\u0649", en: "Nineveh", ku: "\u0646\u06D5\u06CC\u0646\u06D5\u0648\u0627", region: "federal", capital: { ar: "\u0627\u0644\u0645\u0648\u0635\u0644", en: "Mosul" }, aliases: ["Ninawa", "Ninewa"] },
6
+ { id: "anbar", iso: "IQ-AN", ar: "\u0627\u0644\u0623\u0646\u0628\u0627\u0631", en: "Anbar", ku: "\u0626\u06D5\u0646\u0628\u0627\u0631", region: "federal", capital: { ar: "\u0627\u0644\u0631\u0645\u0627\u062F\u064A", en: "Ramadi" }, aliases: [] },
7
+ { id: "salahaddin", iso: "IQ-SD", ar: "\u0635\u0644\u0627\u062D \u0627\u0644\u062F\u064A\u0646", en: "Salah al-Din", ku: "\u0633\u06D5\u0644\u0627\u062D\u06D5\u062F\u06CC\u0646", region: "federal", capital: { ar: "\u062A\u0643\u0631\u064A\u062A", en: "Tikrit" }, aliases: ["Salahuddin", "Salah ad Din", "Saladin"] },
8
+ { id: "kirkuk", iso: "IQ-KI", ar: "\u0643\u0631\u0643\u0648\u0643", en: "Kirkuk", ku: "\u06A9\u06D5\u0631\u06A9\u0648\u0648\u06A9", region: "federal", capital: { ar: "\u0643\u0631\u0643\u0648\u0643", en: "Kirkuk" }, aliases: [] },
9
+ { id: "diyala", iso: "IQ-DI", ar: "\u062F\u064A\u0627\u0644\u0649", en: "Diyala", ku: "\u062F\u06CC\u0627\u0644\u06D5", region: "federal", capital: { ar: "\u0628\u0639\u0642\u0648\u0628\u0629", en: "Baqubah" }, aliases: [] },
10
+ { id: "wasit", iso: "IQ-WA", ar: "\u0648\u0627\u0633\u0637", en: "Wasit", ku: "\u0648\u0627\u0633\u06CC\u062A", region: "federal", capital: { ar: "\u0627\u0644\u0643\u0648\u062A", en: "Kut" }, aliases: [] },
11
+ { id: "babil", iso: "IQ-BB", ar: "\u0628\u0627\u0628\u0644", en: "Babil", ku: "\u0628\u0627\u0628\u0644", region: "federal", capital: { ar: "\u0627\u0644\u062D\u0644\u0629", en: "Hillah" }, aliases: ["Babylon"] },
12
+ { id: "karbala", iso: "IQ-KA", ar: "\u0643\u0631\u0628\u0644\u0627\u0621", en: "Karbala", ku: "\u06A9\u06D5\u0631\u0628\u06D5\u0644\u0627", region: "federal", capital: { ar: "\u0643\u0631\u0628\u0644\u0627\u0621", en: "Karbala" }, aliases: [] },
13
+ { id: "najaf", iso: "IQ-NA", ar: "\u0627\u0644\u0646\u062C\u0641", en: "Najaf", ku: "\u0646\u06D5\u062C\u06D5\u0641", region: "federal", capital: { ar: "\u0627\u0644\u0646\u062C\u0641", en: "Najaf" }, aliases: [] },
14
+ { id: "qadisiyyah", iso: "IQ-QA", ar: "\u0627\u0644\u0642\u0627\u062F\u0633\u064A\u0629", en: "Al-Qadisiyyah", ku: "\u0642\u0627\u062F\u0633\u06CC\u06D5", region: "federal", capital: { ar: "\u0627\u0644\u062F\u064A\u0648\u0627\u0646\u064A\u0629", en: "Diwaniyah" }, aliases: ["Qadisiyah", "Diwaniyah"] },
15
+ { id: "muthanna", iso: "IQ-MU", ar: "\u0627\u0644\u0645\u062B\u0646\u0649", en: "Muthanna", ku: "\u0645\u0648\u0633\u06D5\u0646\u0646\u0627", region: "federal", capital: { ar: "\u0627\u0644\u0633\u0645\u0627\u0648\u0629", en: "Samawah" }, aliases: [] },
16
+ { id: "dhiqar", iso: "IQ-DQ", ar: "\u0630\u064A \u0642\u0627\u0631", en: "Dhi Qar", ku: "\u0632\u06CC\u0642\u0627\u0631", region: "federal", capital: { ar: "\u0627\u0644\u0646\u0627\u0635\u0631\u064A\u0629", en: "Nasiriyah" }, aliases: ["Thi Qar"] },
17
+ { id: "maysan", iso: "IQ-MA", ar: "\u0645\u064A\u0633\u0627\u0646", en: "Maysan", ku: "\u0645\u06D5\u06CC\u0633\u0627\u0646", region: "federal", capital: { ar: "\u0627\u0644\u0639\u0645\u0627\u0631\u0629", en: "Amarah" }, aliases: ["Missan"] },
18
+ { id: "erbil", iso: "IQ-AR", ar: "\u0623\u0631\u0628\u064A\u0644", en: "Erbil", ku: "\u0647\u06D5\u0648\u0644\u06CE\u0631", region: "kurdistan", capital: { ar: "\u0623\u0631\u0628\u064A\u0644", en: "Erbil" }, aliases: ["Arbil", "Hawler", "Hewler", "\u0647\u0648\u0644\u064A\u0631"] },
19
+ { id: "sulaymaniyah", iso: "IQ-SU", ar: "\u0627\u0644\u0633\u0644\u064A\u0645\u0627\u0646\u064A\u0629", en: "Sulaymaniyah", ku: "\u0633\u0644\u06CE\u0645\u0627\u0646\u06CC", region: "kurdistan", capital: { ar: "\u0627\u0644\u0633\u0644\u064A\u0645\u0627\u0646\u064A\u0629", en: "Sulaymaniyah" }, aliases: ["Slemani", "Sulaimani", "Sulaimaniya"] },
20
+ { id: "duhok", iso: "IQ-DA", ar: "\u062F\u0647\u0648\u0643", en: "Duhok", ku: "\u062F\u0647\u06C6\u06A9", region: "kurdistan", capital: { ar: "\u062F\u0647\u0648\u0643", en: "Duhok" }, aliases: ["Dohuk", "Dahuk"] },
21
+ { id: "halabja", iso: null, ar: "\u062D\u0644\u0628\u062C\u0629", en: "Halabja", ku: "\u0647\u06D5\u06B5\u06D5\u0628\u062C\u06D5", region: "kurdistan", capital: { ar: "\u062D\u0644\u0628\u062C\u0629", en: "Halabja" }, aliases: [] }
22
+ ];
23
+
24
+ // src/index.ts
25
+ var freeze = (g) => Object.freeze({ ...g, capital: Object.freeze({ ...g.capital }), aliases: Object.freeze([...g.aliases]) });
26
+ var governorates = Object.freeze(governorates_default.map(freeze));
27
+ var MARKS = /[ؐ-ًؚ-ٰٟـ]/g;
28
+ var LETTERS = {
29
+ \u0623: "\u0627",
30
+ \u0625: "\u0627",
31
+ \u0622: "\u0627",
32
+ \u0671: "\u0627",
33
+ \u0629: "\u0647",
34
+ \u0649: "\u064A",
35
+ \u06CC: "\u064A",
36
+ \u06A9: "\u0643",
37
+ \u06D5: "\u0647",
38
+ \u06CE: "\u064A",
39
+ \u06C6: "\u0648",
40
+ \u06B5: "\u0644",
41
+ \u0695: "\u0631"
42
+ };
43
+ var LETTER_VARIANTS = new RegExp(`[${Object.keys(LETTERS).join("")}]`, "g");
44
+ var ARABIC_ARTICLE = /(^|\s)ال/g;
45
+ var LATIN_ARTICLE = /(^|[\s-])a[ldnrstz][\s-]+/g;
46
+ var NOT_LETTER = /[^a-z0-9ؠ-ي٠-٩ٮ-ۓە]/g;
47
+ function normalize(text) {
48
+ return text.toLowerCase().replace(MARKS, "").replace(LETTER_VARIANTS, (c) => LETTERS[c]).replace(ARABIC_ARTICLE, "$1").replace(LATIN_ARTICLE, "$1").replace(NOT_LETTER, "");
49
+ }
50
+ var keys = governorates.map((g) => [...new Set([g.id, g.ar, g.en, g.ku, ...g.aliases].map(normalize))]);
51
+ function getGovernorate(query) {
52
+ const iso = query.trim().toUpperCase();
53
+ const byIso = governorates.find((g) => g.iso === iso);
54
+ if (byIso) return byIso;
55
+ const q = normalize(query);
56
+ if (!q) return void 0;
57
+ const index = keys.findIndex((k) => k.includes(q));
58
+ return index === -1 ? void 0 : governorates[index];
59
+ }
60
+ function searchGovernorates(query) {
61
+ const q = normalize(query);
62
+ if (!q) return [];
63
+ const rank = (k) => k.includes(q) ? 0 : k.some((key) => key.startsWith(q)) ? 1 : 2;
64
+ return governorates.map((g, i) => ({ g, k: keys[i] })).filter(({ k }) => k.some((key) => key.includes(q))).sort((a, b) => rank(a.k) - rank(b.k)).map(({ g }) => g);
65
+ }
66
+ function getGovernoratesByRegion(region) {
67
+ return governorates.filter((g) => g.region === region);
68
+ }
69
+ export {
70
+ getGovernorate,
71
+ getGovernoratesByRegion,
72
+ governorates,
73
+ normalize,
74
+ searchGovernorates
75
+ };
package/package.json CHANGED
@@ -1,6 +1,65 @@
1
1
  {
2
2
  "name": "iraqi-data",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Iraqi governorates in Arabic, English and Kurdish, with search that handles spelling variations",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/index.d.mts",
12
+ "default": "./dist/index.mjs"
13
+ },
14
+ "require": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.js"
17
+ }
18
+ },
19
+ "./package.json": "./package.json"
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
26
+ "test": "tsx ./node_modules/mocha/bin/mocha \"./test/**/*.test.ts\"",
27
+ "prepublishOnly": "npm run build && npm test",
28
+ "typecheck": "tsc --noEmit"
29
+ },
30
+ "keywords": [
31
+ "iraq",
32
+ "iraqi",
33
+ "governorates",
34
+ "provinces",
35
+ "kurdistan",
36
+ "arabic",
37
+ "kurdish",
38
+ "address",
39
+ "geography",
40
+ "data",
41
+ "typescript"
42
+ ],
43
+ "author": "Karam Al-Dulaimi",
44
+ "license": "MIT",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "git+https://github.com/karam-fikre/iraqi-data.git"
48
+ },
49
+ "bugs": {
50
+ "url": "https://github.com/karam-fikre/iraqi-data/issues"
51
+ },
52
+ "homepage": "https://github.com/karam-fikre/iraqi-data#readme",
53
+ "devDependencies": {
54
+ "@types/mocha": "^10.0.0",
55
+ "@types/node": "^26.6.5",
56
+ "mocha": "^12.0.3",
57
+ "tsup": "^8.0.0",
58
+ "tsx": "^4.23.15",
59
+ "typescript": "^5.0.0"
60
+ },
61
+ "sideEffects": false,
62
+ "engines": {
63
+ "node": ">=14"
64
+ }
65
+ }