sunnah 1.4.0 → 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.
Files changed (65) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +258 -398
  3. package/bin/index.js +1022 -1604
  4. package/books/jami-al-tirmidhi/README.md +201 -0
  5. package/books/jami-al-tirmidhi/bin/index.js +165 -0
  6. package/books/jami-al-tirmidhi/examples/express/server.js +7 -0
  7. package/books/jami-al-tirmidhi/examples/node-commonjs/example.js +7 -0
  8. package/books/jami-al-tirmidhi/examples/node-esm/example.mjs +6 -0
  9. package/books/jami-al-tirmidhi/examples/react/HadithExample.jsx +17 -0
  10. package/books/jami-al-tirmidhi/package.json +58 -0
  11. package/books/jami-al-tirmidhi/src/index.cjs +52 -0
  12. package/books/jami-al-tirmidhi/src/index.js +35 -0
  13. package/books/jami-al-tirmidhi/src/index.node.js +18 -0
  14. package/books/jami-al-tirmidhi/types/index.d.ts +28 -0
  15. package/books/sahih-al-bukhari/README.md +551 -0
  16. package/books/sahih-al-bukhari/bin/index.js +306 -0
  17. package/books/sahih-al-bukhari/data/bukhari.json.gz +0 -0
  18. package/books/sahih-al-bukhari/examples/express/server.js +49 -0
  19. package/books/sahih-al-bukhari/examples/node-commonjs/example.js +21 -0
  20. package/books/sahih-al-bukhari/examples/node-esm/example.mjs +24 -0
  21. package/books/sahih-al-bukhari/examples/react/HadithExample.jsx +73 -0
  22. package/books/sahih-al-bukhari/package.json +54 -0
  23. package/books/sahih-al-bukhari/src/index.cjs +55 -0
  24. package/books/sahih-al-bukhari/src/index.js +35 -0
  25. package/books/sahih-al-bukhari/src/index.node.js +21 -0
  26. package/books/sahih-al-bukhari/types/index.d.ts +35 -0
  27. package/books/sahih-muslim/LICENSE +661 -0
  28. package/books/sahih-muslim/README.md +547 -0
  29. package/books/sahih-muslim/bin/index.js +183 -0
  30. package/books/sahih-muslim/data/muslim.json.gz +0 -0
  31. package/books/sahih-muslim/examples/express/server.js +16 -0
  32. package/books/sahih-muslim/examples/node-commonjs/example.js +11 -0
  33. package/books/sahih-muslim/examples/node-esm/example.mjs +9 -0
  34. package/books/sahih-muslim/examples/react/HadithExample.jsx +28 -0
  35. package/books/sahih-muslim/package.json +58 -0
  36. package/books/sahih-muslim/src/index.cjs +52 -0
  37. package/books/sahih-muslim/src/index.js +35 -0
  38. package/books/sahih-muslim/src/index.node.js +18 -0
  39. package/books/sahih-muslim/types/index.d.ts +28 -0
  40. package/books/sunan-abi-dawud/LICENSE +661 -0
  41. package/books/sunan-abi-dawud/README.md +149 -0
  42. package/books/sunan-abi-dawud/bin/index.js +183 -0
  43. package/books/sunan-abi-dawud/data/dawud.json.gz +0 -0
  44. package/books/sunan-abi-dawud/examples/express/server.js +7 -0
  45. package/books/sunan-abi-dawud/examples/node-commonjs/example.js +7 -0
  46. package/books/sunan-abi-dawud/examples/node-esm/example.mjs +6 -0
  47. package/books/sunan-abi-dawud/examples/react/HadithExample.jsx +17 -0
  48. package/books/sunan-abi-dawud/package.json +58 -0
  49. package/books/sunan-abi-dawud/src/index.cjs +52 -0
  50. package/books/sunan-abi-dawud/src/index.js +35 -0
  51. package/books/sunan-abi-dawud/src/index.node.js +18 -0
  52. package/books/sunan-abi-dawud/types/index.d.ts +28 -0
  53. package/books/sunan-ibn-majah/README.md +198 -0
  54. package/books/sunan-ibn-majah/bin/index.js +138 -0
  55. package/books/sunan-ibn-majah/examples/express/server.js +8 -0
  56. package/books/sunan-ibn-majah/examples/node-commonjs/example.js +7 -0
  57. package/books/sunan-ibn-majah/examples/node-esm/example.mjs +6 -0
  58. package/books/sunan-ibn-majah/examples/react/HadithExample.jsx +17 -0
  59. package/books/sunan-ibn-majah/package.json +58 -0
  60. package/books/sunan-ibn-majah/src/index.cjs +52 -0
  61. package/books/sunan-ibn-majah/src/index.js +35 -0
  62. package/books/sunan-ibn-majah/src/index.node.js +18 -0
  63. package/books/sunan-ibn-majah/types/index.d.ts +28 -0
  64. package/package.json +39 -27
  65. /package/{LICENSE → books/sahih-al-bukhari/LICENSE} +0 -0
@@ -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
+ &nbsp;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
+ [![NPM](https://nodei.co/npm/sahih-al-bukhari.png?downloads=true&downloadRank=true&stars=true)](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
+ [![GitHub stars](https://img.shields.io/github/stars/SENODROOM/sahih-al-bukhari?style=for-the-badge&logo=github&logoColor=white&color=f0c040&labelColor=1a1a1a)](https://github.com/SENODROOM/sahih-al-bukhari/stargazers)
543
+ [![GitHub forks](https://img.shields.io/github/forks/SENODROOM/sahih-al-bukhari?style=for-the-badge&logo=github&logoColor=white&color=8957e5&labelColor=1a1a1a)](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>