@max-xoo/mawaqit 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.
package/README.MD ADDED
File without changes
package/dist/cache.js ADDED
@@ -0,0 +1,44 @@
1
+ const cache = new Map();
2
+
3
+ function getMsUntilMidnight() {
4
+ const midnight = new Date();
5
+ midnight.setHours(24, 0, 0, 0);
6
+ return midnight.getTime() - Date.now();
7
+ }
8
+
9
+ function getFromCache(key) {
10
+ const entry = cache.get(key);
11
+ if (!entry) return null;
12
+ if (Date.now() > entry.expiresAt) {
13
+ cache.delete(key);
14
+ return null;
15
+ }
16
+ return entry.data;
17
+ }
18
+
19
+ function setToCache(key, data) {
20
+ cache.set(key, {
21
+ data,
22
+ expiresAt: Date.now() + getMsUntilMidnight(),
23
+ });
24
+ }
25
+
26
+ function clearCache() {
27
+ cache.clear();
28
+ }
29
+
30
+ function deleteCacheEntry(key) {
31
+ cache.delete(key);
32
+ }
33
+
34
+ function getCacheSize() {
35
+ return cache.size;
36
+ }
37
+
38
+ module.exports = {
39
+ getFromCache,
40
+ setToCache,
41
+ clearCache,
42
+ deleteCacheEntry,
43
+ getCacheSize,
44
+ };
package/dist/errors.js ADDED
@@ -0,0 +1,43 @@
1
+ class MawaqitError extends Error {
2
+ constructor(message, statusCode) {
3
+ super(message);
4
+ this.name = "MawaqitError";
5
+ this.statusCode = statusCode;
6
+ }
7
+ }
8
+
9
+ class MawaqitNotFoundError extends MawaqitError {
10
+ constructor(masjidId) {
11
+ super(`Mosque "${masjidId}" not found`, 404);
12
+ this.name = "MawaqitNotFoundError";
13
+ }
14
+ }
15
+
16
+ class MawaqitParseError extends MawaqitError {
17
+ constructor(masjidId) {
18
+ super(`Failed to parse prayer data for "${masjidId}"`, 500);
19
+ this.name = "MawaqitParseError";
20
+ }
21
+ }
22
+
23
+ class MawaqitFetchError extends MawaqitError {
24
+ constructor(url) {
25
+ super(`Something went wrong fetching "${url}"`, 502);
26
+ this.name = "MawaqitFetchError";
27
+ }
28
+ }
29
+
30
+ class MawaqitValidationError extends MawaqitError {
31
+ constructor(message) {
32
+ super(message, 400);
33
+ this.name = "MawaqitValidationError";
34
+ }
35
+ }
36
+
37
+ module.exports = {
38
+ MawaqitError,
39
+ MawaqitNotFoundError,
40
+ MawaqitParseError,
41
+ MawaqitFetchError,
42
+ MawaqitValidationError,
43
+ };
package/dist/fetch.js ADDED
@@ -0,0 +1,64 @@
1
+ const axios = require("axios");
2
+
3
+ const {
4
+ load
5
+ } = require("cheerio");
6
+ const {
7
+ getFromCache,
8
+ setToCache
9
+ } = require("./cache");
10
+
11
+ const {
12
+ MawaqitNotFoundError,
13
+ MawaqitParseError,
14
+ MawaqitFetchError,
15
+ } = require("./errors");
16
+
17
+ const CONF_DATA_REGEX = /(?:var|let)\s+confData\s*=\s*(.*?);/s;
18
+
19
+ async function fetchMawaqit(masjidId) {
20
+ const cached = getFromCache(masjidId);
21
+ if (cached) {
22
+ return cached;
23
+ }
24
+
25
+ const url = `https://mawaqit.net/fr/${masjidId}`;
26
+ let response;
27
+
28
+ try {
29
+ response = await axios.get(url);
30
+ } catch (err) {
31
+ const status = err.response?.status;
32
+ if (status === 404) throw new MawaqitNotFoundError(masjidId);
33
+ throw new MawaqitFetchError(url);
34
+ }
35
+
36
+ const $ = load(response.data);
37
+ let confData = null;
38
+
39
+ $("script").each((_, el) => {
40
+ if (confData) return; // already found
41
+ const content = $(el).html();
42
+ if (content && CONF_DATA_REGEX.test(content)) {
43
+ const match = content.match(CONF_DATA_REGEX);
44
+ if (match) {
45
+ try {
46
+ confData = JSON.parse(match[1]);
47
+ } catch {
48
+ throw new MawaqitParseError(masjidId);
49
+ }
50
+ }
51
+ }
52
+ });
53
+
54
+ if (!confData) {
55
+ throw new MawaqitParseError(masjidId);
56
+ }
57
+
58
+ setToCache(masjidId, confData);
59
+ return confData;
60
+ }
61
+
62
+ module.exports = {
63
+ fetchMawaqit
64
+ };
package/dist/index.js ADDED
@@ -0,0 +1,48 @@
1
+ const {
2
+ fetchMawaqit
3
+ } = require("./fetch");
4
+
5
+ const {
6
+ getPrayerTimesOfTheDay,
7
+ getCalendar,
8
+ getMonth,
9
+ getMonthIqama,
10
+ getAnnouncements,
11
+ getServices,
12
+ } = require("./mawaqit");
13
+
14
+ const {
15
+ clearCache,
16
+ deleteCacheEntry,
17
+ getCacheSize,
18
+ } = require("./cache");
19
+
20
+ const {
21
+ MawaqitError,
22
+ MawaqitNotFoundError,
23
+ MawaqitParseError,
24
+ MawaqitFetchError,
25
+ MawaqitValidationError,
26
+ } = require("./errors");
27
+
28
+ module.exports = {
29
+ fetchMawaqit,
30
+
31
+ getPrayerTimesOfTheDay,
32
+ getCalendar,
33
+ getMonth,
34
+ getMonthIqama,
35
+
36
+ getAnnouncements,
37
+ getServices,
38
+
39
+ clearCache,
40
+ deleteCacheEntry,
41
+ getCacheSize,
42
+
43
+ MawaqitError,
44
+ MawaqitNotFoundError,
45
+ MawaqitParseError,
46
+ MawaqitFetchError,
47
+ MawaqitValidationError,
48
+ };
@@ -0,0 +1,93 @@
1
+ const {
2
+ fetchMawaqit
3
+ } = require("./fetch");
4
+ const {
5
+ MawaqitValidationError
6
+ } = require("./errors");
7
+
8
+ async function getPrayerTimesOfTheDay(masjidId) {
9
+ const {
10
+ times,
11
+ shuruq
12
+ } = await fetchMawaqit(masjidId);
13
+ return {
14
+ fajr: times[0],
15
+ sunrise: shuruq,
16
+ dohr: times[1],
17
+ asr: times[2],
18
+ maghreb: times[3],
19
+ icha: times[4],
20
+ };
21
+ }
22
+
23
+ async function getCalendar(masjidId) {
24
+ const {
25
+ calendar
26
+ } = await fetchMawaqit(masjidId);
27
+ return calendar;
28
+ }
29
+
30
+ async function getMonth(masjidId, monthNumber) {
31
+ if (monthNumber < 1 || monthNumber > 12) {
32
+ throw new MawaqitValidationError("Month number should be between 1 and 12");
33
+ }
34
+ const {
35
+ calendar
36
+ } = await fetchMawaqit(masjidId);
37
+ const month = calendar[monthNumber - 1];
38
+ return Object.values(month).map((prayer) => ({
39
+ fajr: prayer[0],
40
+ sunrise: prayer[1],
41
+ dohr: prayer[2],
42
+ asr: prayer[3],
43
+ maghreb: prayer[4],
44
+ icha: prayer[5],
45
+ }));
46
+ }
47
+
48
+ async function getMonthIqama(masjidId, monthNumber) {
49
+ if (monthNumber < 1 || monthNumber > 12) {
50
+ throw new MawaqitValidationError("Month number should be between 1 and 12");
51
+ }
52
+ const {
53
+ iqamaCalendar
54
+ } = await fetchMawaqit(masjidId);
55
+ const month = iqamaCalendar[monthNumber - 1];
56
+ return Object.values(month).map((iqama) => ({
57
+ fajr: iqama[0],
58
+ dohr: iqama[1],
59
+ asr: iqama[2],
60
+ maghreb: iqama[3],
61
+ icha: iqama[4],
62
+ }));
63
+ }
64
+
65
+ async function getAnnouncements(masjidId) {
66
+ const {
67
+ announcements
68
+ } = await fetchMawaqit(masjidId);
69
+ return announcements ?? [];
70
+ }
71
+
72
+ async function getServices(masjidId) {
73
+ const confData = await fetchMawaqit(masjidId);
74
+ return {
75
+ name: confData.name,
76
+ label: confData.label,
77
+ localisation: confData.localisation,
78
+ phone: confData.phone,
79
+ email: confData.email,
80
+ site: confData.site,
81
+ mosqueeType: confData.mosqueeType,
82
+ association: confData.association,
83
+ };
84
+ }
85
+
86
+ module.exports = {
87
+ getPrayerTimesOfTheDay,
88
+ getCalendar,
89
+ getMonth,
90
+ getMonthIqama,
91
+ getAnnouncements,
92
+ getServices,
93
+ };
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@max-xoo/mawaqit",
3
+ "version": "1.0.0",
4
+ "description": "A JavaScript wrapper around the unofficial Mawaqit API",
5
+ "keywords": [
6
+ "mawaqit",
7
+ "prayer",
8
+ "islam",
9
+ "mosque",
10
+ "salat",
11
+ "quran"
12
+ ],
13
+ "homepage": "https://github.com/roimee6/mawaqit#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/roimee6/mawaqit/issues"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/roimee6/mawaqit.git"
20
+ },
21
+ "license": "MIT",
22
+ "author": "Maxence",
23
+ "main": "dist/index.js",
24
+ "files": [
25
+ "dist/**/*"
26
+ ],
27
+ "scripts": {
28
+ "test": "node test.cjs"
29
+ },
30
+ "dependencies": {
31
+ "axios": "^1.13.5",
32
+ "cheerio": "^1.2.0"
33
+ },
34
+ "devDependencies": {}
35
+ }