@khitab/core 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 +21 -0
- package/README.ar.md +192 -0
- package/README.md +56 -0
- package/dist/index.cjs +5403 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +21 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +5400 -0
- package/dist/index.js.map +1 -0
- package/package.json +71 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ahmed Almnsour
|
|
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,192 @@
|
|
|
1
|
+
[English](./README.md) | **العربية**
|
|
2
|
+
|
|
3
|
+
# خِطاب | khitab
|
|
4
|
+
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://github.com/ahmedalmnsour/khitab/actions/workflows/ci.yml)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
[](https://github.com/ahmedalmnsour/khitab)
|
|
9
|
+
|
|
10
|
+
> عباراتٌ عربية جاهزة تراعي جنس المخاطَب في نصوص الواجهات. خفيفة، مبنية على TypeScript، ومستقلة عن أُطُر العمل.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## ما هو خِطاب khitab؟ والفلسفة من ورائه
|
|
15
|
+
|
|
16
|
+
في العربية، يتغيّر الفعل وكثيرٌ من الجُمل بحسب من تُخاطِب: تقول للرجل `احفظ` وللمرأة `احفظي`، وللرجل `أهلاً بعودتكَ` وللمرأة `أهلاً بعودتكِ`. أغلب الواجهات تتجاهل هذا الفرق وتلجأ إلى المذكّر افتراضياً، فتُخاطِب نصفَ مستخدميها بصيغةٍ لا تخصّهم.
|
|
17
|
+
|
|
18
|
+
**خِطاب** مكتبة صغيرة: قاموسٌ من العبارات العربية المراجَعة، ودالةٌ صغيرة تُعيد الصيغة الصحيحة بحسب الجنس. الهدف بسيط ومحدَّد: أن تُخاطِب واجهتُك كلَّ مستخدمٍ بالصيغة التي تليق به، دون أن تكتب أنت جداول التصريف يدوياً في كل مشروع.
|
|
19
|
+
|
|
20
|
+
<p align="center">
|
|
21
|
+
<img src="https://raw.githubusercontent.com/ahmedalmnsour/khitab/main/assets/khitab-phrases-ar.svg" alt="قاموس خِطاب: 1367 عبارة — 780 جندرية (57%)، 587 محايدة (43%)" width="380" />
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
الفلسفة التي تحكم المشروع:
|
|
25
|
+
|
|
26
|
+
- **المخاطبة الصحيحة حقٌّ لا تحسين.** أن يُخاطَب المستخدم بصيغته ليس رفاهية تجميلية، بل احترامٌ أساسي للغة وللشخص.
|
|
27
|
+
- **الصدق حول الحدود.** المكتبة تحلّ جزءاً محدوداً من مشكلةٍ لغوية واسعة. لا ندّعي تغطيةً كاملة، ونوثّق ما لا نفعله بوضوح (انظر «حدود المكتبة»).
|
|
28
|
+
- **المذكّر ليس محايداً.** اللجوء إلى المذكّر عند الجهل بالجنس حلٌّ عمليٌّ مؤقّت، لا قاعدة صحيحة. نسعى لتقليله كلما سمحت اللغة بصيغةٍ محايدة فعلاً.
|
|
29
|
+
- **اللغة قبل الكود.** أُثَمِّن المساهمة اللغوية أكثر من غيرها؛ القاموس يُبنى بمراجعة لغوية لا بكثرة الالتزامات.
|
|
30
|
+
- **البساطة عقد.** السطح العام صغير ومقصود: دالتان وأربعة أنواع. كل إضافة تُوزَن بميزان الحاجة لا الإمكان.
|
|
31
|
+
- **الشفافية في المراحل.** هذا إصدار alpha (غير منشور على npm بعد): القاموس مكتمل ومراجَع، لكن المكتبة لم تُختبَر ميدانياً بعد، ونقولها صراحةً بدل أن نوهم باكتمالٍ لم يتحقّق.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## التثبيت
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install @khitab/core
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
المكتبة بلا أي اعتمادات وقت التشغيل (zero runtime dependencies)، وتأتي بصيغتَي ESM وCJS مع تعريفات أنواع كاملة.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## البدء السريع
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { khitab, createKhitab } from '@khitab/core';
|
|
49
|
+
|
|
50
|
+
// الواجهة البسيطة: عديمة الحالة، الجنس إلزامي.
|
|
51
|
+
khitab('save', 'male'); // احفظ
|
|
52
|
+
khitab('save', 'female'); // احفظي
|
|
53
|
+
|
|
54
|
+
// الواجهة المتقدمة (Factory): نطاق محلي فقط.
|
|
55
|
+
const k = createKhitab({ defaultGender: 'female' });
|
|
56
|
+
k('login'); // سجّلي الدخول
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## الواجهتان
|
|
62
|
+
|
|
63
|
+
### 1) الواجهة البسيطة: `khitab(key, gender)`
|
|
64
|
+
|
|
65
|
+
عديمة الحالة (stateless)، والجنس **إلزامي** في كل استدعاء. لا تحتفظ بأي حالة بين الاستدعاءات، فهي **الموصى بها للسيرفرات** ولأي سياقٍ يُخدَم فيه أكثر من مستخدم.
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
khitab('delete', 'male'); // احذف
|
|
69
|
+
khitab('delete', 'female'); // احذفي
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 2) الواجهة المتقدمة: `createKhitab(options)`
|
|
73
|
+
|
|
74
|
+
تُنشئ دالةً مُهيّأة مسبقاً بجنسٍ افتراضي وسلوكٍ محدَّد. **للنطاق المحلي فقط**، داخل مكوِّن (component) أو معالِج طلب واحد.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const k = createKhitab({
|
|
78
|
+
defaultGender: 'female', // الجنس الافتراضي حين لا يُمرَّر
|
|
79
|
+
mode: 'lenient', // 'lenient' (افتراضي) أو 'strict'
|
|
80
|
+
onMissingNeutral: 'male' // سلوك غياب المحايد: 'male' (افتراضي) أو 'throw'
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
k('save'); // يستخدم الافتراضي → احفظي
|
|
84
|
+
k('save', 'male'); // تمرير صريح يتجاوز الافتراضي → احفظ
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
الخيارات الثلاثة كلها اختيارية، وافتراضاتها: `mode: 'lenient'`، `onMissingNeutral: 'male'`، وبلا جنسٍ افتراضي (فيلجأ إلى `male` عند عدم التمرير).
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## شفافية حول الحدود: المحايد والمذكّر الافتراضي
|
|
92
|
+
|
|
93
|
+
هذه أهم نقطة يجب أن تفهمها قبل الاعتماد على المكتبة، ونقولها بصراحة:
|
|
94
|
+
|
|
95
|
+
القاموس فيه نوعان من العبارات:
|
|
96
|
+
|
|
97
|
+
1. **عبارات جندرية** (780 عبارة): تحمل `male` و`female`، وكثيرٌ منها يحمل أيضاً صيغة `neutral` مصدرية حين يكون لفعل الأمر مصدرٌ محايد طبيعي (مثل `save`: `احفظ`/`احفظي`/`الحفظ`). أمّا الجُمل الخبرية والماضية المخاطِبة فلا تحمل `neutral`، لأنه لا يكون لها مصدرٌ محايد صادق.
|
|
98
|
+
2. **عبارات محايدة طبيعياً** (587 عبارة): تحمل `neutral` وحدها، لأن نصّها لا يخاطب بجنسٍ أصلاً، مثل:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
khitab('tryLater', 'male'); // يُرجى المحاولة لاحقاً
|
|
102
|
+
khitab('tryLater', 'female'); // يُرجى المحاولة لاحقاً (النصّ نفسه، لا فرق)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**فماذا يحدث إن طلبتَ `neutral` لعبارةٍ جندرية؟** بما أنها لا تملك صيغةً محايدة، يعتمد السلوك على الوضع:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
// الوضع المتساهل (lenient، الافتراضي): يلجأ إلى المذكّر مع تحذير في الطرفية.
|
|
109
|
+
khitab('save', 'neutral');
|
|
110
|
+
// → احفظ
|
|
111
|
+
// ⚠️ khitab: phrase "save" has no neutral form; falling back to male.
|
|
112
|
+
|
|
113
|
+
// الوضع الصارم (strict): يرمي خطأً صريحاً بدل اللجوء الصامت.
|
|
114
|
+
const strict = createKhitab({ mode: 'strict' });
|
|
115
|
+
strict('save', 'neutral');
|
|
116
|
+
// ✗ Error: khitab: phrase "save" has no neutral form (strict mode).
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
اللجوء إلى المذكّر هنا حلٌّ **عمليٌّ لا مثاليّ**، ونحن صادقون في تسميته كذلك. الصيغة المحايدة **ممكنة نظرياً** لكثيرٍ من العبارات (بإعادة صياغةٍ مبنيّة للمجهول أو مصدرية)، لكنها تحتاج عملاً لغوياً ومراجعة. **هنا يأتي دورك:** انظر «للشمولية الكاملة» و«المساهمة».
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## ⚠️ تحذير: العرض من جانب الخادم (SSR)
|
|
124
|
+
|
|
125
|
+
لا تُنشئ Factory في النطاق العام (global scope) على الخادم. الدالة الناتجة من `createKhitab` تحمل حالةً (الجنس الافتراضي والإعدادات). إن وُضعت في مستوى الوحدة (module-level) على سيرفر، يؤدي ذلك إلى **تسرّب الحالة** بين طلبات المستخدمين، فيرى مستخدمٌ صيغةً هُيّئت لطلب مستخدمٍ آخر.
|
|
126
|
+
|
|
127
|
+
القاعدة:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
// ✗ خطأ على الخادم: حالة مشتركة بين كل الطلبات.
|
|
131
|
+
const k = createKhitab({ defaultGender: 'female' });
|
|
132
|
+
export function handler(req) { return k('save'); }
|
|
133
|
+
|
|
134
|
+
// ✓ صحيح: إمّا الواجهة البسيطة عديمة الحالة...
|
|
135
|
+
export function handler(req) { return khitab('save', req.user.gender); }
|
|
136
|
+
|
|
137
|
+
// ✓ ...أو Factory داخل نطاق الطلب الواحد.
|
|
138
|
+
export function handler(req) {
|
|
139
|
+
const k = createKhitab({ defaultGender: req.user.gender });
|
|
140
|
+
return k('save');
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
على العميل (متصفّح، أو مكوِّن واجهة لمستخدمٍ واحد) فإنشاء Factory محلي آمن.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## ⚠️ تحذير: إصدار alpha
|
|
149
|
+
|
|
150
|
+
هذا إصدار **alpha، غير منشور على npm بعد**: القاموس مكتمل ومراجَع، لكن المكتبة لم تُختبَر بعد في مشاريع حقيقية. قد تتغيّر الواجهة العامة (الدوال والأنواع) وقد يتغيّر القاموس (نصوص، إضافات، أسماء مفاتيح) بصورةٍ **غير متوافقة مع السابق** قبل الإصدار المستقر `1.0.0`. إن اعتمدتَ عليه في الإنتاج، **ثبّت إصدارك** (pin) وراجع [سجل التغييرات](./CHANGELOG.md) قبل الترقية.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## حدود المكتبة
|
|
155
|
+
|
|
156
|
+
لنكون صادقين معك، هذا ما **لا** تفعله المكتبة حالياً:
|
|
157
|
+
|
|
158
|
+
- **لا تكتشف الجنس.** أنت تُمرّره؛ المكتبة لا تخمّنه من اسمٍ ولا من سياق.
|
|
159
|
+
- **لا تصرّف نصوصاً حرّة.** تُعيد عباراتٍ من قاموسٍ مُعدّ مسبقاً فقط، لا تُصرّف جملةً تكتبها أنت لحظياً.
|
|
160
|
+
- **لا تغطّي كل التراكيب.** النطاق الحالي: الأمر، جمل الاستفهام، الصياغات المهذّبة، والفعل الماضي مع «لقد» مسنَداً إلى ضمير المخاطب. المؤجَّل: الجُمَل ذات الإسناد المركّب (ضمائر متعددة)، والمستقبلية المعقّدة، والمبني للمجهول الكامل (عدا المحايدة الموثّقة)، واللهجات.
|
|
161
|
+
- **لا تدعم المثنّى ولا الجمع** كصِيَغ مخاطبة في هذا الإصدار.
|
|
162
|
+
- **لا محايدَ لكل عبارة جندرية.** نضيف `neutral` حيث يكون لفعل الأمر مصدرٌ محايد صادق فقط؛ والجُمل الخبرية والماضية تبقى جندرية بلا محايد (كما شُرح أعلاه).
|
|
163
|
+
|
|
164
|
+
نوثّق هذه الحدود عمداً: مكتبةٌ صادقةٌ بحدودها أنفعُ من واحدةٍ تَعِد بما لا تفي به.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## للشمولية الكاملة
|
|
169
|
+
|
|
170
|
+
اللجوء إلى المذكّر افتراضياً ليس غايتنا، بل نقطة انطلاق. الطريق نحو شموليةٍ أكمل:
|
|
171
|
+
|
|
172
|
+
- **أضف صيغاً محايدة** للعبارات الجندرية حيث تسمح اللغة (إعادة صياغة مبنيّة للمجهول أو مصدرية). كل صيغةٍ محايدة تُضاف تُقلّل اللجوء إلى المذكّر.
|
|
173
|
+
- **استعمل الوضع الصارم** (`mode: 'strict'`) أثناء التطوير لتكتشف مواضع غياب المحايد مبكراً بدل أن تمرّ صامتةً.
|
|
174
|
+
- **مرّر الجنس الحقيقي** متى توفّر من بيانات المستخدم، بدل الاتكال على الافتراضي.
|
|
175
|
+
|
|
176
|
+
المساهمة اللغوية هي المحرّك الأساسي لهذا التقدّم. انظر القسم التالي.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## المساهمة
|
|
181
|
+
|
|
182
|
+
أُثَمِّن المساهمة اللغوية أكثر من غيرها: اقتراح عبارةٍ دقيقة أو إكمال صيغةٍ ناقصة. تفاصيل القواعد وطريقة العمل في [دليل المساهمة](./CONTRIBUTING.md). القاعدة الأهم: **تقترح النصّ والسياق، لا اسم المفتاح** (المفتاح يسكّه صاحب المشروع حفاظاً على عقد القاموس العام).
|
|
183
|
+
|
|
184
|
+
لاقتراح عبارة، افتح [Issue عبر قالب «اقتراح عبارة»](https://github.com/ahmedalmnsour/khitab/issues/new?template=add-phrase.md).
|
|
185
|
+
|
|
186
|
+
يلتزم كل المشاركين بـ[قواعد السلوك](./CODE_OF_CONDUCT.md). للإبلاغ عن أي انتهاك، راسِل: **khitab.conduct@gmail.com**.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## الترخيص
|
|
191
|
+
|
|
192
|
+
[MIT](./LICENSE) © 2026 Ahmed Almnsour
|
package/README.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
**English** | [العربية](./README.ar.md)
|
|
2
|
+
|
|
3
|
+
# khitab
|
|
4
|
+
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://github.com/ahmedalmnsour/khitab/actions/workflows/ci.yml)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
[](https://github.com/ahmedalmnsour/khitab)
|
|
9
|
+
|
|
10
|
+
> Ready-made, gender-aware Arabic phrases for UI text. Lightweight, TypeScript-first, framework-agnostic.
|
|
11
|
+
|
|
12
|
+
This English README is a short gateway. The full documentation, including philosophy, both interfaces, limits, and the inclusivity guide, lives in **[the Arabic README](./README.ar.md)**, the project's heart.
|
|
13
|
+
|
|
14
|
+
## What is khitab?
|
|
15
|
+
|
|
16
|
+
Arabic verbs and many sentences change form depending on whom you address: `احفظ` to a man, `احفظي` to a woman. Most UIs ignore this and default to the masculine. **khitab** is a small dictionary plus a tiny function that returns the correctly-addressed Arabic phrase for a given gender, so your interface speaks to each user properly.
|
|
17
|
+
|
|
18
|
+
It ships 1367 reviewed phrases (780 gendered, 587 naturally neutral) across a core set and ten domains, has zero runtime dependencies, and is fully typed.
|
|
19
|
+
|
|
20
|
+
<p align="center">
|
|
21
|
+
<img src="https://raw.githubusercontent.com/ahmedalmnsour/khitab/main/assets/khitab-phrases-en.svg" alt="khitab dictionary: 1367 phrases — 780 gendered (57%), 587 neutral (43%)" width="380" />
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install @khitab/core
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick start
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { khitab, createKhitab } from '@khitab/core';
|
|
34
|
+
|
|
35
|
+
// Simple, stateless — recommended for servers. `gender` is required.
|
|
36
|
+
khitab('save', 'male'); // احفظ
|
|
37
|
+
khitab('save', 'female'); // احفظي
|
|
38
|
+
|
|
39
|
+
// Factory — for LOCAL scope only (a component or a request handler).
|
|
40
|
+
const k = createKhitab({ defaultGender: 'female' });
|
|
41
|
+
k('login'); // سجّلي الدخول
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
See [`examples/basic.ts`](./examples/basic.ts) for the neutral-fallback and error behaviors.
|
|
45
|
+
|
|
46
|
+
## ⚠️ Alpha
|
|
47
|
+
|
|
48
|
+
This is an alpha release: the phrase dictionary is complete and reviewed, but the library has not yet been tested in real-world projects. No npm package published yet. The API may change before a stable release.
|
|
49
|
+
|
|
50
|
+
## Full documentation
|
|
51
|
+
|
|
52
|
+
The complete guide is in the **[Arabic README](./README.ar.md)**. It covers the philosophy behind gender-aware addressing, the simple vs. factory interfaces in depth, an honest account of the library's limits, the SSR warning, and how to contribute toward full inclusivity.
|
|
53
|
+
|
|
54
|
+
## License
|
|
55
|
+
|
|
56
|
+
[MIT](./LICENSE) © 2026 Ahmed Almnsour
|