sunnah 1.3.6 → 1.5.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/CHANGELOG.md +19 -0
- package/README.md +258 -254
- package/bin/index.js +1022 -1604
- package/books/jami-al-tirmidhi/README.md +201 -0
- package/books/jami-al-tirmidhi/bin/index.js +165 -0
- package/books/jami-al-tirmidhi/examples/express/server.js +7 -0
- package/books/jami-al-tirmidhi/examples/node-commonjs/example.js +7 -0
- package/books/jami-al-tirmidhi/examples/node-esm/example.mjs +6 -0
- package/books/jami-al-tirmidhi/examples/react/HadithExample.jsx +17 -0
- package/books/jami-al-tirmidhi/package.json +58 -0
- package/books/jami-al-tirmidhi/src/index.cjs +52 -0
- package/books/jami-al-tirmidhi/src/index.js +35 -0
- package/books/jami-al-tirmidhi/src/index.node.js +18 -0
- package/books/jami-al-tirmidhi/types/index.d.ts +28 -0
- package/books/sahih-al-bukhari/LICENSE +661 -0
- package/books/sahih-al-bukhari/README.md +551 -0
- package/books/sahih-al-bukhari/bin/index.js +306 -0
- package/books/sahih-al-bukhari/data/bukhari.json.gz +0 -0
- package/books/sahih-al-bukhari/examples/express/server.js +49 -0
- package/books/sahih-al-bukhari/examples/node-commonjs/example.js +21 -0
- package/books/sahih-al-bukhari/examples/node-esm/example.mjs +24 -0
- package/books/sahih-al-bukhari/examples/react/HadithExample.jsx +73 -0
- package/books/sahih-al-bukhari/package.json +54 -0
- package/books/sahih-al-bukhari/src/index.cjs +55 -0
- package/books/sahih-al-bukhari/src/index.js +35 -0
- package/books/sahih-al-bukhari/src/index.node.js +21 -0
- package/books/sahih-al-bukhari/types/index.d.ts +35 -0
- package/books/sahih-muslim/LICENSE +661 -0
- package/books/sahih-muslim/README.md +547 -0
- package/books/sahih-muslim/bin/index.js +183 -0
- package/books/sahih-muslim/data/muslim.json.gz +0 -0
- package/books/sahih-muslim/examples/express/server.js +16 -0
- package/books/sahih-muslim/examples/node-commonjs/example.js +11 -0
- package/books/sahih-muslim/examples/node-esm/example.mjs +9 -0
- package/books/sahih-muslim/examples/react/HadithExample.jsx +28 -0
- package/books/sahih-muslim/package.json +58 -0
- package/books/sahih-muslim/src/index.cjs +52 -0
- package/books/sahih-muslim/src/index.js +35 -0
- package/books/sahih-muslim/src/index.node.js +18 -0
- package/books/sahih-muslim/types/index.d.ts +28 -0
- package/books/sunan-abi-dawud/LICENSE +661 -0
- package/books/sunan-abi-dawud/README.md +149 -0
- package/books/sunan-abi-dawud/bin/index.js +183 -0
- package/books/sunan-abi-dawud/data/dawud.json.gz +0 -0
- package/books/sunan-abi-dawud/examples/express/server.js +7 -0
- package/books/sunan-abi-dawud/examples/node-commonjs/example.js +7 -0
- package/books/sunan-abi-dawud/examples/node-esm/example.mjs +6 -0
- package/books/sunan-abi-dawud/examples/react/HadithExample.jsx +17 -0
- package/books/sunan-abi-dawud/package.json +58 -0
- package/books/sunan-abi-dawud/src/index.cjs +52 -0
- package/books/sunan-abi-dawud/src/index.js +35 -0
- package/books/sunan-abi-dawud/src/index.node.js +18 -0
- package/books/sunan-abi-dawud/types/index.d.ts +28 -0
- package/books/sunan-ibn-majah/README.md +198 -0
- package/books/sunan-ibn-majah/bin/index.js +138 -0
- package/books/sunan-ibn-majah/examples/express/server.js +8 -0
- package/books/sunan-ibn-majah/examples/node-commonjs/example.js +7 -0
- package/books/sunan-ibn-majah/examples/node-esm/example.mjs +6 -0
- package/books/sunan-ibn-majah/examples/react/HadithExample.jsx +17 -0
- package/books/sunan-ibn-majah/package.json +58 -0
- package/books/sunan-ibn-majah/src/index.cjs +52 -0
- package/books/sunan-ibn-majah/src/index.js +35 -0
- package/books/sunan-ibn-majah/src/index.node.js +18 -0
- package/books/sunan-ibn-majah/types/index.d.ts +28 -0
- package/package.json +39 -27
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<h1>
|
|
4
|
+
<img src="https://em-content.zobj.net/source/apple/391/mosque_1f54c.png" width="36" />
|
|
5
|
+
sahih-al-bukhari
|
|
6
|
+
</h1>
|
|
7
|
+
|
|
8
|
+
<p align="center">
|
|
9
|
+
<strong>The complete Sahih al-Bukhari — 7,277 hadiths, full Arabic & English.</strong><br />
|
|
10
|
+
One repo · one dataset · published on both <strong>npm</strong> and <strong>PyPI</strong>.
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<br />
|
|
14
|
+
|
|
15
|
+
<!-- Row 1: version badges -->
|
|
16
|
+
<p>
|
|
17
|
+
<a href="https://www.npmjs.com/package/sahih-al-bukhari" text-decoration="none">
|
|
18
|
+
<img src="https://img.shields.io/npm/v/sahih-al-bukhari?style=for-the-badge&logo=npm&logoColor=white&color=CB3837&labelColor=1a1a1a" alt="npm version" />
|
|
19
|
+
</a><a href="https://pypi.org/project/sahih-al-bukhari/" text-decoration="none">
|
|
20
|
+
<img src="https://img.shields.io/pypi/v/sahih-al-bukhari?style=for-the-badge&logo=pypi&logoColor=white&color=3775A9&labelColor=1a1a1a" alt="PyPI version" />
|
|
21
|
+
</a><a href="https://github.com/SENODROOM/sahih-al-bukhari/blob/main/LICENSE" text-decoration="none">
|
|
22
|
+
<img src="https://img.shields.io/github/license/SENODROOM/sahih-al-bukhari?style=for-the-badge&logo=gnu&logoColor=white&color=A42E2B&labelColor=1a1a1a" alt="License: AGPL-3.0" />
|
|
23
|
+
</a>
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
<!-- Row 2: stats -->
|
|
27
|
+
<p>
|
|
28
|
+
<a href="https://www.npmjs.com/package/sahih-al-bukhari" text-decoration="none">
|
|
29
|
+
<img src="https://img.shields.io/npm/dt/sahih-al-bukhari?style=for-the-badge&logo=npm&logoColor=white&color=CB3837&labelColor=1a1a1a" alt="npm downloads" />
|
|
30
|
+
</a><a href="https://pypi.org/project/sahih-al-bukhari/" text-decoration="none">
|
|
31
|
+
<img src="https://img.shields.io/pypi/dm/sahih-al-bukhari?style=for-the-badge&logo=pypi&logoColor=white&color=3775A9&labelColor=1a1a1a" alt="PyPI monthly downloads" />
|
|
32
|
+
</a>
|
|
33
|
+
</p>
|
|
34
|
+
|
|
35
|
+
<!-- Row 3: repo stats -->
|
|
36
|
+
<p>
|
|
37
|
+
<a href="https://github.com/SENODROOM/sahih-al-bukhari/stargazers" text-decoration="none">
|
|
38
|
+
<img src="https://img.shields.io/github/stars/SENODROOM/sahih-al-bukhari?style=for-the-badge&logo=github&logoColor=white&color=f0c040&labelColor=1a1a1a" alt="GitHub stars" />
|
|
39
|
+
</a><a href="https://github.com/SENODROOM/sahih-al-bukhari/issues" text-decoration="none">
|
|
40
|
+
<img src="https://img.shields.io/github/issues/SENODROOM/sahih-al-bukhari?style=for-the-badge&logo=github&logoColor=white&color=238636&labelColor=1a1a1a" alt="GitHub issues" />
|
|
41
|
+
</a><a href="https://github.com/SENODROOM/sahih-al-bukhari/commits/main" text-decoration="none">
|
|
42
|
+
<img src="https://img.shields.io/github/last-commit/SENODROOM/sahih-al-bukhari?style=for-the-badge&logo=github&logoColor=white&color=8957e5&labelColor=1a1a1a" alt="Last commit" />
|
|
43
|
+
</a>
|
|
44
|
+
</p>
|
|
45
|
+
|
|
46
|
+
<!-- Row 4: tech -->
|
|
47
|
+
<p>
|
|
48
|
+
<img src="https://img.shields.io/badge/Node.js-%3E%3D14-339933?style=for-the-badge&logo=node.js&logoColor=white&labelColor=1a1a1a" alt="Node.js" /><img src="https://img.shields.io/badge/Python-%3E%3D3.8-3776AB?style=for-the-badge&logo=python&logoColor=white&labelColor=1a1a1a" alt="Python" /><img src="https://img.shields.io/badge/TypeScript-Typed-3178C6?style=for-the-badge&logo=typescript&logoColor=white&labelColor=1a1a1a" alt="TypeScript" /><img src="https://img.shields.io/badge/Zero-Dependencies-00C853?style=for-the-badge&logoColor=white&labelColor=1a1a1a" alt="Zero dependencies" />
|
|
49
|
+
</p>
|
|
50
|
+
|
|
51
|
+
<br />
|
|
52
|
+
|
|
53
|
+
[](https://nodei.co/npm/sahih-al-bukhari/)
|
|
54
|
+
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## ✨ Features at a Glance
|
|
60
|
+
|
|
61
|
+
| | Feature | Details |
|
|
62
|
+
| --- | ----------------------- | ------------------------------------------------------- |
|
|
63
|
+
| 📚 | **Complete Collection** | All 7,277 authentic hadiths from Sahih al-Bukhari |
|
|
64
|
+
| 🌐 | **Bilingual** | Full Arabic text + English translation for every hadith |
|
|
65
|
+
| 📝 | **Chapters** | 4,000+ chapters with Arabic & English names |
|
|
66
|
+
| ⚡ | **Tiny Install** | ~3KB package — data loaded from CDN on demand |
|
|
67
|
+
| 🔍 | **Full-text Search** | Search English text and narrator names instantly |
|
|
68
|
+
| 🖥️ | **CLI** | Terminal access with Arabic/English/both flags |
|
|
69
|
+
| ⚛️ | **React Hook** | One command generates `useBukhari()` in your project |
|
|
70
|
+
| 🐍 | **Python** | Identical API — same method names as the npm package |
|
|
71
|
+
| 📘 | **TypeScript** | Full type definitions, zero `@types` package needed |
|
|
72
|
+
| 🔧 | **Zero Config** | Works out of the box everywhere |
|
|
73
|
+
| 🗄️ | **One Dataset** | `bin/bukhari.json` shared by both JS and Python |
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 🚀 Installation
|
|
78
|
+
|
|
79
|
+
<table>
|
|
80
|
+
<tr>
|
|
81
|
+
<td><strong>JavaScript / Node.js</strong></td>
|
|
82
|
+
<td><strong>Python</strong></td>
|
|
83
|
+
</tr>
|
|
84
|
+
<tr>
|
|
85
|
+
<td>
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# local (for projects)
|
|
89
|
+
npm install sahih-al-bukhari
|
|
90
|
+
|
|
91
|
+
# global (for CLI)
|
|
92
|
+
npm install -g sahih-al-bukhari
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
</td>
|
|
96
|
+
<td>
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# local (for projects)
|
|
100
|
+
pip install sahih-al-bukhari
|
|
101
|
+
|
|
102
|
+
# global CLI is included automatically
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
</td>
|
|
106
|
+
</tr>
|
|
107
|
+
</table>
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 🟨 JavaScript / Node.js
|
|
112
|
+
|
|
113
|
+
### CommonJS & ESM
|
|
114
|
+
|
|
115
|
+
```javascript
|
|
116
|
+
// CommonJS — require()
|
|
117
|
+
const bukhari = require("sahih-al-bukhari");
|
|
118
|
+
|
|
119
|
+
// ESM — import
|
|
120
|
+
import bukhari from "sahih-al-bukhari";
|
|
121
|
+
|
|
122
|
+
// Get by ID
|
|
123
|
+
bukhari.get(1); // → Hadith
|
|
124
|
+
|
|
125
|
+
// Get by chapter
|
|
126
|
+
bukhari.getByChapter(1); // → Hadith[]
|
|
127
|
+
|
|
128
|
+
// Full-text search
|
|
129
|
+
bukhari.search("prayer"); // → Hadith[]
|
|
130
|
+
|
|
131
|
+
// Random
|
|
132
|
+
bukhari.getRandom(); // → Hadith
|
|
133
|
+
|
|
134
|
+
// Index access
|
|
135
|
+
bukhari[0]; // → Hadith (first)
|
|
136
|
+
bukhari.length; // → 7277
|
|
137
|
+
|
|
138
|
+
// Metadata
|
|
139
|
+
bukhari.metadata; // → { title, author, ... }
|
|
140
|
+
bukhari.chapters; // → Chapter[]
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Hadith object shape
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
{
|
|
147
|
+
id: 1,
|
|
148
|
+
chapterId: 1,
|
|
149
|
+
arabic: "حَدَّثَنَا الْحُمَيْدِيُّ...",
|
|
150
|
+
english: {
|
|
151
|
+
narrator: "Umar bin Al-Khattab",
|
|
152
|
+
text: "I heard Allah's Messenger (ﷺ) saying..."
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Native array methods — all work
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
bukhari.find((h) => h.id === 23);
|
|
161
|
+
bukhari.filter((h) => h.chapterId === 1);
|
|
162
|
+
bukhari.map((h) => h.english.narrator);
|
|
163
|
+
bukhari.forEach((h) => console.log(h.id));
|
|
164
|
+
bukhari.slice(0, 10);
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## ⚛️ React / Vue / Vite
|
|
170
|
+
|
|
171
|
+
Run this **once** inside your React project:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
cd my-react-app
|
|
175
|
+
bukhari --react
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
This auto-generates `src/hooks/useBukhari.js`. Then use it anywhere:
|
|
179
|
+
|
|
180
|
+
```jsx
|
|
181
|
+
import { useBukhari } from "../hooks/useBukhari";
|
|
182
|
+
|
|
183
|
+
function HadithOfTheDay() {
|
|
184
|
+
const bukhari = useBukhari();
|
|
185
|
+
if (!bukhari) return <p>Loading...</p>;
|
|
186
|
+
|
|
187
|
+
const h = bukhari.getRandom();
|
|
188
|
+
return (
|
|
189
|
+
<div>
|
|
190
|
+
<p>
|
|
191
|
+
<strong>{h.english.narrator}</strong>
|
|
192
|
+
</p>
|
|
193
|
+
<p>{h.english.text}</p>
|
|
194
|
+
</div>
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
```jsx
|
|
200
|
+
// Search example
|
|
201
|
+
function HadithSearch() {
|
|
202
|
+
const bukhari = useBukhari();
|
|
203
|
+
const [results, setResults] = useState([]);
|
|
204
|
+
if (!bukhari) return <p>Loading...</p>;
|
|
205
|
+
|
|
206
|
+
return (
|
|
207
|
+
<>
|
|
208
|
+
<input
|
|
209
|
+
placeholder="Search hadiths..."
|
|
210
|
+
onChange={(e) => setResults(bukhari.search(e.target.value, 10))}
|
|
211
|
+
/>
|
|
212
|
+
{results.map((h) => (
|
|
213
|
+
<p key={h.id}>{h.english.text}</p>
|
|
214
|
+
))}
|
|
215
|
+
</>
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
> Data is fetched from jsDelivr CDN once and cached globally. All components share the same request — no duplicates.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 🐍 Python
|
|
225
|
+
|
|
226
|
+
The Python API is **identical** to the npm package — same camelCase method names, same behaviour.
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
from sahih_al_bukhari import Bukhari
|
|
230
|
+
|
|
231
|
+
bukhari = Bukhari() # reads bin/bukhari.json if in repo, else fetches from CDN
|
|
232
|
+
|
|
233
|
+
# Exact same API as JS
|
|
234
|
+
bukhari.get(1) # Hadith | None
|
|
235
|
+
bukhari.getByChapter(1) # list[Hadith]
|
|
236
|
+
bukhari.search("prayer") # list[Hadith]
|
|
237
|
+
bukhari.search("prayer", limit=5) # list[Hadith] — top 5
|
|
238
|
+
bukhari.getRandom() # Hadith
|
|
239
|
+
|
|
240
|
+
# Index access & iteration
|
|
241
|
+
bukhari[0] # first hadith
|
|
242
|
+
bukhari.length # 7277
|
|
243
|
+
len(bukhari) # 7277
|
|
244
|
+
for h in bukhari: print(h.id)
|
|
245
|
+
|
|
246
|
+
# Array-style methods (matches JS prototype)
|
|
247
|
+
bukhari.find(lambda h: h.id == 23)
|
|
248
|
+
bukhari.filter(lambda h: h.chapterId == 1)
|
|
249
|
+
bukhari.map(lambda h: h.narrator)
|
|
250
|
+
bukhari.slice(0, 10)
|
|
251
|
+
|
|
252
|
+
# Metadata
|
|
253
|
+
bukhari.metadata.english # {"title": ..., "author": ...}
|
|
254
|
+
bukhari.chapters # list[Chapter]
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Custom data path
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
# Use your own bukhari.json at any path
|
|
261
|
+
bukhari = Bukhari(data_path="/absolute/path/to/bukhari.json")
|
|
262
|
+
bukhari = Bukhari(data_path=Path(__file__).parent / "bukhari.json")
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Flask API example
|
|
266
|
+
|
|
267
|
+
```python
|
|
268
|
+
from flask import Flask, jsonify, request
|
|
269
|
+
from sahih_al_bukhari import Bukhari
|
|
270
|
+
|
|
271
|
+
app = Flask(__name__)
|
|
272
|
+
bukhari = Bukhari()
|
|
273
|
+
|
|
274
|
+
@app.get("/api/hadith/random")
|
|
275
|
+
def random_hadith():
|
|
276
|
+
return jsonify(bukhari.getRandom().to_dict())
|
|
277
|
+
|
|
278
|
+
@app.get("/api/hadith/<int:hadith_id>")
|
|
279
|
+
def get_hadith(hadith_id):
|
|
280
|
+
h = bukhari.get(hadith_id)
|
|
281
|
+
return jsonify(h.to_dict()) if h else ("Not found", 404)
|
|
282
|
+
|
|
283
|
+
@app.get("/api/search")
|
|
284
|
+
def search():
|
|
285
|
+
return jsonify([h.to_dict() for h in bukhari.search(request.args.get("q", ""), limit=20)])
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 🖥️ CLI
|
|
291
|
+
|
|
292
|
+
The same `bukhari` command works whether installed via **npm** or **pip**.
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
# By ID
|
|
296
|
+
bukhari 1
|
|
297
|
+
bukhari 2345
|
|
298
|
+
|
|
299
|
+
# Within a chapter
|
|
300
|
+
bukhari 23 34
|
|
301
|
+
|
|
302
|
+
# Language flags
|
|
303
|
+
bukhari 2345 # English only (default)
|
|
304
|
+
bukhari 2345 -a # Arabic only
|
|
305
|
+
bukhari 2345 --arabic # Arabic only
|
|
306
|
+
bukhari 2345 -b # Arabic + English
|
|
307
|
+
bukhari 2345 --both # Arabic + English
|
|
308
|
+
|
|
309
|
+
# Search
|
|
310
|
+
bukhari --search "prayer"
|
|
311
|
+
bukhari --search "fasting" --all # show all results (default: top 5)
|
|
312
|
+
|
|
313
|
+
# Chapter listing
|
|
314
|
+
bukhari --chapter 5
|
|
315
|
+
|
|
316
|
+
# Random
|
|
317
|
+
bukhari --random
|
|
318
|
+
bukhari --random -b
|
|
319
|
+
|
|
320
|
+
# React hook generator (JS only — run inside your React project)
|
|
321
|
+
bukhari --react
|
|
322
|
+
|
|
323
|
+
# Info
|
|
324
|
+
bukhari --version
|
|
325
|
+
bukhari --help
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Example output
|
|
329
|
+
|
|
330
|
+
```
|
|
331
|
+
════════════════════════════════════════════════════════════
|
|
332
|
+
Hadith #1 | Chapter: 1 — Revelation
|
|
333
|
+
════════════════════════════════════════════════════════════
|
|
334
|
+
Narrator: Umar bin Al-Khattab
|
|
335
|
+
|
|
336
|
+
I heard Allah's Messenger (ﷺ) saying, "The reward of deeds
|
|
337
|
+
depends upon the intentions and every person will get the
|
|
338
|
+
reward according to what he has intended..."
|
|
339
|
+
════════════════════════════════════════════════════════════
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## 🗄️ Monorepo Structure
|
|
345
|
+
|
|
346
|
+
```
|
|
347
|
+
sahih-al-bukhari/
|
|
348
|
+
│
|
|
349
|
+
├── bin/
|
|
350
|
+
│ ├── bukhari.json ← 🔑 SHARED — single source of truth for JS + Python
|
|
351
|
+
│ └── index.js ← JS CLI entry
|
|
352
|
+
│
|
|
353
|
+
├── chapters/ ← 🔑 SHARED — generated by `node build.mjs`
|
|
354
|
+
│ ├── meta.json used by CDN loader (JS browser) + Python CDN fallback
|
|
355
|
+
│ ├── 1.json
|
|
356
|
+
│ └── ...
|
|
357
|
+
│
|
|
358
|
+
├── sahih_al_bukhari/ ← Python package
|
|
359
|
+
│ ├── __init__.py
|
|
360
|
+
│ ├── bukhari.py ← auto-reads bin/bukhari.json
|
|
361
|
+
│ └── cli.py
|
|
362
|
+
│
|
|
363
|
+
├── index.js ← JS ESM (browser-safe)
|
|
364
|
+
├── index.cjs ← JS CommonJS
|
|
365
|
+
├── index.node.js ← JS Node ESM
|
|
366
|
+
├── index.browser.js ← JS browser / CDN (auto-generated)
|
|
367
|
+
├── index.d.ts ← TypeScript definitions
|
|
368
|
+
├── build.mjs ← generates chapters/ from bin/bukhari.json
|
|
369
|
+
│
|
|
370
|
+
├── package.json ← npm config
|
|
371
|
+
├── pyproject.toml ← Python / Poetry config
|
|
372
|
+
├── MANIFEST.in ← Python sdist: include data, exclude JS
|
|
373
|
+
└── .npmignore ← npm publish: exclude Python files
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### Shared data — how it works
|
|
377
|
+
|
|
378
|
+
| File | Used by |
|
|
379
|
+
| ------------------ | ----------------------------------------------------------- |
|
|
380
|
+
| `bin/bukhari.json` | JS Node (CJS + ESM) · Python (auto-detected from repo root) |
|
|
381
|
+
| `chapters/` | JS browser CDN fetch · Python CDN fallback |
|
|
382
|
+
|
|
383
|
+
**You never duplicate data.** Both packages read the exact same file.
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## 📊 API Reference
|
|
388
|
+
|
|
389
|
+
### Methods
|
|
390
|
+
|
|
391
|
+
| Method | JS | Python | Returns |
|
|
392
|
+
| ----------------------- | --- | ------ | -------------------------- |
|
|
393
|
+
| `get(id)` | ✅ | ✅ | `Hadith \| undefined/None` |
|
|
394
|
+
| `getByChapter(id)` | ✅ | ✅ | `Hadith[]` |
|
|
395
|
+
| `search(query, limit?)` | ✅ | ✅ | `Hadith[]` |
|
|
396
|
+
| `getRandom()` | ✅ | ✅ | `Hadith` |
|
|
397
|
+
| `find(predicate)` | ✅ | ✅ | `Hadith \| undefined/None` |
|
|
398
|
+
| `filter(predicate)` | ✅ | ✅ | `Hadith[]` |
|
|
399
|
+
| `map(fn)` | ✅ | ✅ | `any[]` |
|
|
400
|
+
| `forEach(fn)` | ✅ | ✅ | `void/None` |
|
|
401
|
+
| `slice(start, end)` | ✅ | ✅ | `Hadith[]` |
|
|
402
|
+
|
|
403
|
+
### Properties
|
|
404
|
+
|
|
405
|
+
| Property | Type | Description |
|
|
406
|
+
| ---------- | -------------- | --------------------------- |
|
|
407
|
+
| `length` | `number / int` | Total hadiths — 7,277 |
|
|
408
|
+
| `metadata` | `Metadata` | Title, author, introduction |
|
|
409
|
+
| `chapters` | `Chapter[]` | All chapters |
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
## 💡 Examples
|
|
414
|
+
|
|
415
|
+
<details>
|
|
416
|
+
<summary><strong>Seed a MongoDB database (Node.js)</strong></summary>
|
|
417
|
+
|
|
418
|
+
```javascript
|
|
419
|
+
import { MongoClient } from "mongodb";
|
|
420
|
+
import bukhari from "sahih-al-bukhari";
|
|
421
|
+
|
|
422
|
+
const client = new MongoClient(process.env.MONGO_URI);
|
|
423
|
+
await client.connect();
|
|
424
|
+
await client
|
|
425
|
+
.db("islam")
|
|
426
|
+
.collection("hadiths")
|
|
427
|
+
.insertMany([...bukhari]);
|
|
428
|
+
await client.close();
|
|
429
|
+
console.log("Seeded", bukhari.length, "hadiths");
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
</details>
|
|
433
|
+
|
|
434
|
+
<details>
|
|
435
|
+
<summary><strong>Seed a database (Python)</strong></summary>
|
|
436
|
+
|
|
437
|
+
```python
|
|
438
|
+
from sahih_al_bukhari import Bukhari
|
|
439
|
+
|
|
440
|
+
bukhari = Bukhari()
|
|
441
|
+
records = [h.to_dict() for h in bukhari]
|
|
442
|
+
# Insert into any DB
|
|
443
|
+
print(f"Seeded {len(records)} hadiths")
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
</details>
|
|
447
|
+
|
|
448
|
+
<details>
|
|
449
|
+
<summary><strong>Thematic search</strong></summary>
|
|
450
|
+
|
|
451
|
+
```python
|
|
452
|
+
from sahih_al_bukhari import Bukhari
|
|
453
|
+
|
|
454
|
+
bukhari = Bukhari()
|
|
455
|
+
topics = ["prayer", "charity", "fasting", "knowledge", "patience"]
|
|
456
|
+
for topic in topics:
|
|
457
|
+
count = len(bukhari.search(topic))
|
|
458
|
+
print(f"{topic:12} → {count} hadiths")
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
</details>
|
|
462
|
+
|
|
463
|
+
<details>
|
|
464
|
+
<summary><strong>Express.js REST API</strong></summary>
|
|
465
|
+
|
|
466
|
+
```javascript
|
|
467
|
+
import express from "express";
|
|
468
|
+
import bukhari from "sahih-al-bukhari";
|
|
469
|
+
|
|
470
|
+
const app = express();
|
|
471
|
+
|
|
472
|
+
app.get("/api/hadith/random", (_, res) => res.json(bukhari.getRandom()));
|
|
473
|
+
app.get("/api/hadith/:id", (req, res) => {
|
|
474
|
+
const h = bukhari.get(parseInt(req.params.id));
|
|
475
|
+
h ? res.json(h) : res.status(404).json({ error: "Not found" });
|
|
476
|
+
});
|
|
477
|
+
app.get("/api/search", (req, res) =>
|
|
478
|
+
res.json(bukhari.search(req.query.q || "")),
|
|
479
|
+
);
|
|
480
|
+
app.get("/api/chapter/:id", (req, res) =>
|
|
481
|
+
res.json(bukhari.getByChapter(parseInt(req.params.id))),
|
|
482
|
+
);
|
|
483
|
+
|
|
484
|
+
app.listen(3000, () => console.log("Running on :3000"));
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
</details>
|
|
488
|
+
|
|
489
|
+
---
|
|
490
|
+
|
|
491
|
+
## 🔧 Development
|
|
492
|
+
|
|
493
|
+
```bash
|
|
494
|
+
git clone https://github.com/SENODROOM/sahih-al-bukhari.git
|
|
495
|
+
cd sahih-al-bukhari
|
|
496
|
+
npm install
|
|
497
|
+
|
|
498
|
+
# Regenerate chapters/ from bin/bukhari.json
|
|
499
|
+
node build.mjs
|
|
500
|
+
|
|
501
|
+
# Publish to npm
|
|
502
|
+
npm publish
|
|
503
|
+
|
|
504
|
+
# Publish to PyPI
|
|
505
|
+
pip install build twine
|
|
506
|
+
python -m build
|
|
507
|
+
python -m twine upload dist/*
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
## 🤝 Contributing
|
|
513
|
+
|
|
514
|
+
Contributions are welcome!
|
|
515
|
+
|
|
516
|
+
1. Fork the repository
|
|
517
|
+
2. Create a branch: `git checkout -b feature/my-feature`
|
|
518
|
+
3. Commit: `git commit -m 'Add my feature'`
|
|
519
|
+
4. Push: `git push origin feature/my-feature`
|
|
520
|
+
5. Open a Pull Request
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
## 📄 License
|
|
525
|
+
|
|
526
|
+
Licensed under the **GNU Affero General Public License v3.0 (AGPL-3.0)** — see [LICENSE](LICENSE) for details.
|
|
527
|
+
|
|
528
|
+
---
|
|
529
|
+
|
|
530
|
+
## 🙏 Acknowledgments
|
|
531
|
+
|
|
532
|
+
- **📖 Source** — Sahih al-Bukhari, the most authentic hadith collection in Islam
|
|
533
|
+
- **👨🏫 Translations** — By reputable Islamic scholars
|
|
534
|
+
- **💚 Inspiration** — The global Muslim community seeking knowledge
|
|
535
|
+
|
|
536
|
+
---
|
|
537
|
+
|
|
538
|
+
<div align="center">
|
|
539
|
+
|
|
540
|
+
### 🌟 If this project helped you, please give it a star!
|
|
541
|
+
|
|
542
|
+
[](https://github.com/SENODROOM/sahih-al-bukhari/stargazers)
|
|
543
|
+
[](https://github.com/SENODROOM/sahih-al-bukhari/fork)
|
|
544
|
+
|
|
545
|
+
<br />
|
|
546
|
+
|
|
547
|
+
**Made with ❤️ for the Muslim community · Seeking knowledge together**
|
|
548
|
+
|
|
549
|
+
[📖 Docs](https://github.com/SENODROOM/sahih-al-bukhari#readme) · [🐛 Issues](https://github.com/SENODROOM/sahih-al-bukhari/issues) · [💬 Discussions](https://github.com/SENODROOM/sahih-al-bukhari/discussions)
|
|
550
|
+
|
|
551
|
+
</div>
|