@ihsandeen/aya 1.0.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 (112) hide show
  1. package/CONTRIBUTING.md +39 -0
  2. package/LICENSE +21 -0
  3. package/README.md +141 -0
  4. package/dist/commands/adab.js +28 -0
  5. package/dist/commands/adhan.js +58 -0
  6. package/dist/commands/anatomy.js +29 -0
  7. package/dist/commands/blame.js +29 -0
  8. package/dist/commands/commit.js +44 -0
  9. package/dist/commands/diff.js +54 -0
  10. package/dist/commands/dua.js +34 -0
  11. package/dist/commands/fast.js +36 -0
  12. package/dist/commands/friday.js +21 -0
  13. package/dist/commands/hero.js +69 -0
  14. package/dist/commands/hijri.js +42 -0
  15. package/dist/commands/history.js +98 -0
  16. package/dist/commands/init.js +54 -0
  17. package/dist/commands/invest.js +26 -0
  18. package/dist/commands/journal.js +84 -0
  19. package/dist/commands/journey.js +24 -0
  20. package/dist/commands/lens.js +58 -0
  21. package/dist/commands/memorize.js +117 -0
  22. package/dist/commands/mirror.js +47 -0
  23. package/dist/commands/names.js +48 -0
  24. package/dist/commands/nature.js +28 -0
  25. package/dist/commands/nazm.js +100 -0
  26. package/dist/commands/parable.js +332 -0
  27. package/dist/commands/prayers.js +63 -0
  28. package/dist/commands/pull.js +28 -0
  29. package/dist/commands/push.js +156 -0
  30. package/dist/commands/qibla.js +118 -0
  31. package/dist/commands/repo.js +34 -0
  32. package/dist/commands/sabr.js +32 -0
  33. package/dist/commands/scene.js +54 -0
  34. package/dist/commands/seek.js +28 -0
  35. package/dist/commands/shukr.js +22 -0
  36. package/dist/commands/sleep.js +26 -0
  37. package/dist/commands/sound.js +35 -0
  38. package/dist/commands/status.js +109 -0
  39. package/dist/commands/sunnah.js +24 -0
  40. package/dist/commands/tafsir.js +89 -0
  41. package/dist/commands/tasbih.js +50 -0
  42. package/dist/commands/wudu.js +22 -0
  43. package/dist/commands/zakat.js +72 -0
  44. package/dist/data/commands-db.js +365 -0
  45. package/dist/data/events.js +105 -0
  46. package/dist/data/gems.js +160 -0
  47. package/dist/data/nak.js +616 -0
  48. package/dist/data/tafsir.js +157 -0
  49. package/dist/data/vocab.js +105 -0
  50. package/dist/index.js +86 -0
  51. package/dist/server.js +140 -0
  52. package/dist/utils/config.js +38 -0
  53. package/dist/utils/logger.js +104 -0
  54. package/dist/utils/printer.js +36 -0
  55. package/docs/index.html +1048 -0
  56. package/docs/repo.html +952 -0
  57. package/package.json +55 -0
  58. package/public/hero.html +285 -0
  59. package/public/index.html +1039 -0
  60. package/public/repo.html +904 -0
  61. package/src/commands/adab.ts +24 -0
  62. package/src/commands/adhan.ts +55 -0
  63. package/src/commands/anatomy.ts +25 -0
  64. package/src/commands/blame.ts +31 -0
  65. package/src/commands/commit.ts +42 -0
  66. package/src/commands/diff.ts +56 -0
  67. package/src/commands/dua.ts +34 -0
  68. package/src/commands/fast.ts +35 -0
  69. package/src/commands/friday.ts +17 -0
  70. package/src/commands/hero.ts +73 -0
  71. package/src/commands/hijri.ts +43 -0
  72. package/src/commands/history.ts +103 -0
  73. package/src/commands/init.ts +53 -0
  74. package/src/commands/invest.ts +22 -0
  75. package/src/commands/journal.ts +97 -0
  76. package/src/commands/journey.ts +20 -0
  77. package/src/commands/lens.ts +58 -0
  78. package/src/commands/memorize.ts +131 -0
  79. package/src/commands/mirror.ts +48 -0
  80. package/src/commands/names.ts +46 -0
  81. package/src/commands/nature.ts +24 -0
  82. package/src/commands/nazm.ts +102 -0
  83. package/src/commands/parable.ts +360 -0
  84. package/src/commands/prayers.ts +65 -0
  85. package/src/commands/pull.ts +28 -0
  86. package/src/commands/push.ts +171 -0
  87. package/src/commands/qibla.ts +127 -0
  88. package/src/commands/repo.ts +34 -0
  89. package/src/commands/sabr.ts +28 -0
  90. package/src/commands/scene.ts +56 -0
  91. package/src/commands/seek.ts +24 -0
  92. package/src/commands/shukr.ts +19 -0
  93. package/src/commands/sleep.ts +23 -0
  94. package/src/commands/sound.ts +34 -0
  95. package/src/commands/status.ts +132 -0
  96. package/src/commands/sunnah.ts +21 -0
  97. package/src/commands/tafsir.ts +86 -0
  98. package/src/commands/tasbih.ts +49 -0
  99. package/src/commands/wudu.ts +19 -0
  100. package/src/commands/zakat.ts +73 -0
  101. package/src/data/commands-db.ts +372 -0
  102. package/src/data/events.ts +113 -0
  103. package/src/data/gems.ts +163 -0
  104. package/src/data/nak.ts +805 -0
  105. package/src/data/tafsir.ts +165 -0
  106. package/src/data/vocab.ts +114 -0
  107. package/src/index.ts +94 -0
  108. package/src/server.ts +128 -0
  109. package/src/utils/config.ts +44 -0
  110. package/src/utils/logger.ts +122 -0
  111. package/src/utils/printer.ts +38 -0
  112. package/tsconfig.json +16 -0
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.qiblaCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const axios_1 = __importDefault(require("axios"));
10
+ const config_1 = require("../utils/config");
11
+ const ora_1 = __importDefault(require("ora"));
12
+ const inquirer_1 = __importDefault(require("inquirer"));
13
+ const printer_1 = require("../utils/printer");
14
+ exports.qiblaCommand = new commander_1.Command('qibla')
15
+ .description('Find the direction and distance to the Kaaba')
16
+ .action(async () => {
17
+ (0, printer_1.printCommandHeader)('qibla');
18
+ let config = (0, config_1.getConfig)();
19
+ let city = config.location?.city;
20
+ let country = config.location?.country;
21
+ if (!city || !country) {
22
+ console.log(chalk_1.default.yellow('Location not configured.'));
23
+ const answers = await inquirer_1.default.prompt([
24
+ { type: 'input', name: 'city', message: 'Enter your city:' },
25
+ { type: 'input', name: 'country', message: 'Enter your country:' }
26
+ ]);
27
+ city = answers.city;
28
+ country = answers.country;
29
+ }
30
+ const spinner = (0, ora_1.default)(`Locating Kaaba from ${city}, ${country}...`).start();
31
+ try {
32
+ // 1. Get coordinates for the city
33
+ const response = await axios_1.default.get('http://api.aladhan.com/v1/timingsByCity', {
34
+ params: { city, country }
35
+ });
36
+ const meta = response.data.data.meta;
37
+ const lat = meta.latitude;
38
+ const long = meta.longitude;
39
+ // 2. Get Qibla direction
40
+ const qiblaResponse = await axios_1.default.get(`http://api.aladhan.com/v1/qibla/${lat}/${long}`);
41
+ const direction = qiblaResponse.data.data.direction; // Degrees from North
42
+ spinner.stop();
43
+ console.clear();
44
+ console.log(chalk_1.default.green.bold('\n Qibla Finder'));
45
+ console.log(chalk_1.default.gray('----------------------------------------'));
46
+ console.log(chalk_1.default.white(`Location: ${chalk_1.default.bold(city)}, ${country}`));
47
+ console.log(chalk_1.default.white(`Coordinates: ${lat}, ${long}`));
48
+ console.log(chalk_1.default.cyan.bold(`Qibla Direction: ${Math.round(direction)}° from North (Clockwise)`));
49
+ console.log('');
50
+ // Calculate Distance (Haversine Formula)
51
+ // Kaaba coordinates: 21.4225° N, 39.8262° E
52
+ const kaabaLat = 21.4225;
53
+ const kaabaLong = 39.8262;
54
+ const distance = getDistanceFromLatLonInKm(lat, long, kaabaLat, kaabaLong);
55
+ console.log(chalk_1.default.blue(`Distance to Kaaba: ${Math.round(distance).toLocaleString()} km`));
56
+ console.log('');
57
+ // ASCII Compass Visualization
58
+ drawCompass(direction);
59
+ console.log('');
60
+ console.log(chalk_1.default.gray('Turn your face towards the Sacred Mosque.'));
61
+ console.log(chalk_1.default.italic('"So turn your face toward al-Masjid al-Haram." (2:144)'));
62
+ }
63
+ catch (error) {
64
+ spinner.fail('Could not calculate Qibla.');
65
+ console.error(chalk_1.default.red('Please check your internet connection or location settings.'));
66
+ }
67
+ });
68
+ function drawCompass(degree) {
69
+ const needle = getArrow(degree);
70
+ const compass = `
71
+ N
72
+ |
73
+ W --+-- E
74
+ |
75
+ S
76
+ `;
77
+ // We can't easily rotate the whole compass in ASCII without complex logic.
78
+ // Instead, we show the needle direction relative to North.
79
+ console.log(chalk_1.default.yellow.bold(' N'));
80
+ console.log(chalk_1.default.yellow.bold(' |'));
81
+ // Show the direction arrow
82
+ console.log(chalk_1.default.green.bold(` ${needle} (${Math.round(degree)}°)`));
83
+ console.log(chalk_1.default.yellow.bold(' |'));
84
+ }
85
+ function getArrow(degree) {
86
+ const normalized = (degree % 360 + 360) % 360;
87
+ if (normalized >= 337.5 || normalized < 22.5)
88
+ return '^';
89
+ if (normalized >= 22.5 && normalized < 67.5)
90
+ return '/';
91
+ if (normalized >= 67.5 && normalized < 112.5)
92
+ return '>';
93
+ if (normalized >= 112.5 && normalized < 157.5)
94
+ return '\\';
95
+ if (normalized >= 157.5 && normalized < 202.5)
96
+ return 'v';
97
+ if (normalized >= 202.5 && normalized < 247.5)
98
+ return '/';
99
+ if (normalized >= 247.5 && normalized < 292.5)
100
+ return '<';
101
+ if (normalized >= 292.5 && normalized < 337.5)
102
+ return '\\';
103
+ return '^';
104
+ }
105
+ function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
106
+ const R = 6371; // Radius of the earth in km
107
+ const dLat = deg2rad(lat2 - lat1); // deg2rad below
108
+ const dLon = deg2rad(lon2 - lon1);
109
+ const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
110
+ Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
111
+ Math.sin(dLon / 2) * Math.sin(dLon / 2);
112
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
113
+ const d = R * c; // Distance in km
114
+ return d;
115
+ }
116
+ function deg2rad(deg) {
117
+ return deg * (Math.PI / 180);
118
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.repoCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const server_1 = require("../server");
9
+ const child_process_1 = require("child_process");
10
+ const chalk_1 = __importDefault(require("chalk"));
11
+ const ora_1 = __importDefault(require("ora"));
12
+ const printer_1 = require("../utils/printer");
13
+ exports.repoCommand = new commander_1.Command('repo')
14
+ .description('The Book of Deeds UI (Visualize your journey)')
15
+ .action(async () => {
16
+ (0, printer_1.printCommandHeader)('repo');
17
+ const spinner = (0, ora_1.default)('Opening your Book of Deeds in the browser...').start();
18
+ try {
19
+ const port = await (0, server_1.startServer)();
20
+ const url = `http://localhost:${port}/repo`;
21
+ spinner.succeed(chalk_1.default.green('Book of Deeds is open!'));
22
+ console.log(chalk_1.default.cyan(` ➜ ${url}`));
23
+ console.log(chalk_1.default.dim(' (Press Ctrl+C to close the connection)'));
24
+ // Open browser based on OS
25
+ const start = (process.platform == 'darwin' ? 'open' : process.platform == 'win32' ? 'start' : 'xdg-open');
26
+ (0, child_process_1.exec)(`${start} ${url}`);
27
+ // Keep the process alive is handled by the server.listen() inside startServer
28
+ // We don't need to do anything else, the node process will stay alive.
29
+ }
30
+ catch (error) {
31
+ spinner.fail('Could not open Book of Deeds.');
32
+ console.error(error);
33
+ }
34
+ });
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.sabrCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const inquirer_1 = __importDefault(require("inquirer"));
10
+ const nak_1 = require("../data/nak");
11
+ const printer_1 = require("../utils/printer");
12
+ exports.sabrCommand = new commander_1.Command('sabr')
13
+ .description('The Patience Diagnostic')
14
+ .action(async () => {
15
+ (0, printer_1.printCommandHeader)('sabr');
16
+ const { situation } = await inquirer_1.default.prompt([{
17
+ type: 'list',
18
+ name: 'situation',
19
+ message: 'What are you struggling with?',
20
+ choices: nak_1.sabrData.map(s => ({
21
+ name: `${s.type} (${s.arabic})`,
22
+ value: s.type
23
+ }))
24
+ }]);
25
+ const data = nak_1.sabrData.find(s => s.type === situation);
26
+ if (data) {
27
+ console.log(chalk_1.default.blue.bold(`\n Diagnosis: ${data.type} (${data.arabic})`));
28
+ console.log(chalk_1.default.white(` Definition: ${data.description}`));
29
+ console.log(chalk_1.default.gray(` Example: ${data.example}`));
30
+ console.log(chalk_1.default.green('\n Prescription: "Indeed, Allah is with the patient." (2:153)\n'));
31
+ }
32
+ });
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.sceneCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const inquirer_1 = __importDefault(require("inquirer"));
10
+ const nak_1 = require("../data/nak");
11
+ const printer_1 = require("../utils/printer");
12
+ const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
13
+ exports.sceneCommand = new commander_1.Command('scene')
14
+ .description('The Cinematic Visualizer (Tadabbur in 4K)')
15
+ .argument('[ref]', 'The Ayah reference (e.g. 82:1)')
16
+ .action(async (ref) => {
17
+ (0, printer_1.printCommandHeader)('scene');
18
+ let data = ref
19
+ ? nak_1.sceneData.find(s => s.ref.includes(ref) || s.surah.toLowerCase().includes(ref))
20
+ : null;
21
+ if (!data && ref) {
22
+ console.log(chalk_1.default.red('Scene not found for that reference.'));
23
+ }
24
+ if (!data) {
25
+ const { choice } = await inquirer_1.default.prompt([{
26
+ type: 'list',
27
+ name: 'choice',
28
+ message: 'Select a scene to visualize:',
29
+ choices: nak_1.sceneData.map(s => ({
30
+ name: `${s.surah} (${s.ayah}): ${s.title}`,
31
+ value: s
32
+ }))
33
+ }]);
34
+ data = choice;
35
+ }
36
+ if (!data)
37
+ return;
38
+ console.clear();
39
+ console.log(chalk_1.default.red.bold(`\n Aya Scene: ${data.title}`));
40
+ console.log(chalk_1.default.gray(`Surah ${data.surah} (${data.ayah})\n`));
41
+ // Display Lighting and Audio first to set the mood
42
+ console.log(chalk_1.default.yellow(' Lighting: ') + chalk_1.default.white(data.lighting));
43
+ console.log(chalk_1.default.cyan(' Audio: ') + chalk_1.default.white(data.audio));
44
+ console.log(chalk_1.default.gray('----------------------------------------\n'));
45
+ console.log(chalk_1.default.white.bold(' Shot List:'));
46
+ // Animate shots sequentially
47
+ for (let i = 0; i < data.shots.length; i++) {
48
+ const shot = data.shots[i];
49
+ await sleep(1000);
50
+ console.log(chalk_1.default.green(`\n[${i + 1}] ${shot.type}`));
51
+ console.log(chalk_1.default.white(` ${shot.description}`));
52
+ }
53
+ console.log('');
54
+ });
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.seekCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const inquirer_1 = __importDefault(require("inquirer"));
10
+ const nak_1 = require("../data/nak");
11
+ const printer_1 = require("../utils/printer");
12
+ exports.seekCommand = new commander_1.Command('seek')
13
+ .description('Contextual Quranic Search')
14
+ .action(async () => {
15
+ (0, printer_1.printCommandHeader)('seek');
16
+ const { topic } = await inquirer_1.default.prompt([{
17
+ type: 'list',
18
+ name: 'topic',
19
+ message: 'What topic are you looking for?',
20
+ choices: nak_1.searchData.map(s => s.keyword)
21
+ }]);
22
+ const data = nak_1.searchData.find(s => s.keyword === topic);
23
+ if (data) {
24
+ console.log(chalk_1.default.blue.bold(`\n Topic: ${data.keyword}`));
25
+ console.log(chalk_1.default.green(` Ayah: ${data.ayah}`));
26
+ console.log(chalk_1.default.white(` Context (The "Why"): ${data.context}\n`));
27
+ }
28
+ });
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.shukrCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const nak_1 = require("../data/nak");
10
+ const printer_1 = require("../utils/printer");
11
+ exports.shukrCommand = new commander_1.Command('shukr')
12
+ .description('The Gratitude Reality Check')
13
+ .action(() => {
14
+ (0, printer_1.printCommandHeader)('shukr');
15
+ console.log(chalk_1.default.yellow.bold('\n The 3 Levels of Shukr (Gratitude)\n'));
16
+ nak_1.shukrData.forEach((level) => {
17
+ console.log(chalk_1.default.blue.bold(` Level: ${level.level}`));
18
+ console.log(chalk_1.default.white(` ${level.description}`));
19
+ console.log(chalk_1.default.green(` Reality: ${level.reality}\n`));
20
+ });
21
+ console.log(chalk_1.default.gray(' "If you are grateful, I will surely increase you." (14:7)'));
22
+ });
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.sleepCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const nak_1 = require("../data/nak");
10
+ const printer_1 = require("../utils/printer");
11
+ exports.sleepCommand = new commander_1.Command('sleep')
12
+ .description('The Minor Death (Sleep Adhkar)')
13
+ .action(async () => {
14
+ (0, printer_1.printCommandHeader)('sleep');
15
+ console.clear();
16
+ console.log(chalk_1.default.blue.bold('\n The Minor Death (An-Nawm)\n'));
17
+ console.log(chalk_1.default.gray(' "Allah takes the souls at the time of their death, and those that do not die [He takes] during their sleep." (39:42)\n'));
18
+ nak_1.sleepData.forEach(s => {
19
+ console.log(chalk_1.default.yellow.bold(` ${s.title}`));
20
+ console.log(chalk_1.default.green(` "${s.arabic}"`));
21
+ console.log(chalk_1.default.white(` "${s.translation}"`));
22
+ console.log(chalk_1.default.cyan.italic(` Reflection: ${s.reflection}\n`));
23
+ });
24
+ console.log(chalk_1.default.gray(' Good night. Reset your intentions for the resurrection (tomorrow).'));
25
+ console.log('\n');
26
+ });
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.soundCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const nak_1 = require("../data/nak");
10
+ const printer_1 = require("../utils/printer");
11
+ exports.soundCommand = new commander_1.Command('sound')
12
+ .description('Phonetic Storytelling (Tajweed as Tafsir)')
13
+ .argument('[ref]', 'The Ayah reference (e.g. 100:1)')
14
+ .action((ref) => {
15
+ (0, printer_1.printCommandHeader)('sound');
16
+ // If no ref, show available?
17
+ if (!ref) {
18
+ console.log(chalk_1.default.yellow('Please provide an Ayah reference to analyze.'));
19
+ console.log(chalk_1.default.gray('Available examples: 100:1, 113:1'));
20
+ return;
21
+ }
22
+ const data = nak_1.soundData.find(d => d.ref === ref || `${d.surah}:${d.ayah}` === ref);
23
+ if (!data) {
24
+ console.log(chalk_1.default.red('Sound analysis not found for that Ayah.'));
25
+ console.log(chalk_1.default.gray('Currently available: 100:1 (Al-Adiyat), 113:1 (Al-Falaq)'));
26
+ return;
27
+ }
28
+ console.clear();
29
+ console.log(chalk_1.default.cyan.bold(`\n Aya Sound: ${data.surah} (${data.ayah})`));
30
+ console.log(chalk_1.default.white.italic(`"${data.text}"`));
31
+ console.log(chalk_1.default.gray('----------------------------------------\n'));
32
+ console.log(chalk_1.default.green.bold('Phonetic Analysis:'));
33
+ console.log(chalk_1.default.white(data.analysis));
34
+ console.log('');
35
+ });
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.statusCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const axios_1 = __importDefault(require("axios"));
10
+ const date_fns_1 = require("date-fns");
11
+ const config_1 = require("../utils/config");
12
+ const ora_1 = __importDefault(require("ora"));
13
+ const printer_1 = require("../utils/printer");
14
+ const boxen_1 = __importDefault(require("boxen"));
15
+ exports.statusCommand = new commander_1.Command('status')
16
+ .description('Check your spiritual status (prayer times)')
17
+ .action(async () => {
18
+ (0, printer_1.printCommandHeader)('status');
19
+ const config = (0, config_1.getConfig)();
20
+ const city = config.location?.city || 'Mecca';
21
+ const country = config.location?.country || 'Saudi Arabia';
22
+ const spinner = (0, ora_1.default)(`Pinging the heavens for ${city}, ${country}...`).start();
23
+ try {
24
+ const response = await axios_1.default.get('http://api.aladhan.com/v1/timingsByCity', {
25
+ params: {
26
+ city,
27
+ country,
28
+ method: 2, // ISNA
29
+ }
30
+ });
31
+ const timings = response.data.data.timings;
32
+ const hijri = response.data.data.date.hijri;
33
+ const prayerNames = ['Fajr', 'Dhuhr', 'Asr', 'Maghrib', 'Isha'];
34
+ const now = new Date();
35
+ let nextPrayer = null;
36
+ let nextPrayerTime = null;
37
+ let missedPrayersCount = 0;
38
+ // Find next prayer logic...
39
+ for (const name of prayerNames) {
40
+ const timeStr = timings[name];
41
+ const [hours, minutes] = timeStr.split(':').map(Number);
42
+ const prayerDate = new Date();
43
+ prayerDate.setHours(hours, minutes, 0, 0);
44
+ if (prayerDate > now) {
45
+ if (!nextPrayer) {
46
+ nextPrayer = name;
47
+ nextPrayerTime = prayerDate;
48
+ }
49
+ }
50
+ else {
51
+ missedPrayersCount++;
52
+ }
53
+ }
54
+ if (!nextPrayer) {
55
+ nextPrayer = 'Fajr';
56
+ const timeStr = timings['Fajr'];
57
+ const [hours, minutes] = timeStr.split(':').map(Number);
58
+ const prayerDate = new Date();
59
+ prayerDate.setDate(prayerDate.getDate() + 1);
60
+ prayerDate.setHours(hours, minutes, 0, 0);
61
+ nextPrayerTime = prayerDate;
62
+ }
63
+ spinner.stop();
64
+ // NAK Style Status Output
65
+ console.log((0, boxen_1.default)(chalk_1.default.bold.green(` 🕌 Spiritual Status Report `) + '\n' +
66
+ chalk_1.default.dim(` Location: ${city}, ${country} `) + '\n' +
67
+ chalk_1.default.dim(` Date: ${hijri.day} ${hijri.month.en} ${hijri.year} AH `), {
68
+ padding: 1,
69
+ margin: 1,
70
+ borderStyle: 'round',
71
+ borderColor: 'green',
72
+ }));
73
+ console.log(chalk_1.default.bold.blue('📡 Connection Status:'));
74
+ console.log(` Your heart is currently on branch ${chalk_1.default.green("'dunya'")}.`);
75
+ if (missedPrayersCount > 0) {
76
+ console.log(chalk_1.default.yellow(` Warning: ${missedPrayersCount} prayer times missed.`));
77
+ console.log(chalk_1.default.cyan(` Suggestion: run 'aya wudu' to refresh session.`));
78
+ }
79
+ console.log('');
80
+ if (nextPrayer && nextPrayerTime) {
81
+ const diff = (0, date_fns_1.differenceInMinutes)(nextPrayerTime, now);
82
+ const hours = Math.floor(diff / 60);
83
+ const mins = diff % 60;
84
+ let timeString = '';
85
+ if (hours > 0)
86
+ timeString += `${hours}h `;
87
+ timeString += `${mins}m`;
88
+ console.log(chalk_1.default.bold.yellow('⏳ Next Obligatory Commit:'));
89
+ console.log(` ${chalk_1.default.cyan.bold(nextPrayer)} is due in ${chalk_1.default.yellow.bold(timeString)}`);
90
+ console.log(chalk_1.default.italic.gray(' "Indeed, prayer has been decreed upon the believers a decree of specified times." (4:103)'));
91
+ }
92
+ console.log('');
93
+ console.log(chalk_1.default.bold.white('📅 Today\'s Schedule (The Daily Sprint):'));
94
+ prayerNames.forEach(name => {
95
+ const isNext = name === nextPrayer;
96
+ const color = isNext ? chalk_1.default.green.bold : chalk_1.default.white;
97
+ const marker = isNext ? chalk_1.default.yellow(' ← UP NEXT') : '';
98
+ const time = timings[name];
99
+ // Simple formatting
100
+ console.log(` ${color(name.padEnd(10))} ${time} ${marker}`);
101
+ });
102
+ console.log('');
103
+ console.log(chalk_1.default.gray('(Run "aya init" to re-calibrate your location coordinates)'));
104
+ }
105
+ catch (error) {
106
+ spinner.fail('Connection lost.');
107
+ console.error(chalk_1.default.red('Could not fetch prayer times. Please check your network connection.'));
108
+ }
109
+ });
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.sunnahCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const nak_1 = require("../data/nak");
10
+ const printer_1 = require("../utils/printer");
11
+ exports.sunnahCommand = new commander_1.Command('sunnah')
12
+ .description('Daily Micro-Ibadaat Habits')
13
+ .action(async () => {
14
+ (0, printer_1.printCommandHeader)('sunnah');
15
+ console.clear();
16
+ console.log(chalk_1.default.green.bold('\n Daily Sunnah Habits (Micro-Ibadaat)\n'));
17
+ nak_1.sunnahData.forEach(s => {
18
+ console.log(chalk_1.default.yellow.bold(` ${s.action} `) + chalk_1.default.gray(`(${s.category})`));
19
+ console.log(chalk_1.default.cyan(` Impact: ${s.impact}`));
20
+ console.log(chalk_1.default.white.italic(` ${s.description}\n`));
21
+ });
22
+ console.log(chalk_1.default.gray(' "He who revives my Sunnah has loved me..."'));
23
+ console.log('\n');
24
+ });
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.tafsirCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const inquirer_1 = __importDefault(require("inquirer"));
10
+ const tafsir_1 = require("../data/tafsir");
11
+ const printer_1 = require("../utils/printer");
12
+ exports.tafsirCommand = new commander_1.Command('tafsir')
13
+ .description('Interactive linguistic deep dive (Tadabbur)')
14
+ .argument('[query]', 'The specific surah/ayah to study (e.g. 93:3, fatiha, ikhlas)')
15
+ .action(async (query) => {
16
+ (0, printer_1.printCommandHeader)('tafsir');
17
+ let selectedTafsir;
18
+ if (query) {
19
+ const q = query.toLowerCase();
20
+ selectedTafsir = tafsir_1.tafsirData.find(t => t.surah.toLowerCase().includes(q) ||
21
+ `${t.ayah}` === q ||
22
+ (query.includes(':') && `${t.surah}:${t.ayah}`.includes(q)) || // weak check, but okay
23
+ (query.includes(':') && t.ayah === parseInt(query.split(':')[1]) && t.surah.toLowerCase().includes(query.split(':')[0])) // better check? No, surah is a name in data
24
+ );
25
+ // Better matching logic
26
+ if (!selectedTafsir) {
27
+ // Try to match "93:3" style
28
+ if (query.includes(':')) {
29
+ const [s, a] = query.split(':');
30
+ // We don't have surah numbers in data, only names.
31
+ // But let's check if user typed "duha:3"
32
+ selectedTafsir = tafsir_1.tafsirData.find(t => t.surah.toLowerCase().includes(s) && t.ayah.toString() === a);
33
+ }
34
+ }
35
+ // Hardcoded fallback for specific numbers if they were in the original code
36
+ // 93:3 -> Ad-Duhaa
37
+ if (!selectedTafsir && query === '93:3')
38
+ selectedTafsir = tafsir_1.tafsirData.find(t => t.surah === 'Ad-Duhaa');
39
+ if (!selectedTafsir && query === '1:5')
40
+ selectedTafsir = tafsir_1.tafsirData.find(t => t.surah === 'Al-Fatiha');
41
+ if (!selectedTafsir && query === '103:1')
42
+ selectedTafsir = tafsir_1.tafsirData.find(t => t.surah === 'Al-Asr');
43
+ if (!selectedTafsir && query === '112:1')
44
+ selectedTafsir = tafsir_1.tafsirData.find(t => t.surah === 'Al-Ikhlas');
45
+ if (!selectedTafsir && query === '113:1')
46
+ selectedTafsir = tafsir_1.tafsirData.find(t => t.surah === 'Al-Falaq');
47
+ if (!selectedTafsir && query === '114:1')
48
+ selectedTafsir = tafsir_1.tafsirData.find(t => t.surah === 'An-Nas');
49
+ if (!selectedTafsir) {
50
+ console.log(chalk_1.default.red('Tafsir not found for that Ayah.'));
51
+ console.log(chalk_1.default.gray('Available: Ad-Duhaa (93:3), Al-Fatiha (1:5), Al-Asr (103:1), Al-Ikhlas (112:1), Al-Falaq (113:1), An-Nas (114:1)'));
52
+ return;
53
+ }
54
+ }
55
+ else {
56
+ // Interactive menu if no argument provided
57
+ const answers = await inquirer_1.default.prompt([
58
+ {
59
+ type: 'list',
60
+ name: 'selectedTafsirIndex',
61
+ message: 'Choose a Surah/Ayah to study:',
62
+ choices: tafsir_1.tafsirData.map((t, index) => ({
63
+ name: `${t.surah} (Ayah ${t.ayah})`,
64
+ value: index
65
+ }))
66
+ }
67
+ ]);
68
+ selectedTafsir = tafsir_1.tafsirData[answers.selectedTafsirIndex];
69
+ }
70
+ if (!selectedTafsir)
71
+ return;
72
+ console.clear();
73
+ console.log(chalk_1.default.green.bold(`\n Tafsir: Surah ${selectedTafsir.surah}, Ayah ${selectedTafsir.ayah}`));
74
+ console.log(chalk_1.default.gray('Take a deep breath. Let the words sink in.\n'));
75
+ for (const step of selectedTafsir.steps) {
76
+ await inquirer_1.default.prompt([{
77
+ type: 'input',
78
+ name: 'continue',
79
+ message: chalk_1.default.yellow.bold(step.word),
80
+ suffix: chalk_1.default.gray(' (Press Enter to reveal meaning)')
81
+ }]);
82
+ console.log(chalk_1.default.cyan(`Meaning: ${step.meaning}`));
83
+ console.log(chalk_1.default.white(step.explanation));
84
+ console.log(chalk_1.default.gray('----------------------------------------'));
85
+ }
86
+ console.log(chalk_1.default.green.bold('\n Final Reflection:'));
87
+ console.log(chalk_1.default.white.italic(selectedTafsir.finalThought));
88
+ console.log('');
89
+ });
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.tasbihCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const inquirer_1 = __importDefault(require("inquirer"));
10
+ const printer_1 = require("../utils/printer");
11
+ const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
12
+ exports.tasbihCommand = new commander_1.Command('tasbih')
13
+ .description('Digital Counter (Tasbih)')
14
+ .action(async () => {
15
+ (0, printer_1.printCommandHeader)('tasbih');
16
+ let count = 0;
17
+ console.clear();
18
+ console.log(chalk_1.default.cyan.bold('\n Digital Tasbih'));
19
+ console.log(chalk_1.default.gray('Press ENTER to count. Type "reset" to reset. Ctrl+C to exit.\n'));
20
+ // We need a loop to handle inputs
21
+ while (true) {
22
+ const { input } = await inquirer_1.default.prompt([{
23
+ type: 'input',
24
+ name: 'input',
25
+ message: `Count: ${chalk_1.default.green.bold(count)} Wait for prompt...`,
26
+ default: '',
27
+ prefix: '' // Remove prefix
28
+ }]);
29
+ if (input.toLowerCase() === 'reset') {
30
+ count = 0;
31
+ }
32
+ else if (input.toLowerCase() === 'exit' || input.toLowerCase() === 'q') {
33
+ break;
34
+ }
35
+ else {
36
+ count++;
37
+ }
38
+ console.clear();
39
+ console.log(chalk_1.default.cyan.bold('\n Digital Tasbih'));
40
+ console.log(chalk_1.default.gray('Press ENTER to count. Type "reset" to reset. Type "exit" to quit.\n'));
41
+ console.log(chalk_1.default.green.bold(`Current Count: ${count}`));
42
+ // Simple feedback
43
+ if (count % 33 === 0 && count > 0) {
44
+ console.log(chalk_1.default.yellow(' SubhanAllah / Alhamdulillah / Allahu Akbar (33 completed)'));
45
+ }
46
+ if (count % 100 === 0 && count > 0) {
47
+ console.log(chalk_1.default.magenta(' 100 Completed! May Allah accept it.'));
48
+ }
49
+ }
50
+ });
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.wuduCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const nak_1 = require("../data/nak");
10
+ const printer_1 = require("../utils/printer");
11
+ exports.wuduCommand = new commander_1.Command('wudu')
12
+ .description('The Spiritual Detox (Washing away sins)')
13
+ .action(() => {
14
+ (0, printer_1.printCommandHeader)('wudu');
15
+ console.log(chalk_1.default.cyan.bold('\n Wudu: The Spiritual Detox\n'));
16
+ nak_1.wuduData.forEach((step, index) => {
17
+ console.log(chalk_1.default.blue.bold(` ${index + 1}. ${step.step}`));
18
+ console.log(chalk_1.default.white(` Physical: ${step.physical}`));
19
+ console.log(chalk_1.default.green(` Spiritual: ${step.spiritual}\n`));
20
+ });
21
+ console.log(chalk_1.default.gray(' "Oh Allah, make me of those who repent and those who purify themselves."'));
22
+ });