@quranjs/api 1.6.0 → 1.7.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 (63) hide show
  1. package/dist/index.d.ts +553 -2
  2. package/dist/index.js +11 -6
  3. package/dist/index.js.map +1 -0
  4. package/dist/index.mjs +6 -0
  5. package/dist/index.mjs.map +1 -0
  6. package/package.json +24 -21
  7. package/src/sdk/utils.ts +18 -9
  8. package/src/sdk/v4/_fetcher.ts +58 -7
  9. package/src/sdk/v4/audio.ts +30 -50
  10. package/src/sdk/v4/chapters.ts +12 -15
  11. package/src/sdk/v4/juzs.ts +7 -2
  12. package/src/sdk/v4/resources.ts +27 -31
  13. package/src/sdk/v4/search.ts +14 -13
  14. package/src/sdk/v4/verses.ts +72 -50
  15. package/src/types/BaseApiOptions.ts +6 -0
  16. package/src/types/FetchFn.ts +1 -0
  17. package/src/types/index.ts +2 -0
  18. package/dist/api.cjs.development.js +0 -2754
  19. package/dist/api.cjs.development.js.map +0 -1
  20. package/dist/api.cjs.production.min.js +0 -2
  21. package/dist/api.cjs.production.min.js.map +0 -1
  22. package/dist/api.esm.js +0 -2746
  23. package/dist/api.esm.js.map +0 -1
  24. package/dist/sdk/index.d.ts +0 -195
  25. package/dist/sdk/utils.d.ts +0 -125
  26. package/dist/sdk/v4/_fetcher.d.ts +0 -3
  27. package/dist/sdk/v4/audio.d.ts +0 -52
  28. package/dist/sdk/v4/chapters.d.ts +0 -13
  29. package/dist/sdk/v4/index.d.ts +0 -185
  30. package/dist/sdk/v4/juzs.d.ts +0 -5
  31. package/dist/sdk/v4/resources.d.ts +0 -26
  32. package/dist/sdk/v4/search.d.ts +0 -22
  33. package/dist/sdk/v4/verses.d.ts +0 -76
  34. package/dist/types/ChapterId.d.ts +0 -4
  35. package/dist/types/HizbNumber.d.ts +0 -4
  36. package/dist/types/JuzNumber.d.ts +0 -4
  37. package/dist/types/PageNumber.d.ts +0 -4
  38. package/dist/types/RubNumber.d.ts +0 -4
  39. package/dist/types/VerseKey.d.ts +0 -2
  40. package/dist/types/api/ApiResponses.d.ts +0 -18
  41. package/dist/types/api/AudioData.d.ts +0 -17
  42. package/dist/types/api/AudioResponse.d.ts +0 -8
  43. package/dist/types/api/Chapter.d.ts +0 -14
  44. package/dist/types/api/ChapterInfo.d.ts +0 -8
  45. package/dist/types/api/Footnote.d.ts +0 -6
  46. package/dist/types/api/Juz.d.ts +0 -8
  47. package/dist/types/api/Pagination.d.ts +0 -7
  48. package/dist/types/api/Reciter.d.ts +0 -21
  49. package/dist/types/api/Resources.d.ts +0 -70
  50. package/dist/types/api/Segment.d.ts +0 -4
  51. package/dist/types/api/Tafsir.d.ts +0 -7
  52. package/dist/types/api/TafsirInfo.d.ts +0 -9
  53. package/dist/types/api/TranslatedName.d.ts +0 -4
  54. package/dist/types/api/Translation.d.ts +0 -17
  55. package/dist/types/api/Transliteration.d.ts +0 -4
  56. package/dist/types/api/Verse.d.ts +0 -32
  57. package/dist/types/api/Word.d.ts +0 -28
  58. package/dist/types/api/index.d.ts +0 -18
  59. package/dist/types/index.d.ts +0 -88
  60. package/dist/types/utils.d.ts +0 -5
  61. package/dist/utils/misc.d.ts +0 -1
  62. package/dist/utils/qs-stringify.d.ts +0 -21
  63. package/src/utils/qs-stringify.ts +0 -81
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types/api/Word.ts","../src/types/index.ts","../src/sdk/v4/_fetcher.ts","../src/utils/misc.ts","../src/sdk/utils.ts","../src/sdk/v4/chapters.ts","../src/sdk/v4/verses.ts","../src/sdk/v4/juzs.ts","../src/sdk/v4/audio.ts","../src/sdk/v4/resources.ts","../src/sdk/v4/search.ts","../src/sdk/v4/index.ts","../src/sdk/index.ts"],"names":["CharType","Language","QuranFont","camelizeKeys","decamelize","decamelizeKeys","removeBeginningSlash","url","API_BASE_URL","makeUrl","params","baseUrl","paramsWithDecamelizedKeys","paramsString","value","fetcher","fetchFn","json","res","mergeApiOptions","options","defaultOptions","final","fields","key","versesMapping","isValidChapterId","id","parsedId","isValidJuz","juz","parsedJuz","isValidRub","rub","parsedRub","isValidHizb","hizb","parsedHizb","isValidQuranPage","page","parsedPage","isValidVerseKey","chapterId","verseId","parsedVerse","verseCount","utils","utils_default","findAll","chapters","findById","chapter","findInfoById","chapterInfo","chapters_default","mergeVerseOptions","result","wordFields","translationFields","findByKey","verse","findByChapter","verses","findByPage","findByJuz","findByHizb","findRandom","verses_default","juzs","juzs_default","defaultChapterRecitationsOptions","defaultVerseRecitationsOptions","findAllChapterRecitations","reciterId","audioFiles","findChapterRecitationById","audioFile","findVerseRecitationsByChapter","recitationId","findVerseRecitationsByJuz","findVerseRecitationsByPage","findVerseRecitationsByRub","findVerseRecitationsByHizb","findVerseRecitationsByKey","audio","audio_default","findAllRecitations","recitations","findAllTranslations","translations","findAllTafsirs","tafsirs","findAllRecitationStyles","recitationStyles","findAllLanguages","languages","findAllChapterInfos","chapterInfos","findVerseMedia","verseMedia","findAllChapterReciters","reciters","resources","resources_default","defaultSearchOptions","search","q","searchApi","search_default","v4","v4_default","quran","sdk_default"],"mappings":"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DF,EAAM,OAASC,EAAO,KAAK,GAAG,CAChC,CAEA,OAAOD,CACT,EEpEO,IAAMG,EAAgB,CAC3B,EAAK,EACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,GACL,EAAK,IACL,GAAM,IACN,GAAM,IACN,GAAM,IACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,IACN,GAAM,IACN,GAAM,IACN,GAAM,GACN,GAAM,IACN,GAAM,IACN,GAAM,GACN,GAAM,IACN,GAAM,GACN,GAAM,GACN,GAAM,IACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,IACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,EACN,GAAM,EACN,GAAM,GACN,GAAM,EACN,GAAM,EACN,GAAM,EACN,IAAO,GACP,IAAO,GACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,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","sourcesContent":["import { VerseKey } from '../VerseKey';\nimport { Translation } from './Translation';\nimport { Transliteration } from './Transliteration';\n\nexport enum CharType {\n Word = 'word',\n End = 'end',\n Pause = 'pause',\n Sajdah = 'sajdah',\n RubElHizb = 'rub-el-hizb',\n}\n\nexport interface Word {\n id?: number;\n position: number;\n audioUrl: string;\n charTypeName: CharType;\n codeV1?: string;\n codeV2?: string;\n pageNumber?: number;\n lineNumber?: number;\n text?: string;\n textUthmani?: string;\n textIndopak?: string;\n textImlaei?: string;\n translation: Translation;\n transliteration: Transliteration;\n location?: string; // chapter:verse:word\n verseKey?: VerseKey;\n}\n","export enum Language {\n ARABIC = 'ar',\n ENGLISH = 'en',\n URDU = 'ur',\n BENGALI = 'bn',\n TURKISH = 'tr',\n SPANISH = 'es',\n GERMAN = 'de',\n BOSNIAN = 'bs',\n RUSSIAN = 'ru',\n ALBANIAN_AL = 'al',\n FRENCH = 'fr',\n DUTCH = 'nl',\n TAMIL = 'ta',\n TAJIK = 'tg',\n INDONESIAN = 'id',\n UZBEK = 'uz',\n VIETNAMESE = 'vi',\n CHINESE = 'zh',\n ITALIAN = 'it',\n JAPANESE = 'ja',\n MALAYALAM = 'ml',\n AMHARIC = 'am',\n KAZAKH = 'kk',\n PORTUGUESE = 'pt',\n TAGALOG = 'tl',\n THAI = 'th',\n KOREAN = 'ko',\n HINDI = 'hi',\n KURDISH = 'ku',\n HAUSA = 'ha',\n AZERI = 'az',\n SWAHILI = 'sw',\n PERSIAN = 'fa',\n SERBIAN = 'sr',\n MARANAO = 'mrn',\n AMAZIGH = 'zgh',\n ASSAMESE = 'as',\n BULGARIAN = 'bg',\n CHECHEN = 'ce',\n CZECH = 'cs',\n\n DIVEHI = 'dv',\n DHIVEHI = 'dv',\n MALDIVIAN = 'dv',\n\n FINNISH = 'fi',\n GUJAARATI = 'gu',\n HEBREW = 'he',\n GEORGIAN = 'ka',\n CENTRAL_KHMER = 'km',\n GANDA = 'lg',\n MARATHI = 'mr',\n YORUBA = 'yo',\n MALAY = 'ms',\n NEPALI = 'ne',\n SWEDISH = 'sv',\n TELUGU = 'te',\n TATAR = 'tt',\n\n UIGHUR = 'ug',\n UYGHUR = 'ug',\n\n UKRAINIAN = 'uk',\n NORWEGIAN = 'no',\n OROMO = 'om',\n POLISH = 'pl',\n PASHTO = 'ps',\n ROMANIAN = 'ro',\n SINDHI = 'sd',\n NORTHERN_SAMI = 'se',\n\n SINHALA = 'si',\n SINHALESE = 'si',\n\n SOMALI = 'so',\n ALBANIAN_SQ = 'sq',\n}\n\nexport enum QuranFont {\n MadaniV1 = 'code_v1',\n MadaniV2 = 'code_v2',\n Uthmani = 'text_uthmani',\n}\n\nexport type VerseField =\n | 'chapterId'\n | 'textUthmani'\n | 'textUthmaniSimple'\n | 'textImlaei'\n | 'textImlaeiSimple'\n | 'textIndopak'\n | 'textUthmaniTajweed'\n | 'imageUrl'\n | 'imageWidth'\n | 'codeV1'\n | 'codeV2'\n | 'v1Page'\n | 'v2Page';\n\nexport type WordField =\n | 'v1Page'\n | 'v2Page'\n | 'textUthmani'\n | 'textImlaei'\n | 'textIndopak'\n | 'verseKey'\n | 'location'\n | 'codeV1'\n | 'codeV2';\n\nexport type TranslationField =\n | 'resourceName'\n | 'verseId'\n | 'languageId'\n | 'languageName'\n | 'verseKey'\n | 'chapterId'\n | 'verseNumber'\n | 'juzNumber'\n | 'hizbNumber'\n | 'rubNumber'\n | 'pageNumber';\n\nexport type VerseRecitationField = 'id' | 'chapterId' | 'segments' | 'format';\n\nexport * from './VerseKey';\nexport * from './ChapterId';\nexport * from './HizbNumber';\nexport * from './JuzNumber';\nexport * from './PageNumber';\nexport * from './RubNumber';\n\nexport * from './api';\n\nexport * from './FetchFn';\n","import { camelizeKeys, decamelize, decamelizeKeys } from 'humps';\nimport { FetchFn } from '../../types';\nimport { BaseApiOptions } from '../../types/BaseApiOptions';\nimport { removeBeginningSlash } from '../../utils/misc';\n\nexport const API_BASE_URL = 'https://api.quran.com/api/v4/';\n\nexport const makeUrl = (url: string, params?: Record<string, unknown>) => {\n const baseUrl = `${API_BASE_URL}${removeBeginningSlash(url)}`;\n if (!params) return baseUrl;\n\n const paramsWithDecamelizedKeys = decamelizeKeys(params) as Record<\n string,\n string\n >;\n const paramsString = new URLSearchParams(\n Object.entries(paramsWithDecamelizedKeys).filter(\n ([, value]) => value !== undefined\n )\n ).toString();\n if (!paramsString) return baseUrl;\n\n return `${baseUrl}?${paramsString}`;\n};\n\nexport const fetcher = async <T extends object>(\n url: string,\n params: Record<string, unknown> = {},\n fetchFn?: FetchFn\n) => {\n if (fetchFn) {\n const json = await fetchFn(makeUrl(url, params));\n return camelizeKeys(json) as T;\n }\n\n if (typeof fetch === 'undefined') {\n throw new Error('fetch is not defined');\n }\n\n // if there is no fetchFn, we use the global fetch\n const res = await fetch(makeUrl(url, params));\n\n if (!res.ok || res.status >= 400) {\n throw new Error(`${res.status} ${res.statusText}`);\n }\n\n const json = await res.json();\n\n return camelizeKeys(json) as T;\n};\n\ntype MergeApiOptionsObject = Pick<BaseApiOptions, 'fetchFn'> & {\n fields?: Record<string, boolean>;\n} & Record<string, unknown>;\n\nexport const mergeApiOptions = (\n options: MergeApiOptionsObject = {},\n defaultOptions: Record<string, unknown> = {}\n) => {\n // we can set it to undefined because `makeUrl` will filter it out\n if (options.fetchFn) options.fetchFn = undefined;\n\n const final: Record<string, unknown> = {\n ...defaultOptions,\n ...options,\n };\n\n if (final.fields) {\n const fields: string[] = [];\n Object.entries(final.fields).forEach(([key, value]) => {\n if (value) fields.push(decamelize(key));\n });\n\n // convert `fields` to a string sperated by commas\n final.fields = fields.join(',');\n }\n\n return final;\n};\n","export const removeBeginningSlash = (url: string) => {\n return url.startsWith('/') ? url.slice(1) : url;\n};\n","import {\n ChapterId,\n HizbNumber,\n JuzNumber,\n PageNumber,\n RubNumber,\n VerseKey,\n} from '../types';\n\n// this maps chapterNumber to verseCount\nexport const versesMapping = {\n '1': 7,\n '2': 286,\n '3': 200,\n '4': 176,\n '5': 120,\n '6': 165,\n '7': 206,\n '8': 75,\n '9': 129,\n '10': 109,\n '11': 123,\n '12': 111,\n '13': 43,\n '14': 52,\n '15': 99,\n '16': 128,\n '17': 111,\n '18': 110,\n '19': 98,\n '20': 135,\n '21': 112,\n '22': 78,\n '23': 118,\n '24': 64,\n '25': 77,\n '26': 227,\n '27': 93,\n '28': 88,\n '29': 69,\n '30': 60,\n '31': 34,\n '32': 30,\n '33': 73,\n '34': 54,\n '35': 45,\n '36': 83,\n '37': 182,\n '38': 88,\n '39': 75,\n '40': 85,\n '41': 54,\n '42': 53,\n '43': 89,\n '44': 59,\n '45': 37,\n '46': 35,\n '47': 38,\n '48': 29,\n '49': 18,\n '50': 45,\n '51': 60,\n '52': 49,\n '53': 62,\n '54': 55,\n '55': 78,\n '56': 96,\n '57': 29,\n '58': 22,\n '59': 24,\n '60': 13,\n '61': 14,\n '62': 11,\n '63': 11,\n '64': 18,\n '65': 12,\n '66': 12,\n '67': 30,\n '68': 52,\n '69': 52,\n '70': 44,\n '71': 28,\n '72': 28,\n '73': 20,\n '74': 56,\n '75': 40,\n '76': 31,\n '77': 50,\n '78': 40,\n '79': 46,\n '80': 42,\n '81': 29,\n '82': 19,\n '83': 36,\n '84': 25,\n '85': 22,\n '86': 17,\n '87': 19,\n '88': 26,\n '89': 30,\n '90': 20,\n '91': 15,\n '92': 21,\n '93': 11,\n '94': 8,\n '95': 8,\n '96': 19,\n '97': 5,\n '98': 8,\n '99': 8,\n '100': 11,\n '101': 11,\n '102': 8,\n '103': 3,\n '104': 9,\n '105': 5,\n '106': 4,\n '107': 7,\n '108': 3,\n '109': 6,\n '110': 3,\n '111': 5,\n '112': 4,\n '113': 5,\n '114': 6,\n};\n\n/**\n * Validates chapter id\n * @param id chapter id\n * @example \n isValidChapterId('1') // true\n isValidChapterId('114') // true\n isValidChapterId('0') // false\n isValidChapterId('-1') // false\n isValidChapterId('200') // false\n */\nconst isValidChapterId = (id: string | number): id is ChapterId => {\n const parsedId = typeof id === 'number' ? id : Number(id);\n if (!parsedId || parsedId <= 0 || parsedId > 114) return false;\n return true;\n};\n\n/**\n * Validates juz number\n * @param juz juz number\n * @example \n isValidJuz('1') // true\n isValidJuz('30') // true\n isValidJuz('0') // false\n isValidJuz('-1') // false\n isValidJuz('200') // false\n */\nconst isValidJuz = (juz: string | number): juz is JuzNumber => {\n const parsedJuz = typeof juz === 'number' ? juz : Number(juz);\n if (!parsedJuz || parsedJuz <= 0 || parsedJuz > 30) return false;\n return true;\n};\n\n/**\n * Validates rub number\n * @param rub rub number\n * @example \n isValidRub('1') // true\n isValidRub('240') // true\n isValidRub('0') // false\n isValidRub('-1') // false\n isValidRub('300') // false\n */\nconst isValidRub = (rub: string | number): rub is RubNumber => {\n const parsedRub = typeof rub === 'number' ? rub : Number(rub);\n if (!parsedRub || parsedRub <= 0 || parsedRub > 240) return false;\n return true;\n};\n\n/**\n * Validates hizb number\n * @param hizb hizb number\n * @example \n isValidHizb('1') // true\n isValidHizb('60') // true\n isValidHizb('0') // false\n isValidHizb('-1') // false\n isValidHizb('200') // false\n */\nconst isValidHizb = (hizb: string | number): hizb is HizbNumber => {\n const parsedHizb = typeof hizb === 'number' ? hizb : Number(hizb);\n if (!parsedHizb || parsedHizb <= 0 || parsedHizb > 60) return false;\n return true;\n};\n\n/**\n * Validates mushaf page number\n * @param page mushaf page number\n * @example \n isValidQuranPage('1') // true\n isValidQuranPage('604') // true\n isValidQuranPage('0') // false\n isValidQuranPage('-1') // false\n isValidQuranPage('1000') // false\n */\nconst isValidQuranPage = (page: string | number): page is PageNumber => {\n const parsedPage = typeof page === 'number' ? page : Number(page);\n if (!parsedPage || parsedPage <= 0 || parsedPage > 604) return false;\n return true;\n};\n\n/**\n * Validates verse key\n * @param key colon separated verse key (chapter:verse)\n * @example \n isValidVerseKey('1:1') // true\n isValidVerseKey('30:1') // true\n isValidVerseKey('0') // false\n isValidVerseKey('1:-') // false\n isValidVerseKey('1_1') // false\n */\nconst isValidVerseKey = (key: string): key is VerseKey => {\n const [chapterId, verseId] = key.trim().split(':');\n if (!chapterId || !verseId || !isValidChapterId(chapterId)) return false;\n\n const parsedVerse = Number(verseId);\n const verseCount = (versesMapping as Record<string, number>)[chapterId];\n if (!parsedVerse || parsedVerse <= 0 || parsedVerse > verseCount)\n return false;\n\n return true;\n};\n\nconst utils = {\n isValidChapterId,\n isValidJuz,\n isValidRub,\n isValidHizb,\n isValidQuranPage,\n isValidVerseKey,\n};\n\nexport default utils;\n","import { Chapter, ChapterId, ChapterInfo, Language } from '../../types';\nimport { fetcher, mergeApiOptions } from './_fetcher';\nimport Utils from '../utils';\nimport { BaseApiOptions } from '../../types/BaseApiOptions';\n\ntype GetChapterOptions = Partial<BaseApiOptions>;\n\nconst defaultOptions: GetChapterOptions = {\n language: Language.ARABIC,\n};\n\n/**\n * Get all chapters.\n * @description https://quran.api-docs.io/v4/chapters/list-chapters\n * @param {GetChapterOptions} options\n * @example\n * quran.v4.chapters.findAll()\n */\nconst findAll = async (options?: GetChapterOptions) => {\n const params = mergeApiOptions(options, defaultOptions);\n const { chapters } = await fetcher<{ chapters: Chapter[] }>(\n '/chapters',\n params,\n options?.fetchFn\n );\n\n return chapters;\n};\n\n/**\n * Get chapter by id.\n * @description https://quran.api-docs.io/v4/chapters/get-chapter\n * @param {ChapterId} id chapter id, minimum 1, maximum 114\n * @param {GetChapterOptions} options\n * @example\n * quran.v4.chapters.findById('1')\n * quran.v4.chapters.findById('114')\n */\nconst findById = async (id: ChapterId, options?: GetChapterOptions) => {\n if (!Utils.isValidChapterId(id)) throw new Error('Invalid chapter id');\n\n const params = mergeApiOptions(options, defaultOptions);\n const { chapter } = await fetcher<{ chapter: Chapter }>(\n `/chapters/${id}`,\n params,\n options?.fetchFn\n );\n\n return chapter;\n};\n\n/**\n * Get chapter info by id.\n * @description https://quran.api-docs.io/v4/chapters/chapter_info\n * @param {ChapterId} id chapter id, minimum 1, maximum 114\n * @param {GetChapterOptions} options\n * @example\n * quran.v4.chapters.findInfoById('1')\n * quran.v4.chapters.findInfoById('114')\n */\nconst findInfoById = async (id: ChapterId, options?: GetChapterOptions) => {\n if (!Utils.isValidChapterId(id)) throw new Error('Invalid chapter id');\n\n const params = mergeApiOptions(options, defaultOptions);\n const { chapterInfo } = await fetcher<{ chapterInfo: ChapterInfo }>(\n `/chapters/${id}/info`,\n params,\n options?.fetchFn\n );\n\n return chapterInfo;\n};\n\nconst chapters = {\n findAll,\n findById,\n findInfoById,\n};\n\nexport default chapters;\n","import {\n ChapterId,\n HizbNumber,\n JuzNumber,\n Language,\n PageNumber,\n TranslationField,\n // RubNumber,\n Verse,\n VerseField,\n VerseKey,\n WordField,\n} from '../../types';\nimport { decamelize } from 'humps';\nimport Utils from '../utils';\nimport { fetcher, mergeApiOptions } from './_fetcher';\nimport { BaseApiOptions } from '../../types/BaseApiOptions';\n\ntype GetVerseOptions = Partial<\n BaseApiOptions & {\n reciter: string | number;\n words: boolean;\n translations: string[] | number[];\n tafsirs: string[] | number[];\n wordFields: Partial<Record<WordField, boolean>>;\n translationFields: Partial<Record<TranslationField, boolean>>;\n fields: Partial<Record<VerseField, boolean>>;\n page: number;\n perPage: number;\n }\n>;\n\nconst defaultOptions: GetVerseOptions = {\n language: Language.ARABIC,\n perPage: 50,\n words: false,\n};\n\nconst mergeVerseOptions = (options: GetVerseOptions = {}) => {\n const result = mergeApiOptions(options, defaultOptions);\n\n // @ts-expect-error - we accept an array of strings, however, the API expects a comma separated string\n if (result.translations) result.translations = result.translations.join(',');\n\n // @ts-expect-error - we accept an array of strings, however, the API expects a comma separated string\n if (result.tafsirs) result.tafsirs = result.tafsirs.join(',');\n\n if (result.wordFields) {\n const wordFields: string[] = [];\n Object.entries(result.wordFields).forEach(([key, value]) => {\n if (value) wordFields.push(decamelize(key));\n });\n result.wordFields = wordFields.join(',');\n }\n\n if (result.translationFields) {\n const translationFields: string[] = [];\n Object.entries(result.translationFields).forEach(([key, value]) => {\n if (value) translationFields.push(decamelize(key));\n });\n result.translationFields = translationFields.join(',');\n }\n\n // rename `reciter` to `audio` because the API expects `audio`\n if (result.reciter) {\n result.audio = result.reciter;\n result.reciter = undefined;\n }\n\n return result;\n};\n\n/**\n * Get a specific ayah with key. Key is combination of surah number and ayah number.\n * @description https://quran.api-docs.io/v4/verses/by-specific-verse-by-key\n * @param {VerseKey} key - surah number and ayah number separated by a colon.\n * @param {GetVerseOptions} options\n * @example\n * quran.v4.verses.findByKey('1:1')\n * quran.v4.verses.findByKey('101:5')\n */\nconst findByKey = async (key: VerseKey, options?: GetVerseOptions) => {\n if (!Utils.isValidVerseKey(key)) throw new Error('Invalid verse key');\n const params = mergeVerseOptions(options);\n const url = `/verses/by_key/${key}`;\n const { verse } = await fetcher<{ verse: Verse }>(\n url,\n params,\n options?.fetchFn\n );\n\n return verse;\n};\n\n/**\n * Get all ayahs for a specific chapter (surah).\n * @description https://quran.api-docs.io/v4/verses/by_chapter\n * @param {ChapterId} id - chapter id (surah number)\n * @param {GetVerseOptions} options\n * @example\n * quran.v4.verses.findByChapter('1')\n * quran.v4.verses.findByChapter('101')\n */\nconst findByChapter = async (id: ChapterId, options?: GetVerseOptions) => {\n if (!Utils.isValidChapterId(id)) throw new Error('Invalid chapter id');\n const params = mergeVerseOptions(options);\n const url = `/verses/by_chapter/${id}`;\n const { verses } = await fetcher<{ verses: Verse[] }>(\n url,\n params,\n options?.fetchFn\n );\n\n return verses;\n};\n\n/**\n * Get all ayahs for a specific page in the Quran.\n * @description https://quran.api-docs.io/v4/verses/by-page\n * @param {PageNumber} page - Quran page number\n * @param {GetVerseOptions} options\n * @example\n * quran.v4.verses.findByPage('1')\n * quran.v4.verses.findByPage('101')\n */\nconst findByPage = async (page: PageNumber, options?: GetVerseOptions) => {\n if (!Utils.isValidQuranPage(page)) throw new Error('Invalid page');\n\n const params = mergeVerseOptions(options);\n const url = `/verses/by_page/${page}`;\n const { verses } = await fetcher<{ verses: Verse[] }>(\n url,\n params,\n options?.fetchFn\n );\n\n return verses;\n};\n\n/**\n * Get all ayahs for a Juz.\n * @description https://quran.api-docs.io/v4/verses/by-juz\n * @param {JuzNumber} id - juz number\n * @param {GetVerseOptions} options\n * @example\n * quran.v4.verses.findByJuz('1')\n * quran.v4.verses.findByJuz('29')\n */\nconst findByJuz = async (juz: JuzNumber, options?: GetVerseOptions) => {\n if (!Utils.isValidJuz(juz)) throw new Error('Invalid juz');\n\n const params = mergeVerseOptions(options);\n const url = `/verses/by_juz/${juz}`;\n const { verses } = await fetcher<{ verses: Verse[] }>(\n url,\n params,\n options?.fetchFn\n );\n\n return verses;\n};\n\n/**\n * Get all ayahs for a Hizb.\n * @description https://quran.api-docs.io/v4/verses/by-hizb-number\n * @param {HizbNumber} hizb - hizb number\n * @param {GetVerseOptions} options\n * @example\n * quran.v4.verses.findByHizb('1')\n * quran.v4.verses.findByHizb('29')\n */\nconst findByHizb = async (hizb: HizbNumber, options?: GetVerseOptions) => {\n if (!Utils.isValidHizb(hizb)) throw new Error('Invalid hizb');\n\n const params = mergeVerseOptions(options);\n const url = `/verses/by_hizb/${hizb}`;\n const { verses } = await fetcher<{ verses: Verse[] }>(\n url,\n params,\n options?.fetchFn\n );\n\n return verses;\n};\n\n// TODO: uncomment when API is fixed\n/**\n * Get all ayahs for a Rub.\n * @description https://quran.api-docs.io/v4/verses/by-rub-number\n * @param {RubNumber} rub - rub number\n * @param {GetVerseOptions} options\n * @example\n * quran.v4.verses.findByRub('1')\n * quran.v4.verses.findByRub('29')\n */\n// const findByRub = async (rub: RubNumber, options?: GetVerseOptions) => {\n// if (!Utils.isValidRub(rub)) throw new Error('Invalid rub');\n\n// const params = getVerseOptions(options);\n// const url = `/verses/by_rub/${rub}`;\n// const { verses } = await fetcher<{ verses: Verse[] }>(url, params);\n\n// return verses;\n// };\n\n/**\n * Get a random ayah.\n * @description https://quran.api-docs.io/v4/verses/random\n * @param {GetVerseOptions} options\n * @example\n * quran.v4.verses.findRandom()\n */\nconst findRandom = async (options?: GetVerseOptions) => {\n const params = mergeVerseOptions(options);\n const { verse } = await fetcher<{ verse: Verse }>(\n '/verses/random',\n params,\n options?.fetchFn\n );\n\n return verse;\n};\n\nconst verses = {\n findByKey,\n findByChapter,\n findByPage,\n findByJuz,\n findByHizb,\n // findByRub,\n findRandom,\n};\n\nexport default verses;\n","import { Juz } from '../../types';\nimport { BaseApiOptions } from '../../types/BaseApiOptions';\nimport { fetcher } from './_fetcher';\n\n/**\n * Get All Juzs\n * @description https://quran.api-docs.io/v4/juz/get-all-juzs\n * @example\n * quran.v4.juzs.findAll()\n */\nconst findAll = async (options?: Omit<BaseApiOptions, 'language'>) => {\n const { juzs } = await fetcher<{ juzs: Juz[] }>(\n '/juzs',\n undefined,\n options?.fetchFn\n );\n return juzs;\n};\n\nconst juzs = { findAll };\n\nexport default juzs;\n","import {\n ChapterRecitation,\n VerseRecitation,\n ChapterId,\n HizbNumber,\n JuzNumber,\n Language,\n PageNumber,\n Pagination,\n RubNumber,\n VerseKey,\n VerseRecitationField,\n} from '../../types';\nimport Utils from '../utils';\nimport { fetcher, mergeApiOptions } from './_fetcher';\nimport { BaseApiOptions } from '../../types/BaseApiOptions';\n\ntype GetChapterRecitationOptions = Partial<BaseApiOptions>;\n\nconst defaultChapterRecitationsOptions: GetChapterRecitationOptions = {\n language: Language.ARABIC,\n};\n\ntype GetVerseRecitationOptions = Partial<\n BaseApiOptions & {\n fields: Partial<Record<VerseRecitationField, boolean>>;\n }\n>;\n\nconst defaultVerseRecitationsOptions: GetVerseRecitationOptions = {\n language: Language.ARABIC,\n};\n\n/**\n * Get all chapter recitations for specific reciter\n * @description https://quran.api-docs.io/v4/audio-recitations/list-of-all-surah-audio-files-for-specific-reciter\n * @param {string} reciterId\n * @param {GetChapterRecitationOptions} options\n * @example\n * quran.v4.audio.findAllChapterRecitations('2')\n */\nconst findAllChapterRecitations = async (\n reciterId: string,\n options?: GetChapterRecitationOptions\n) => {\n const params = mergeApiOptions(options, defaultChapterRecitationsOptions);\n const { audioFiles } = await fetcher<{ audioFiles: ChapterRecitation[] }>(\n `/chapter_recitations/${reciterId}`,\n params,\n options?.fetchFn\n );\n return audioFiles;\n};\n\n/**\n * Get chapter recitation for specific reciter and a specific chapter\n * @description https://quran.api-docs.io/v4/audio-recitations/get-single-surah-audio-for-specific-reciter\n * @param {ChapterId} chapterId\n * @param {string} reciterId\n * @param {GetChapterRecitationOptions} options\n * @example\n * quran.v4.audio.findChapterRecitationById('1', '2') // first chapter recitation for reciter 2\n */\nconst findChapterRecitationById = async (\n chapterId: ChapterId,\n reciterId: string,\n options?: GetChapterRecitationOptions\n) => {\n if (!Utils.isValidChapterId(chapterId)) throw new Error('Invalid chapter id');\n\n const params = mergeApiOptions(options, defaultChapterRecitationsOptions);\n const { audioFile } = await fetcher<{ audioFile: ChapterRecitation }>(\n `/chapter_recitations/${reciterId}/${chapterId}`,\n params,\n options?.fetchFn\n );\n\n return audioFile;\n};\n\n/**\n * Get all verse audio files for a specific reciter and a specific chapter\n * @description https://quran.api-docs.io/v4/audio-recitations/get-ayah-recitations-for-specific-surah\n * @param {ChapterId} chapterId\n * @param {string} recitationId\n * @param {GetVerseRecitationOptions} options\n * @example\n * quran.v4.audio.findVerseRecitationsByChapter('1', '2')\n */\nconst findVerseRecitationsByChapter = async (\n chapterId: ChapterId,\n recitationId: string,\n options?: GetVerseRecitationOptions\n) => {\n if (!Utils.isValidChapterId(chapterId)) throw new Error('Invalid chapter id');\n\n const params = mergeApiOptions(options, defaultVerseRecitationsOptions);\n const data = await fetcher<{\n audioFiles: VerseRecitation[];\n pagination: Pagination;\n }>(\n `/recitations/${recitationId}/by_chapter/${chapterId}`,\n params,\n options?.fetchFn\n );\n\n return data;\n};\n\n/**\n * Get all verse audio files for a specific reciter and a specific juz\n * @description https://quran.api-docs.io/v4/audio-recitations/get-ayah-recitations-for-specific-juz\n * @param {JuzNumber} juz\n * @param {string} recitationId\n * @param {GetRecitationsOptions} options\n * @example\n * quran.v4.audio.findVerseRecitationsByJuz('1', '2')\n */\nconst findVerseRecitationsByJuz = async (\n juz: JuzNumber,\n recitationId: string,\n options?: GetVerseRecitationOptions\n) => {\n if (!Utils.isValidJuz(juz)) throw new Error('Invalid juz');\n\n const params = mergeApiOptions(options, defaultVerseRecitationsOptions);\n const data = await fetcher<{\n audioFiles: VerseRecitation[];\n pagination: Pagination;\n }>(`/recitations/${recitationId}/by_juz/${juz}`, params, options?.fetchFn);\n\n return data;\n};\n\n/**\n * Get all verse audio files for a specific reciter and a specific mushaf page\n * @description https://quran.api-docs.io/v4/audio-recitations/get-ayah-recitations-for-specific-madani-mushaf-page\n * @param {PageNumber} page\n * @param {string} recitationId\n * @param {GetVerseRecitationOptions} options\n * @example\n * quran.v4.audio.findVerseRecitationsByPage('1', '2')\n */\nconst findVerseRecitationsByPage = async (\n page: PageNumber,\n recitationId: string,\n options?: GetVerseRecitationOptions\n) => {\n if (!Utils.isValidQuranPage(page)) throw new Error('Invalid page');\n\n const params = mergeApiOptions(options, defaultVerseRecitationsOptions);\n const data = await fetcher<{\n audioFiles: VerseRecitation[];\n pagination: Pagination;\n }>(`/recitations/${recitationId}/by_page/${page}`, params, options?.fetchFn);\n\n return data;\n};\n\n/**\n * Get all verse audio files for a specific reciter and a specific rub\n * @description https://quran.api-docs.io/v4/audio-recitations/get-ayah-recitations-for-specific-rub\n * @param {RubNumber} rub\n * @param {string} recitationId\n * @param {GetVerseRecitationOptions} options\n * @example\n * quran.v4.audio.findVerseRecitationsByRub('1', '2')\n */\nconst findVerseRecitationsByRub = async (\n rub: RubNumber,\n recitationId: string,\n options?: GetVerseRecitationOptions\n) => {\n if (!Utils.isValidRub(rub)) throw new Error('Invalid rub');\n\n const params = mergeApiOptions(options, defaultVerseRecitationsOptions);\n const data = await fetcher<{\n audioFiles: VerseRecitation[];\n pagination: Pagination;\n }>(`/recitations/${recitationId}/by_rub/${rub}`, params, options?.fetchFn);\n\n return data;\n};\n\n/**\n * Get all verse audio files for a specific reciter and a specific hizb\n * @description https://quran.api-docs.io/v4/audio-recitations/get-ayah-recitations-for-specific-hizb\n * @param {HizbNumber} hizb\n * @param {string} recitationId\n * @param {GetVerseRecitationOptions} options\n * @example\n * quran.v4.audio.findVerseRecitationsByHizb('1', '2')\n */\nconst findVerseRecitationsByHizb = async (\n hizb: HizbNumber,\n recitationId: string,\n options?: GetVerseRecitationOptions\n) => {\n if (!Utils.isValidHizb(hizb)) throw new Error('Invalid hizb');\n\n const params = mergeApiOptions(options, defaultVerseRecitationsOptions);\n const data = await fetcher<{\n audioFiles: VerseRecitation[];\n pagination: Pagination;\n }>(`/recitations/${recitationId}/by_hizb/${hizb}`, params, options?.fetchFn);\n\n return data;\n};\n\n/**\n * Get all verse audio files for a specific reciter and a specific verse\n * @description https://quran.api-docs.io/v4/audio-recitations/get-ayah-recitations-for-specific-ayah\n * @param {VerseKey} key\n * @param {string} recitationId\n * @param {GetVerseRecitationOptions} options\n * @example\n * quran.v4.audio.findVerseRecitationsByKey('1:1', '2')\n */\nconst findVerseRecitationsByKey = async (\n key: VerseKey,\n recitationId: string,\n options?: GetVerseRecitationOptions\n) => {\n if (!Utils.isValidVerseKey(key)) throw new Error('Invalid verse key');\n\n const params = mergeApiOptions(options, defaultVerseRecitationsOptions);\n const data = await fetcher<{\n audioFiles: VerseRecitation[];\n pagination: Pagination;\n }>(`/recitations/${recitationId}/by_ayah/${key}`, params, options?.fetchFn);\n\n return data;\n};\n\nconst audio = {\n findAllChapterRecitations,\n findChapterRecitationById,\n findVerseRecitationsByChapter,\n findVerseRecitationsByJuz,\n findVerseRecitationsByPage,\n findVerseRecitationsByRub,\n findVerseRecitationsByHizb,\n findVerseRecitationsByKey,\n};\n\nexport default audio;\n","import {\n ChapterInfoResource,\n ChapterReciterResource,\n Language,\n LanguageResource,\n // RecitationInfoResource,\n RecitationResource,\n RecitationStylesResource,\n // TafsirInfoResource,\n TafsirResource,\n // TranslationInfoResource,\n TranslationResource,\n VerseMediaResource,\n} from '../../types';\nimport { BaseApiOptions } from '../../types/BaseApiOptions';\nimport { fetcher, mergeApiOptions } from './_fetcher';\n\ntype GetResourceOptions = Partial<BaseApiOptions>;\n\nconst defaultOptions: GetResourceOptions = {\n language: Language.ARABIC,\n};\n\n/**\n * Get all recitations.\n * @description https://quran.api-docs.io/v4/resources/recitations\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findAllRecitations()\n */\nconst findAllRecitations = async (options?: GetResourceOptions) => {\n const params = mergeApiOptions(options);\n const { recitations } = await fetcher<{\n recitations: RecitationResource[];\n }>('/resources/recitations', params, options?.fetchFn);\n\n return recitations;\n};\n\n// TODO: uncomment when API is ready\n/**\n * Get all recitation info.\n * @description https://quran.api-docs.io/v4/resources/recitation-info\n * @param {string} id recitation id\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findRecitationInfo('1')\n */\n// const findRecitationInfo = async (id: string, options?: GetResourceOptions) => {\n// const params = mergeApiOptions(options, defaultOptions);\n// const { info } = await fetcher<{\n// info: RecitationInfoResource;\n// }>(`/resources/recitations/${id}/info`, params, options?.fetchFn);\n\n// return info;\n// };\n\n/**\n * Get all translations.\n * @description https://quran.api-docs.io/v4/resources/translations\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findAllTranslations()\n */\nconst findAllTranslations = async (options?: GetResourceOptions) => {\n const params = mergeApiOptions(options, defaultOptions);\n const { translations } = await fetcher<{\n translations: TranslationResource[];\n }>('/resources/translations', params, options?.fetchFn);\n\n return translations;\n};\n\n// TODO: uncomment when API is ready\n/**\n * Get translation info.\n * @description https://quran.api-docs.io/v4/resources/translation-info\n * @param {string} id translation id\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findTranslationInfo('169')\n */\n// const findTranslationInfo = async (id: string, options?: GetResourceOptions) => {\n// const params = mergeApiOptions(options, defaultOptions);\n// const { info } = await fetcher<{\n// info: TranslationInfoResource;\n// }>(`/resources/translations/${id}/info`, params, options?.fetchFn);\n\n// return info;\n// };\n\n/**\n * Get all tafsirs.\n * @description https://quran.api-docs.io/v4/resources/tafsirs\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findAllTafsirs()\n */\nconst findAllTafsirs = async (options?: GetResourceOptions) => {\n const params = mergeApiOptions(options, defaultOptions);\n const { tafsirs } = await fetcher<{\n tafsirs: TafsirResource[];\n }>('/resources/tafsirs', params, options?.fetchFn);\n\n return tafsirs;\n};\n\n// TODO: uncomment when API is ready\n/**\n * Get tafsir info.\n * @description https://quran.api-docs.io/v4/resources/tafsirs-info\n * @param {string} id tafsir id\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findTranslationInfo('1')\n */\n// const findTafsirInfo = async (id: string, options?: GetResourceOptions) => {\n// const params = mergeApiOptions(options, defaultOptions);\n// const { info } = await fetcher<{\n// info: TafsirInfoResource;\n// }>(`/resources/tafsirs/${id}/info`, params, options?.fetchFn);\n\n// return info;\n// };\n\n/**\n * Get all recitation styles.\n * @description https://quran.api-docs.io/v4/resources/recitation-styles\n * @example\n * quran.v4.resources.findAllRecitationStyles()\n */\nconst findAllRecitationStyles = async (\n options?: Omit<BaseApiOptions, 'language'>\n) => {\n const { recitationStyles } = await fetcher<{\n recitationStyles: RecitationStylesResource;\n }>('/resources/recitation_styles', undefined, options?.fetchFn);\n\n return recitationStyles;\n};\n\n/**\n * Get all languages.\n * @description https://quran.api-docs.io/v4/resources/languages\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findAllLanguages()\n */\nconst findAllLanguages = async (options?: GetResourceOptions) => {\n const params = mergeApiOptions(options, defaultOptions);\n const { languages } = await fetcher<{\n languages: LanguageResource[];\n }>('/resources/languages', params, options?.fetchFn);\n\n return languages;\n};\n\n/**\n * Get all chapter infos.\n * @description https://quran.api-docs.io/v4/resources/chapter-info\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findAllChapterInfos()\n */\nconst findAllChapterInfos = async (options?: GetResourceOptions) => {\n const params = mergeApiOptions(options, defaultOptions);\n const { chapterInfos } = await fetcher<{\n chapterInfos: ChapterInfoResource[];\n }>('/resources/chapter_infos', params, options?.fetchFn);\n\n return chapterInfos;\n};\n\n/**\n * Get verse media.\n * @description https://quran.api-docs.io/v4/resources/verse_media\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findVerseMedia()\n */\nconst findVerseMedia = async (options?: GetResourceOptions) => {\n const params = mergeApiOptions(options, defaultOptions);\n const { verseMedia } = await fetcher<{\n verseMedia: VerseMediaResource;\n }>(`/resources/verse_media`, params, options?.fetchFn);\n\n return verseMedia;\n};\n\n/**\n * Get all chapter reciters.\n * @description https://quran.api-docs.io/v4/resources/list-of-chapter-reciters\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findAllChapterReciters()\n */\nconst findAllChapterReciters = async (options?: GetResourceOptions) => {\n const params = mergeApiOptions(options, defaultOptions);\n const { reciters } = await fetcher<{\n reciters: ChapterReciterResource[];\n }>(`/resources/chapter_reciters`, params, options?.fetchFn);\n\n return reciters;\n};\n\nconst resources = {\n findAllRecitations,\n findAllTranslations,\n findAllTafsirs,\n findAllRecitationStyles,\n findAllLanguages,\n findVerseMedia,\n findAllChapterReciters,\n findAllChapterInfos,\n // findRecitationInfo\n // findTranslationInfo\n // findTafsirInfo\n};\n\nexport default resources;\n","import { Language, SearchResponse } from '../../types';\nimport { BaseApiOptions } from '../../types/BaseApiOptions';\nimport { fetcher, mergeApiOptions } from './_fetcher';\n\ntype SearchOptions = Partial<\n BaseApiOptions & {\n size: number;\n page: number;\n }\n>;\n\nconst defaultSearchOptions: SearchOptions = {\n language: Language.ARABIC,\n size: 30,\n};\n\n/**\n * Search\n * @description https://quran.api-docs.io/v4/search/KfCmk4KQYbtyK9adj\n * @param {string} q search query\n * @param {SearchOptions} options\n * @example\n * quran.v4.search.search('نور')\n * quran.v4.search.search('نور', { language: Language.ENGLISH })\n * quran.v4.search.search('نور', { language: Language.ENGLISH, size: 10 })\n * quran.v4.search.search('نور', { language: Language.ENGLISH, page: 2 })\n */\nconst search = async (q: string, options?: SearchOptions) => {\n const params = mergeApiOptions({ q, ...options }, defaultSearchOptions);\n const { search } = await fetcher<SearchResponse>(\n '/search',\n params,\n options?.fetchFn\n );\n\n return search;\n};\n\nconst searchApi = { search };\n\nexport default searchApi;\n","import chapters from './chapters';\nimport verses from './verses';\nimport juzs from './juzs';\nimport audio from './audio';\nimport resources from './resources';\nimport search from './search';\n\nconst v4 = {\n chapters,\n verses,\n juzs,\n audio,\n resources,\n search,\n};\n\nexport default v4;\n","import v4 from './v4';\nimport utils from './utils';\n\nconst quran = {\n v4,\n utils,\n};\n\nexport default quran;\n"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,6 @@
1
+ import { camelizeKeys, decamelize, decamelizeKeys } from 'humps';
2
+
3
+ var E=(f=>(f.Word="word",f.End="end",f.Pause="pause",f.Sajdah="sajdah",f.RubElHizb="rub-el-hizb",f))(E||{});var d=(s=>(s.ARABIC="ar",s.ENGLISH="en",s.URDU="ur",s.BENGALI="bn",s.TURKISH="tr",s.SPANISH="es",s.GERMAN="de",s.BOSNIAN="bs",s.RUSSIAN="ru",s.ALBANIAN_AL="al",s.FRENCH="fr",s.DUTCH="nl",s.TAMIL="ta",s.TAJIK="tg",s.INDONESIAN="id",s.UZBEK="uz",s.VIETNAMESE="vi",s.CHINESE="zh",s.ITALIAN="it",s.JAPANESE="ja",s.MALAYALAM="ml",s.AMHARIC="am",s.KAZAKH="kk",s.PORTUGUESE="pt",s.TAGALOG="tl",s.THAI="th",s.KOREAN="ko",s.HINDI="hi",s.KURDISH="ku",s.HAUSA="ha",s.AZERI="az",s.SWAHILI="sw",s.PERSIAN="fa",s.SERBIAN="sr",s.MARANAO="mrn",s.AMAZIGH="zgh",s.ASSAMESE="as",s.BULGARIAN="bg",s.CHECHEN="ce",s.CZECH="cs",s.DIVEHI="dv",s.DHIVEHI="dv",s.MALDIVIAN="dv",s.FINNISH="fi",s.GUJAARATI="gu",s.HEBREW="he",s.GEORGIAN="ka",s.CENTRAL_KHMER="km",s.GANDA="lg",s.MARATHI="mr",s.YORUBA="yo",s.MALAY="ms",s.NEPALI="ne",s.SWEDISH="sv",s.TELUGU="te",s.TATAR="tt",s.UIGHUR="ug",s.UYGHUR="ug",s.UKRAINIAN="uk",s.NORWEGIAN="no",s.OROMO="om",s.POLISH="pl",s.PASHTO="ps",s.ROMANIAN="ro",s.SINDHI="sd",s.NORTHERN_SAMI="se",s.SINHALA="si",s.SINHALESE="si",s.SOMALI="so",s.ALBANIAN_SQ="sq",s))(d||{}),C=(i=>(i.MadaniV1="code_v1",i.MadaniV2="code_v2",i.Uthmani="text_uthmani",i))(C||{});var h=e=>e.startsWith("/")?e.slice(1):e;var B="https://api.quran.com/api/v4/",A=(e,r)=>{let t=`${B}${h(e)}`;if(!r)return t;let i=decamelizeKeys(r),n=new URLSearchParams(Object.entries(i).filter(([,f])=>f!==void 0)).toString();return n?`${t}?${n}`:t},a=async(e,r={},t)=>{if(t){let f=await t(A(e,r));return camelizeKeys(f)}if(typeof fetch>"u")throw new Error("fetch is not defined");let i=await fetch(A(e,r));if(!i.ok||i.status>=400)throw new Error(`${i.status} ${i.statusText}`);let n=await i.json();return camelizeKeys(n)},c=(e={},r={})=>{e.fetchFn&&(e.fetchFn=void 0);let t={...r,...e};if(t.fields){let i=[];Object.entries(t.fields).forEach(([n,f])=>{f&&i.push(decamelize(n));}),t.fields=i.join(",");}return t};var z={1:7,2:286,3:200,4:176,5:120,6:165,7:206,8:75,9:129,10:109,11:123,12:111,13:43,14:52,15:99,16:128,17:111,18:110,19:98,20:135,21:112,22:78,23:118,24:64,25:77,26:227,27:93,28:88,29:69,30:60,31:34,32:30,33:73,34:54,35:45,36:83,37:182,38:88,39:75,40:85,41:54,42:53,43:89,44:59,45:37,46:35,47:38,48:29,49:18,50:45,51:60,52:49,53:62,54:55,55:78,56:96,57:29,58:22,59:24,60:13,61:14,62:11,63:11,64:18,65:12,66:12,67:30,68:52,69:52,70:44,71:28,72:28,73:20,74:56,75:40,76:31,77:50,78:40,79:46,80:42,81:29,82:19,83:36,84:25,85:22,86:17,87:19,88:26,89:30,90:20,91:15,92:21,93:11,94:8,95:8,96:19,97:5,98:8,99:8,100:11,101:11,102:8,103:3,104:9,105:5,106:4,107:7,108:3,109:6,110:3,111:5,112:4,113:5,114:6},I=e=>{let r=typeof e=="number"?e:Number(e);return !(!r||r<=0||r>114)},H=e=>{let r=typeof e=="number"?e:Number(e);return !(!r||r<=0||r>30)},P=e=>{let r=typeof e=="number"?e:Number(e);return !(!r||r<=0||r>240)},U=e=>{let r=typeof e=="number"?e:Number(e);return !(!r||r<=0||r>60)},T=e=>{let r=typeof e=="number"?e:Number(e);return !(!r||r<=0||r>604)},K=e=>{let[r,t]=e.trim().split(":");if(!r||!t||!I(r))return !1;let i=Number(t),n=z[r];return !(!i||i<=0||i>n)},$={isValidChapterId:I,isValidJuz:H,isValidRub:P,isValidHizb:U,isValidQuranPage:T,isValidVerseKey:K},o=$;var p={language:"ar"},M=async e=>{let r=c(e,p),{chapters:t}=await a("/chapters",r,e==null?void 0:e.fetchFn);return t},j=async(e,r)=>{if(!o.isValidChapterId(e))throw new Error("Invalid chapter id");let t=c(r,p),{chapter:i}=await a(`/chapters/${e}`,t,r==null?void 0:r.fetchFn);return i},_=async(e,r)=>{if(!o.isValidChapterId(e))throw new Error("Invalid chapter id");let t=c(r,p),{chapterInfo:i}=await a(`/chapters/${e}/info`,t,r==null?void 0:r.fetchFn);return i},k={findAll:M,findById:j,findInfoById:_},b=k;var J={language:"ar",perPage:50,words:!1},m=(e={})=>{let r=c(e,J);if(r.translations&&(r.translations=r.translations.join(",")),r.tafsirs&&(r.tafsirs=r.tafsirs.join(",")),r.wordFields){let t=[];Object.entries(r.wordFields).forEach(([i,n])=>{n&&t.push(decamelize(i));}),r.wordFields=t.join(",");}if(r.translationFields){let t=[];Object.entries(r.translationFields).forEach(([i,n])=>{n&&t.push(decamelize(i));}),r.translationFields=t.join(",");}return r.reciter&&(r.audio=r.reciter,r.reciter=void 0),r},D=async(e,r)=>{if(!o.isValidVerseKey(e))throw new Error("Invalid verse key");let t=m(r),i=`/verses/by_key/${e}`,{verse:n}=await a(i,t,r==null?void 0:r.fetchFn);return n},W=async(e,r)=>{if(!o.isValidChapterId(e))throw new Error("Invalid chapter id");let t=m(r),i=`/verses/by_chapter/${e}`,{verses:n}=await a(i,t,r==null?void 0:r.fetchFn);return n},g=async(e,r)=>{if(!o.isValidQuranPage(e))throw new Error("Invalid page");let t=m(r),i=`/verses/by_page/${e}`,{verses:n}=await a(i,t,r==null?void 0:r.fetchFn);return n},Z=async(e,r)=>{if(!o.isValidJuz(e))throw new Error("Invalid juz");let t=m(r),i=`/verses/by_juz/${e}`,{verses:n}=await a(i,t,r==null?void 0:r.fetchFn);return n},q=async(e,r)=>{if(!o.isValidHizb(e))throw new Error("Invalid hizb");let t=m(r),i=`/verses/by_hizb/${e}`,{verses:n}=await a(i,t,r==null?void 0:r.fetchFn);return n},Y=async e=>{let r=m(e),{verse:t}=await a("/verses/random",r,e==null?void 0:e.fetchFn);return t},Q={findByKey:D,findByChapter:W,findByPage:g,findByJuz:Z,findByHizb:q,findRandom:Y},O=Q;var X=async e=>{let{juzs:r}=await a("/juzs",void 0,e==null?void 0:e.fetchFn);return r},L={findAll:X},V=L;var N={language:"ar"},l={language:"ar"},ee=async(e,r)=>{let t=c(r,N),{audioFiles:i}=await a(`/chapter_recitations/${e}`,t,r==null?void 0:r.fetchFn);return i},re=async(e,r,t)=>{if(!o.isValidChapterId(e))throw new Error("Invalid chapter id");let i=c(t,N),{audioFile:n}=await a(`/chapter_recitations/${r}/${e}`,i,t==null?void 0:t.fetchFn);return n},te=async(e,r,t)=>{if(!o.isValidChapterId(e))throw new Error("Invalid chapter id");let i=c(t,l);return await a(`/recitations/${r}/by_chapter/${e}`,i,t==null?void 0:t.fetchFn)},se=async(e,r,t)=>{if(!o.isValidJuz(e))throw new Error("Invalid juz");let i=c(t,l);return await a(`/recitations/${r}/by_juz/${e}`,i,t==null?void 0:t.fetchFn)},ie=async(e,r,t)=>{if(!o.isValidQuranPage(e))throw new Error("Invalid page");let i=c(t,l);return await a(`/recitations/${r}/by_page/${e}`,i,t==null?void 0:t.fetchFn)},ae=async(e,r,t)=>{if(!o.isValidRub(e))throw new Error("Invalid rub");let i=c(t,l);return await a(`/recitations/${r}/by_rub/${e}`,i,t==null?void 0:t.fetchFn)},ne=async(e,r,t)=>{if(!o.isValidHizb(e))throw new Error("Invalid hizb");let i=c(t,l);return await a(`/recitations/${r}/by_hizb/${e}`,i,t==null?void 0:t.fetchFn)},ce=async(e,r,t)=>{if(!o.isValidVerseKey(e))throw new Error("Invalid verse key");let i=c(t,l);return await a(`/recitations/${r}/by_ayah/${e}`,i,t==null?void 0:t.fetchFn)},oe={findAllChapterRecitations:ee,findChapterRecitationById:re,findVerseRecitationsByChapter:te,findVerseRecitationsByJuz:se,findVerseRecitationsByPage:ie,findVerseRecitationsByRub:ae,findVerseRecitationsByHizb:ne,findVerseRecitationsByKey:ce},w=oe;var u={language:"ar"},fe=async e=>{let r=c(e),{recitations:t}=await a("/resources/recitations",r,e==null?void 0:e.fetchFn);return t},de=async e=>{let r=c(e,u),{translations:t}=await a("/resources/translations",r,e==null?void 0:e.fetchFn);return t},me=async e=>{let r=c(e,u),{tafsirs:t}=await a("/resources/tafsirs",r,e==null?void 0:e.fetchFn);return t},le=async e=>{let{recitationStyles:r}=await a("/resources/recitation_styles",void 0,e==null?void 0:e.fetchFn);return r},ue=async e=>{let r=c(e,u),{languages:t}=await a("/resources/languages",r,e==null?void 0:e.fetchFn);return t},pe=async e=>{let r=c(e,u),{chapterInfos:t}=await a("/resources/chapter_infos",r,e==null?void 0:e.fetchFn);return t},he=async e=>{let r=c(e,u),{verseMedia:t}=await a("/resources/verse_media",r,e==null?void 0:e.fetchFn);return t},Re=async e=>{let r=c(e,u),{reciters:t}=await a("/resources/chapter_reciters",r,e==null?void 0:e.fetchFn);return t},Ae={findAllRecitations:fe,findAllTranslations:de,findAllTafsirs:me,findAllRecitationStyles:le,findAllLanguages:ue,findVerseMedia:he,findAllChapterReciters:Re,findAllChapterInfos:pe},x=Ae;var Ie={language:"ar",size:30},be=async(e,r)=>{let t=c({q:e,...r},Ie),{search:i}=await a("/search",t,r==null?void 0:r.fetchFn);return i},ye={search:be},F=ye;var Oe={chapters:b,verses:O,juzs:V,audio:w,resources:x,search:F},v=Oe;var Ve={v4:v,utils:o},Ne=Ve;
4
+
5
+ export { E as CharType, d as Language, C as QuranFont, Ne as quran };
6
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types/api/Word.ts","../src/types/index.ts","../src/sdk/v4/_fetcher.ts","../src/utils/misc.ts","../src/sdk/utils.ts","../src/sdk/v4/chapters.ts","../src/sdk/v4/verses.ts","../src/sdk/v4/juzs.ts","../src/sdk/v4/audio.ts","../src/sdk/v4/resources.ts","../src/sdk/v4/search.ts","../src/sdk/v4/index.ts","../src/sdk/index.ts"],"names":["CharType","Language","QuranFont","camelizeKeys","decamelize","decamelizeKeys","removeBeginningSlash","url","API_BASE_URL","makeUrl","params","baseUrl","paramsWithDecamelizedKeys","paramsString","value","fetcher","fetchFn","json","res","mergeApiOptions","options","defaultOptions","final","fields","key","versesMapping","isValidChapterId","id","parsedId","isValidJuz","juz","parsedJuz","isValidRub","rub","parsedRub","isValidHizb","hizb","parsedHizb","isValidQuranPage","page","parsedPage","isValidVerseKey","chapterId","verseId","parsedVerse","verseCount","utils","utils_default","findAll","chapters","findById","chapter","findInfoById","chapterInfo","chapters_default","mergeVerseOptions","result","wordFields","translationFields","findByKey","verse","findByChapter","verses","findByPage","findByJuz","findByHizb","findRandom","verses_default","juzs","juzs_default","defaultChapterRecitationsOptions","defaultVerseRecitationsOptions","findAllChapterRecitations","reciterId","audioFiles","findChapterRecitationById","audioFile","findVerseRecitationsByChapter","recitationId","findVerseRecitationsByJuz","findVerseRecitationsByPage","findVerseRecitationsByRub","findVerseRecitationsByHizb","findVerseRecitationsByKey","audio","audio_default","findAllRecitations","recitations","findAllTranslations","translations","findAllTafsirs","tafsirs","findAllRecitationStyles","recitationStyles","findAllLanguages","languages","findAllChapterInfos","chapterInfos","findVerseMedia","verseMedia","findAllChapterReciters","reciters","resources","resources_default","defaultSearchOptions","search","q","searchApi","search_default","v4","v4_default","quran","sdk_default"],"mappings":"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DF,EAAM,OAASC,EAAO,KAAK,GAAG,CAChC,CAEA,OAAOD,CACT,EEpEO,IAAMG,EAAgB,CAC3B,EAAK,EACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,GACL,EAAK,IACL,GAAM,IACN,GAAM,IACN,GAAM,IACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,IACN,GAAM,IACN,GAAM,IACN,GAAM,GACN,GAAM,IACN,GAAM,IACN,GAAM,GACN,GAAM,IACN,GAAM,GACN,GAAM,GACN,GAAM,IACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,IACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,GACN,GAAM,EACN,GAAM,EACN,GAAM,GACN,GAAM,EACN,GAAM,EACN,GAAM,EACN,IAAO,GACP,IAAO,GACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,EACP,IAAO,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","sourcesContent":["import { VerseKey } from '../VerseKey';\nimport { Translation } from './Translation';\nimport { Transliteration } from './Transliteration';\n\nexport enum CharType {\n Word = 'word',\n End = 'end',\n Pause = 'pause',\n Sajdah = 'sajdah',\n RubElHizb = 'rub-el-hizb',\n}\n\nexport interface Word {\n id?: number;\n position: number;\n audioUrl: string;\n charTypeName: CharType;\n codeV1?: string;\n codeV2?: string;\n pageNumber?: number;\n lineNumber?: number;\n text?: string;\n textUthmani?: string;\n textIndopak?: string;\n textImlaei?: string;\n translation: Translation;\n transliteration: Transliteration;\n location?: string; // chapter:verse:word\n verseKey?: VerseKey;\n}\n","export enum Language {\n ARABIC = 'ar',\n ENGLISH = 'en',\n URDU = 'ur',\n BENGALI = 'bn',\n TURKISH = 'tr',\n SPANISH = 'es',\n GERMAN = 'de',\n BOSNIAN = 'bs',\n RUSSIAN = 'ru',\n ALBANIAN_AL = 'al',\n FRENCH = 'fr',\n DUTCH = 'nl',\n TAMIL = 'ta',\n TAJIK = 'tg',\n INDONESIAN = 'id',\n UZBEK = 'uz',\n VIETNAMESE = 'vi',\n CHINESE = 'zh',\n ITALIAN = 'it',\n JAPANESE = 'ja',\n MALAYALAM = 'ml',\n AMHARIC = 'am',\n KAZAKH = 'kk',\n PORTUGUESE = 'pt',\n TAGALOG = 'tl',\n THAI = 'th',\n KOREAN = 'ko',\n HINDI = 'hi',\n KURDISH = 'ku',\n HAUSA = 'ha',\n AZERI = 'az',\n SWAHILI = 'sw',\n PERSIAN = 'fa',\n SERBIAN = 'sr',\n MARANAO = 'mrn',\n AMAZIGH = 'zgh',\n ASSAMESE = 'as',\n BULGARIAN = 'bg',\n CHECHEN = 'ce',\n CZECH = 'cs',\n\n DIVEHI = 'dv',\n DHIVEHI = 'dv',\n MALDIVIAN = 'dv',\n\n FINNISH = 'fi',\n GUJAARATI = 'gu',\n HEBREW = 'he',\n GEORGIAN = 'ka',\n CENTRAL_KHMER = 'km',\n GANDA = 'lg',\n MARATHI = 'mr',\n YORUBA = 'yo',\n MALAY = 'ms',\n NEPALI = 'ne',\n SWEDISH = 'sv',\n TELUGU = 'te',\n TATAR = 'tt',\n\n UIGHUR = 'ug',\n UYGHUR = 'ug',\n\n UKRAINIAN = 'uk',\n NORWEGIAN = 'no',\n OROMO = 'om',\n POLISH = 'pl',\n PASHTO = 'ps',\n ROMANIAN = 'ro',\n SINDHI = 'sd',\n NORTHERN_SAMI = 'se',\n\n SINHALA = 'si',\n SINHALESE = 'si',\n\n SOMALI = 'so',\n ALBANIAN_SQ = 'sq',\n}\n\nexport enum QuranFont {\n MadaniV1 = 'code_v1',\n MadaniV2 = 'code_v2',\n Uthmani = 'text_uthmani',\n}\n\nexport type VerseField =\n | 'chapterId'\n | 'textUthmani'\n | 'textUthmaniSimple'\n | 'textImlaei'\n | 'textImlaeiSimple'\n | 'textIndopak'\n | 'textUthmaniTajweed'\n | 'imageUrl'\n | 'imageWidth'\n | 'codeV1'\n | 'codeV2'\n | 'v1Page'\n | 'v2Page';\n\nexport type WordField =\n | 'v1Page'\n | 'v2Page'\n | 'textUthmani'\n | 'textImlaei'\n | 'textIndopak'\n | 'verseKey'\n | 'location'\n | 'codeV1'\n | 'codeV2';\n\nexport type TranslationField =\n | 'resourceName'\n | 'verseId'\n | 'languageId'\n | 'languageName'\n | 'verseKey'\n | 'chapterId'\n | 'verseNumber'\n | 'juzNumber'\n | 'hizbNumber'\n | 'rubNumber'\n | 'pageNumber';\n\nexport type VerseRecitationField = 'id' | 'chapterId' | 'segments' | 'format';\n\nexport * from './VerseKey';\nexport * from './ChapterId';\nexport * from './HizbNumber';\nexport * from './JuzNumber';\nexport * from './PageNumber';\nexport * from './RubNumber';\n\nexport * from './api';\n\nexport * from './FetchFn';\n","import { camelizeKeys, decamelize, decamelizeKeys } from 'humps';\nimport { FetchFn } from '../../types';\nimport { BaseApiOptions } from '../../types/BaseApiOptions';\nimport { removeBeginningSlash } from '../../utils/misc';\n\nexport const API_BASE_URL = 'https://api.quran.com/api/v4/';\n\nexport const makeUrl = (url: string, params?: Record<string, unknown>) => {\n const baseUrl = `${API_BASE_URL}${removeBeginningSlash(url)}`;\n if (!params) return baseUrl;\n\n const paramsWithDecamelizedKeys = decamelizeKeys(params) as Record<\n string,\n string\n >;\n const paramsString = new URLSearchParams(\n Object.entries(paramsWithDecamelizedKeys).filter(\n ([, value]) => value !== undefined\n )\n ).toString();\n if (!paramsString) return baseUrl;\n\n return `${baseUrl}?${paramsString}`;\n};\n\nexport const fetcher = async <T extends object>(\n url: string,\n params: Record<string, unknown> = {},\n fetchFn?: FetchFn\n) => {\n if (fetchFn) {\n const json = await fetchFn(makeUrl(url, params));\n return camelizeKeys(json) as T;\n }\n\n if (typeof fetch === 'undefined') {\n throw new Error('fetch is not defined');\n }\n\n // if there is no fetchFn, we use the global fetch\n const res = await fetch(makeUrl(url, params));\n\n if (!res.ok || res.status >= 400) {\n throw new Error(`${res.status} ${res.statusText}`);\n }\n\n const json = await res.json();\n\n return camelizeKeys(json) as T;\n};\n\ntype MergeApiOptionsObject = Pick<BaseApiOptions, 'fetchFn'> & {\n fields?: Record<string, boolean>;\n} & Record<string, unknown>;\n\nexport const mergeApiOptions = (\n options: MergeApiOptionsObject = {},\n defaultOptions: Record<string, unknown> = {}\n) => {\n // we can set it to undefined because `makeUrl` will filter it out\n if (options.fetchFn) options.fetchFn = undefined;\n\n const final: Record<string, unknown> = {\n ...defaultOptions,\n ...options,\n };\n\n if (final.fields) {\n const fields: string[] = [];\n Object.entries(final.fields).forEach(([key, value]) => {\n if (value) fields.push(decamelize(key));\n });\n\n // convert `fields` to a string sperated by commas\n final.fields = fields.join(',');\n }\n\n return final;\n};\n","export const removeBeginningSlash = (url: string) => {\n return url.startsWith('/') ? url.slice(1) : url;\n};\n","import {\n ChapterId,\n HizbNumber,\n JuzNumber,\n PageNumber,\n RubNumber,\n VerseKey,\n} from '../types';\n\n// this maps chapterNumber to verseCount\nexport const versesMapping = {\n '1': 7,\n '2': 286,\n '3': 200,\n '4': 176,\n '5': 120,\n '6': 165,\n '7': 206,\n '8': 75,\n '9': 129,\n '10': 109,\n '11': 123,\n '12': 111,\n '13': 43,\n '14': 52,\n '15': 99,\n '16': 128,\n '17': 111,\n '18': 110,\n '19': 98,\n '20': 135,\n '21': 112,\n '22': 78,\n '23': 118,\n '24': 64,\n '25': 77,\n '26': 227,\n '27': 93,\n '28': 88,\n '29': 69,\n '30': 60,\n '31': 34,\n '32': 30,\n '33': 73,\n '34': 54,\n '35': 45,\n '36': 83,\n '37': 182,\n '38': 88,\n '39': 75,\n '40': 85,\n '41': 54,\n '42': 53,\n '43': 89,\n '44': 59,\n '45': 37,\n '46': 35,\n '47': 38,\n '48': 29,\n '49': 18,\n '50': 45,\n '51': 60,\n '52': 49,\n '53': 62,\n '54': 55,\n '55': 78,\n '56': 96,\n '57': 29,\n '58': 22,\n '59': 24,\n '60': 13,\n '61': 14,\n '62': 11,\n '63': 11,\n '64': 18,\n '65': 12,\n '66': 12,\n '67': 30,\n '68': 52,\n '69': 52,\n '70': 44,\n '71': 28,\n '72': 28,\n '73': 20,\n '74': 56,\n '75': 40,\n '76': 31,\n '77': 50,\n '78': 40,\n '79': 46,\n '80': 42,\n '81': 29,\n '82': 19,\n '83': 36,\n '84': 25,\n '85': 22,\n '86': 17,\n '87': 19,\n '88': 26,\n '89': 30,\n '90': 20,\n '91': 15,\n '92': 21,\n '93': 11,\n '94': 8,\n '95': 8,\n '96': 19,\n '97': 5,\n '98': 8,\n '99': 8,\n '100': 11,\n '101': 11,\n '102': 8,\n '103': 3,\n '104': 9,\n '105': 5,\n '106': 4,\n '107': 7,\n '108': 3,\n '109': 6,\n '110': 3,\n '111': 5,\n '112': 4,\n '113': 5,\n '114': 6,\n};\n\n/**\n * Validates chapter id\n * @param id chapter id\n * @example \n isValidChapterId('1') // true\n isValidChapterId('114') // true\n isValidChapterId('0') // false\n isValidChapterId('-1') // false\n isValidChapterId('200') // false\n */\nconst isValidChapterId = (id: string | number): id is ChapterId => {\n const parsedId = typeof id === 'number' ? id : Number(id);\n if (!parsedId || parsedId <= 0 || parsedId > 114) return false;\n return true;\n};\n\n/**\n * Validates juz number\n * @param juz juz number\n * @example \n isValidJuz('1') // true\n isValidJuz('30') // true\n isValidJuz('0') // false\n isValidJuz('-1') // false\n isValidJuz('200') // false\n */\nconst isValidJuz = (juz: string | number): juz is JuzNumber => {\n const parsedJuz = typeof juz === 'number' ? juz : Number(juz);\n if (!parsedJuz || parsedJuz <= 0 || parsedJuz > 30) return false;\n return true;\n};\n\n/**\n * Validates rub number\n * @param rub rub number\n * @example \n isValidRub('1') // true\n isValidRub('240') // true\n isValidRub('0') // false\n isValidRub('-1') // false\n isValidRub('300') // false\n */\nconst isValidRub = (rub: string | number): rub is RubNumber => {\n const parsedRub = typeof rub === 'number' ? rub : Number(rub);\n if (!parsedRub || parsedRub <= 0 || parsedRub > 240) return false;\n return true;\n};\n\n/**\n * Validates hizb number\n * @param hizb hizb number\n * @example \n isValidHizb('1') // true\n isValidHizb('60') // true\n isValidHizb('0') // false\n isValidHizb('-1') // false\n isValidHizb('200') // false\n */\nconst isValidHizb = (hizb: string | number): hizb is HizbNumber => {\n const parsedHizb = typeof hizb === 'number' ? hizb : Number(hizb);\n if (!parsedHizb || parsedHizb <= 0 || parsedHizb > 60) return false;\n return true;\n};\n\n/**\n * Validates mushaf page number\n * @param page mushaf page number\n * @example \n isValidQuranPage('1') // true\n isValidQuranPage('604') // true\n isValidQuranPage('0') // false\n isValidQuranPage('-1') // false\n isValidQuranPage('1000') // false\n */\nconst isValidQuranPage = (page: string | number): page is PageNumber => {\n const parsedPage = typeof page === 'number' ? page : Number(page);\n if (!parsedPage || parsedPage <= 0 || parsedPage > 604) return false;\n return true;\n};\n\n/**\n * Validates verse key\n * @param key colon separated verse key (chapter:verse)\n * @example \n isValidVerseKey('1:1') // true\n isValidVerseKey('30:1') // true\n isValidVerseKey('0') // false\n isValidVerseKey('1:-') // false\n isValidVerseKey('1_1') // false\n */\nconst isValidVerseKey = (key: string): key is VerseKey => {\n const [chapterId, verseId] = key.trim().split(':');\n if (!chapterId || !verseId || !isValidChapterId(chapterId)) return false;\n\n const parsedVerse = Number(verseId);\n const verseCount = (versesMapping as Record<string, number>)[chapterId];\n if (!parsedVerse || parsedVerse <= 0 || parsedVerse > verseCount)\n return false;\n\n return true;\n};\n\nconst utils = {\n isValidChapterId,\n isValidJuz,\n isValidRub,\n isValidHizb,\n isValidQuranPage,\n isValidVerseKey,\n};\n\nexport default utils;\n","import { Chapter, ChapterId, ChapterInfo, Language } from '../../types';\nimport { fetcher, mergeApiOptions } from './_fetcher';\nimport Utils from '../utils';\nimport { BaseApiOptions } from '../../types/BaseApiOptions';\n\ntype GetChapterOptions = Partial<BaseApiOptions>;\n\nconst defaultOptions: GetChapterOptions = {\n language: Language.ARABIC,\n};\n\n/**\n * Get all chapters.\n * @description https://quran.api-docs.io/v4/chapters/list-chapters\n * @param {GetChapterOptions} options\n * @example\n * quran.v4.chapters.findAll()\n */\nconst findAll = async (options?: GetChapterOptions) => {\n const params = mergeApiOptions(options, defaultOptions);\n const { chapters } = await fetcher<{ chapters: Chapter[] }>(\n '/chapters',\n params,\n options?.fetchFn\n );\n\n return chapters;\n};\n\n/**\n * Get chapter by id.\n * @description https://quran.api-docs.io/v4/chapters/get-chapter\n * @param {ChapterId} id chapter id, minimum 1, maximum 114\n * @param {GetChapterOptions} options\n * @example\n * quran.v4.chapters.findById('1')\n * quran.v4.chapters.findById('114')\n */\nconst findById = async (id: ChapterId, options?: GetChapterOptions) => {\n if (!Utils.isValidChapterId(id)) throw new Error('Invalid chapter id');\n\n const params = mergeApiOptions(options, defaultOptions);\n const { chapter } = await fetcher<{ chapter: Chapter }>(\n `/chapters/${id}`,\n params,\n options?.fetchFn\n );\n\n return chapter;\n};\n\n/**\n * Get chapter info by id.\n * @description https://quran.api-docs.io/v4/chapters/chapter_info\n * @param {ChapterId} id chapter id, minimum 1, maximum 114\n * @param {GetChapterOptions} options\n * @example\n * quran.v4.chapters.findInfoById('1')\n * quran.v4.chapters.findInfoById('114')\n */\nconst findInfoById = async (id: ChapterId, options?: GetChapterOptions) => {\n if (!Utils.isValidChapterId(id)) throw new Error('Invalid chapter id');\n\n const params = mergeApiOptions(options, defaultOptions);\n const { chapterInfo } = await fetcher<{ chapterInfo: ChapterInfo }>(\n `/chapters/${id}/info`,\n params,\n options?.fetchFn\n );\n\n return chapterInfo;\n};\n\nconst chapters = {\n findAll,\n findById,\n findInfoById,\n};\n\nexport default chapters;\n","import {\n ChapterId,\n HizbNumber,\n JuzNumber,\n Language,\n PageNumber,\n TranslationField,\n // RubNumber,\n Verse,\n VerseField,\n VerseKey,\n WordField,\n} from '../../types';\nimport { decamelize } from 'humps';\nimport Utils from '../utils';\nimport { fetcher, mergeApiOptions } from './_fetcher';\nimport { BaseApiOptions } from '../../types/BaseApiOptions';\n\ntype GetVerseOptions = Partial<\n BaseApiOptions & {\n reciter: string | number;\n words: boolean;\n translations: string[] | number[];\n tafsirs: string[] | number[];\n wordFields: Partial<Record<WordField, boolean>>;\n translationFields: Partial<Record<TranslationField, boolean>>;\n fields: Partial<Record<VerseField, boolean>>;\n page: number;\n perPage: number;\n }\n>;\n\nconst defaultOptions: GetVerseOptions = {\n language: Language.ARABIC,\n perPage: 50,\n words: false,\n};\n\nconst mergeVerseOptions = (options: GetVerseOptions = {}) => {\n const result = mergeApiOptions(options, defaultOptions);\n\n // @ts-expect-error - we accept an array of strings, however, the API expects a comma separated string\n if (result.translations) result.translations = result.translations.join(',');\n\n // @ts-expect-error - we accept an array of strings, however, the API expects a comma separated string\n if (result.tafsirs) result.tafsirs = result.tafsirs.join(',');\n\n if (result.wordFields) {\n const wordFields: string[] = [];\n Object.entries(result.wordFields).forEach(([key, value]) => {\n if (value) wordFields.push(decamelize(key));\n });\n result.wordFields = wordFields.join(',');\n }\n\n if (result.translationFields) {\n const translationFields: string[] = [];\n Object.entries(result.translationFields).forEach(([key, value]) => {\n if (value) translationFields.push(decamelize(key));\n });\n result.translationFields = translationFields.join(',');\n }\n\n // rename `reciter` to `audio` because the API expects `audio`\n if (result.reciter) {\n result.audio = result.reciter;\n result.reciter = undefined;\n }\n\n return result;\n};\n\n/**\n * Get a specific ayah with key. Key is combination of surah number and ayah number.\n * @description https://quran.api-docs.io/v4/verses/by-specific-verse-by-key\n * @param {VerseKey} key - surah number and ayah number separated by a colon.\n * @param {GetVerseOptions} options\n * @example\n * quran.v4.verses.findByKey('1:1')\n * quran.v4.verses.findByKey('101:5')\n */\nconst findByKey = async (key: VerseKey, options?: GetVerseOptions) => {\n if (!Utils.isValidVerseKey(key)) throw new Error('Invalid verse key');\n const params = mergeVerseOptions(options);\n const url = `/verses/by_key/${key}`;\n const { verse } = await fetcher<{ verse: Verse }>(\n url,\n params,\n options?.fetchFn\n );\n\n return verse;\n};\n\n/**\n * Get all ayahs for a specific chapter (surah).\n * @description https://quran.api-docs.io/v4/verses/by_chapter\n * @param {ChapterId} id - chapter id (surah number)\n * @param {GetVerseOptions} options\n * @example\n * quran.v4.verses.findByChapter('1')\n * quran.v4.verses.findByChapter('101')\n */\nconst findByChapter = async (id: ChapterId, options?: GetVerseOptions) => {\n if (!Utils.isValidChapterId(id)) throw new Error('Invalid chapter id');\n const params = mergeVerseOptions(options);\n const url = `/verses/by_chapter/${id}`;\n const { verses } = await fetcher<{ verses: Verse[] }>(\n url,\n params,\n options?.fetchFn\n );\n\n return verses;\n};\n\n/**\n * Get all ayahs for a specific page in the Quran.\n * @description https://quran.api-docs.io/v4/verses/by-page\n * @param {PageNumber} page - Quran page number\n * @param {GetVerseOptions} options\n * @example\n * quran.v4.verses.findByPage('1')\n * quran.v4.verses.findByPage('101')\n */\nconst findByPage = async (page: PageNumber, options?: GetVerseOptions) => {\n if (!Utils.isValidQuranPage(page)) throw new Error('Invalid page');\n\n const params = mergeVerseOptions(options);\n const url = `/verses/by_page/${page}`;\n const { verses } = await fetcher<{ verses: Verse[] }>(\n url,\n params,\n options?.fetchFn\n );\n\n return verses;\n};\n\n/**\n * Get all ayahs for a Juz.\n * @description https://quran.api-docs.io/v4/verses/by-juz\n * @param {JuzNumber} id - juz number\n * @param {GetVerseOptions} options\n * @example\n * quran.v4.verses.findByJuz('1')\n * quran.v4.verses.findByJuz('29')\n */\nconst findByJuz = async (juz: JuzNumber, options?: GetVerseOptions) => {\n if (!Utils.isValidJuz(juz)) throw new Error('Invalid juz');\n\n const params = mergeVerseOptions(options);\n const url = `/verses/by_juz/${juz}`;\n const { verses } = await fetcher<{ verses: Verse[] }>(\n url,\n params,\n options?.fetchFn\n );\n\n return verses;\n};\n\n/**\n * Get all ayahs for a Hizb.\n * @description https://quran.api-docs.io/v4/verses/by-hizb-number\n * @param {HizbNumber} hizb - hizb number\n * @param {GetVerseOptions} options\n * @example\n * quran.v4.verses.findByHizb('1')\n * quran.v4.verses.findByHizb('29')\n */\nconst findByHizb = async (hizb: HizbNumber, options?: GetVerseOptions) => {\n if (!Utils.isValidHizb(hizb)) throw new Error('Invalid hizb');\n\n const params = mergeVerseOptions(options);\n const url = `/verses/by_hizb/${hizb}`;\n const { verses } = await fetcher<{ verses: Verse[] }>(\n url,\n params,\n options?.fetchFn\n );\n\n return verses;\n};\n\n// TODO: uncomment when API is fixed\n/**\n * Get all ayahs for a Rub.\n * @description https://quran.api-docs.io/v4/verses/by-rub-number\n * @param {RubNumber} rub - rub number\n * @param {GetVerseOptions} options\n * @example\n * quran.v4.verses.findByRub('1')\n * quran.v4.verses.findByRub('29')\n */\n// const findByRub = async (rub: RubNumber, options?: GetVerseOptions) => {\n// if (!Utils.isValidRub(rub)) throw new Error('Invalid rub');\n\n// const params = getVerseOptions(options);\n// const url = `/verses/by_rub/${rub}`;\n// const { verses } = await fetcher<{ verses: Verse[] }>(url, params);\n\n// return verses;\n// };\n\n/**\n * Get a random ayah.\n * @description https://quran.api-docs.io/v4/verses/random\n * @param {GetVerseOptions} options\n * @example\n * quran.v4.verses.findRandom()\n */\nconst findRandom = async (options?: GetVerseOptions) => {\n const params = mergeVerseOptions(options);\n const { verse } = await fetcher<{ verse: Verse }>(\n '/verses/random',\n params,\n options?.fetchFn\n );\n\n return verse;\n};\n\nconst verses = {\n findByKey,\n findByChapter,\n findByPage,\n findByJuz,\n findByHizb,\n // findByRub,\n findRandom,\n};\n\nexport default verses;\n","import { Juz } from '../../types';\nimport { BaseApiOptions } from '../../types/BaseApiOptions';\nimport { fetcher } from './_fetcher';\n\n/**\n * Get All Juzs\n * @description https://quran.api-docs.io/v4/juz/get-all-juzs\n * @example\n * quran.v4.juzs.findAll()\n */\nconst findAll = async (options?: Omit<BaseApiOptions, 'language'>) => {\n const { juzs } = await fetcher<{ juzs: Juz[] }>(\n '/juzs',\n undefined,\n options?.fetchFn\n );\n return juzs;\n};\n\nconst juzs = { findAll };\n\nexport default juzs;\n","import {\n ChapterRecitation,\n VerseRecitation,\n ChapterId,\n HizbNumber,\n JuzNumber,\n Language,\n PageNumber,\n Pagination,\n RubNumber,\n VerseKey,\n VerseRecitationField,\n} from '../../types';\nimport Utils from '../utils';\nimport { fetcher, mergeApiOptions } from './_fetcher';\nimport { BaseApiOptions } from '../../types/BaseApiOptions';\n\ntype GetChapterRecitationOptions = Partial<BaseApiOptions>;\n\nconst defaultChapterRecitationsOptions: GetChapterRecitationOptions = {\n language: Language.ARABIC,\n};\n\ntype GetVerseRecitationOptions = Partial<\n BaseApiOptions & {\n fields: Partial<Record<VerseRecitationField, boolean>>;\n }\n>;\n\nconst defaultVerseRecitationsOptions: GetVerseRecitationOptions = {\n language: Language.ARABIC,\n};\n\n/**\n * Get all chapter recitations for specific reciter\n * @description https://quran.api-docs.io/v4/audio-recitations/list-of-all-surah-audio-files-for-specific-reciter\n * @param {string} reciterId\n * @param {GetChapterRecitationOptions} options\n * @example\n * quran.v4.audio.findAllChapterRecitations('2')\n */\nconst findAllChapterRecitations = async (\n reciterId: string,\n options?: GetChapterRecitationOptions\n) => {\n const params = mergeApiOptions(options, defaultChapterRecitationsOptions);\n const { audioFiles } = await fetcher<{ audioFiles: ChapterRecitation[] }>(\n `/chapter_recitations/${reciterId}`,\n params,\n options?.fetchFn\n );\n return audioFiles;\n};\n\n/**\n * Get chapter recitation for specific reciter and a specific chapter\n * @description https://quran.api-docs.io/v4/audio-recitations/get-single-surah-audio-for-specific-reciter\n * @param {ChapterId} chapterId\n * @param {string} reciterId\n * @param {GetChapterRecitationOptions} options\n * @example\n * quran.v4.audio.findChapterRecitationById('1', '2') // first chapter recitation for reciter 2\n */\nconst findChapterRecitationById = async (\n chapterId: ChapterId,\n reciterId: string,\n options?: GetChapterRecitationOptions\n) => {\n if (!Utils.isValidChapterId(chapterId)) throw new Error('Invalid chapter id');\n\n const params = mergeApiOptions(options, defaultChapterRecitationsOptions);\n const { audioFile } = await fetcher<{ audioFile: ChapterRecitation }>(\n `/chapter_recitations/${reciterId}/${chapterId}`,\n params,\n options?.fetchFn\n );\n\n return audioFile;\n};\n\n/**\n * Get all verse audio files for a specific reciter and a specific chapter\n * @description https://quran.api-docs.io/v4/audio-recitations/get-ayah-recitations-for-specific-surah\n * @param {ChapterId} chapterId\n * @param {string} recitationId\n * @param {GetVerseRecitationOptions} options\n * @example\n * quran.v4.audio.findVerseRecitationsByChapter('1', '2')\n */\nconst findVerseRecitationsByChapter = async (\n chapterId: ChapterId,\n recitationId: string,\n options?: GetVerseRecitationOptions\n) => {\n if (!Utils.isValidChapterId(chapterId)) throw new Error('Invalid chapter id');\n\n const params = mergeApiOptions(options, defaultVerseRecitationsOptions);\n const data = await fetcher<{\n audioFiles: VerseRecitation[];\n pagination: Pagination;\n }>(\n `/recitations/${recitationId}/by_chapter/${chapterId}`,\n params,\n options?.fetchFn\n );\n\n return data;\n};\n\n/**\n * Get all verse audio files for a specific reciter and a specific juz\n * @description https://quran.api-docs.io/v4/audio-recitations/get-ayah-recitations-for-specific-juz\n * @param {JuzNumber} juz\n * @param {string} recitationId\n * @param {GetRecitationsOptions} options\n * @example\n * quran.v4.audio.findVerseRecitationsByJuz('1', '2')\n */\nconst findVerseRecitationsByJuz = async (\n juz: JuzNumber,\n recitationId: string,\n options?: GetVerseRecitationOptions\n) => {\n if (!Utils.isValidJuz(juz)) throw new Error('Invalid juz');\n\n const params = mergeApiOptions(options, defaultVerseRecitationsOptions);\n const data = await fetcher<{\n audioFiles: VerseRecitation[];\n pagination: Pagination;\n }>(`/recitations/${recitationId}/by_juz/${juz}`, params, options?.fetchFn);\n\n return data;\n};\n\n/**\n * Get all verse audio files for a specific reciter and a specific mushaf page\n * @description https://quran.api-docs.io/v4/audio-recitations/get-ayah-recitations-for-specific-madani-mushaf-page\n * @param {PageNumber} page\n * @param {string} recitationId\n * @param {GetVerseRecitationOptions} options\n * @example\n * quran.v4.audio.findVerseRecitationsByPage('1', '2')\n */\nconst findVerseRecitationsByPage = async (\n page: PageNumber,\n recitationId: string,\n options?: GetVerseRecitationOptions\n) => {\n if (!Utils.isValidQuranPage(page)) throw new Error('Invalid page');\n\n const params = mergeApiOptions(options, defaultVerseRecitationsOptions);\n const data = await fetcher<{\n audioFiles: VerseRecitation[];\n pagination: Pagination;\n }>(`/recitations/${recitationId}/by_page/${page}`, params, options?.fetchFn);\n\n return data;\n};\n\n/**\n * Get all verse audio files for a specific reciter and a specific rub\n * @description https://quran.api-docs.io/v4/audio-recitations/get-ayah-recitations-for-specific-rub\n * @param {RubNumber} rub\n * @param {string} recitationId\n * @param {GetVerseRecitationOptions} options\n * @example\n * quran.v4.audio.findVerseRecitationsByRub('1', '2')\n */\nconst findVerseRecitationsByRub = async (\n rub: RubNumber,\n recitationId: string,\n options?: GetVerseRecitationOptions\n) => {\n if (!Utils.isValidRub(rub)) throw new Error('Invalid rub');\n\n const params = mergeApiOptions(options, defaultVerseRecitationsOptions);\n const data = await fetcher<{\n audioFiles: VerseRecitation[];\n pagination: Pagination;\n }>(`/recitations/${recitationId}/by_rub/${rub}`, params, options?.fetchFn);\n\n return data;\n};\n\n/**\n * Get all verse audio files for a specific reciter and a specific hizb\n * @description https://quran.api-docs.io/v4/audio-recitations/get-ayah-recitations-for-specific-hizb\n * @param {HizbNumber} hizb\n * @param {string} recitationId\n * @param {GetVerseRecitationOptions} options\n * @example\n * quran.v4.audio.findVerseRecitationsByHizb('1', '2')\n */\nconst findVerseRecitationsByHizb = async (\n hizb: HizbNumber,\n recitationId: string,\n options?: GetVerseRecitationOptions\n) => {\n if (!Utils.isValidHizb(hizb)) throw new Error('Invalid hizb');\n\n const params = mergeApiOptions(options, defaultVerseRecitationsOptions);\n const data = await fetcher<{\n audioFiles: VerseRecitation[];\n pagination: Pagination;\n }>(`/recitations/${recitationId}/by_hizb/${hizb}`, params, options?.fetchFn);\n\n return data;\n};\n\n/**\n * Get all verse audio files for a specific reciter and a specific verse\n * @description https://quran.api-docs.io/v4/audio-recitations/get-ayah-recitations-for-specific-ayah\n * @param {VerseKey} key\n * @param {string} recitationId\n * @param {GetVerseRecitationOptions} options\n * @example\n * quran.v4.audio.findVerseRecitationsByKey('1:1', '2')\n */\nconst findVerseRecitationsByKey = async (\n key: VerseKey,\n recitationId: string,\n options?: GetVerseRecitationOptions\n) => {\n if (!Utils.isValidVerseKey(key)) throw new Error('Invalid verse key');\n\n const params = mergeApiOptions(options, defaultVerseRecitationsOptions);\n const data = await fetcher<{\n audioFiles: VerseRecitation[];\n pagination: Pagination;\n }>(`/recitations/${recitationId}/by_ayah/${key}`, params, options?.fetchFn);\n\n return data;\n};\n\nconst audio = {\n findAllChapterRecitations,\n findChapterRecitationById,\n findVerseRecitationsByChapter,\n findVerseRecitationsByJuz,\n findVerseRecitationsByPage,\n findVerseRecitationsByRub,\n findVerseRecitationsByHizb,\n findVerseRecitationsByKey,\n};\n\nexport default audio;\n","import {\n ChapterInfoResource,\n ChapterReciterResource,\n Language,\n LanguageResource,\n // RecitationInfoResource,\n RecitationResource,\n RecitationStylesResource,\n // TafsirInfoResource,\n TafsirResource,\n // TranslationInfoResource,\n TranslationResource,\n VerseMediaResource,\n} from '../../types';\nimport { BaseApiOptions } from '../../types/BaseApiOptions';\nimport { fetcher, mergeApiOptions } from './_fetcher';\n\ntype GetResourceOptions = Partial<BaseApiOptions>;\n\nconst defaultOptions: GetResourceOptions = {\n language: Language.ARABIC,\n};\n\n/**\n * Get all recitations.\n * @description https://quran.api-docs.io/v4/resources/recitations\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findAllRecitations()\n */\nconst findAllRecitations = async (options?: GetResourceOptions) => {\n const params = mergeApiOptions(options);\n const { recitations } = await fetcher<{\n recitations: RecitationResource[];\n }>('/resources/recitations', params, options?.fetchFn);\n\n return recitations;\n};\n\n// TODO: uncomment when API is ready\n/**\n * Get all recitation info.\n * @description https://quran.api-docs.io/v4/resources/recitation-info\n * @param {string} id recitation id\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findRecitationInfo('1')\n */\n// const findRecitationInfo = async (id: string, options?: GetResourceOptions) => {\n// const params = mergeApiOptions(options, defaultOptions);\n// const { info } = await fetcher<{\n// info: RecitationInfoResource;\n// }>(`/resources/recitations/${id}/info`, params, options?.fetchFn);\n\n// return info;\n// };\n\n/**\n * Get all translations.\n * @description https://quran.api-docs.io/v4/resources/translations\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findAllTranslations()\n */\nconst findAllTranslations = async (options?: GetResourceOptions) => {\n const params = mergeApiOptions(options, defaultOptions);\n const { translations } = await fetcher<{\n translations: TranslationResource[];\n }>('/resources/translations', params, options?.fetchFn);\n\n return translations;\n};\n\n// TODO: uncomment when API is ready\n/**\n * Get translation info.\n * @description https://quran.api-docs.io/v4/resources/translation-info\n * @param {string} id translation id\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findTranslationInfo('169')\n */\n// const findTranslationInfo = async (id: string, options?: GetResourceOptions) => {\n// const params = mergeApiOptions(options, defaultOptions);\n// const { info } = await fetcher<{\n// info: TranslationInfoResource;\n// }>(`/resources/translations/${id}/info`, params, options?.fetchFn);\n\n// return info;\n// };\n\n/**\n * Get all tafsirs.\n * @description https://quran.api-docs.io/v4/resources/tafsirs\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findAllTafsirs()\n */\nconst findAllTafsirs = async (options?: GetResourceOptions) => {\n const params = mergeApiOptions(options, defaultOptions);\n const { tafsirs } = await fetcher<{\n tafsirs: TafsirResource[];\n }>('/resources/tafsirs', params, options?.fetchFn);\n\n return tafsirs;\n};\n\n// TODO: uncomment when API is ready\n/**\n * Get tafsir info.\n * @description https://quran.api-docs.io/v4/resources/tafsirs-info\n * @param {string} id tafsir id\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findTranslationInfo('1')\n */\n// const findTafsirInfo = async (id: string, options?: GetResourceOptions) => {\n// const params = mergeApiOptions(options, defaultOptions);\n// const { info } = await fetcher<{\n// info: TafsirInfoResource;\n// }>(`/resources/tafsirs/${id}/info`, params, options?.fetchFn);\n\n// return info;\n// };\n\n/**\n * Get all recitation styles.\n * @description https://quran.api-docs.io/v4/resources/recitation-styles\n * @example\n * quran.v4.resources.findAllRecitationStyles()\n */\nconst findAllRecitationStyles = async (\n options?: Omit<BaseApiOptions, 'language'>\n) => {\n const { recitationStyles } = await fetcher<{\n recitationStyles: RecitationStylesResource;\n }>('/resources/recitation_styles', undefined, options?.fetchFn);\n\n return recitationStyles;\n};\n\n/**\n * Get all languages.\n * @description https://quran.api-docs.io/v4/resources/languages\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findAllLanguages()\n */\nconst findAllLanguages = async (options?: GetResourceOptions) => {\n const params = mergeApiOptions(options, defaultOptions);\n const { languages } = await fetcher<{\n languages: LanguageResource[];\n }>('/resources/languages', params, options?.fetchFn);\n\n return languages;\n};\n\n/**\n * Get all chapter infos.\n * @description https://quran.api-docs.io/v4/resources/chapter-info\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findAllChapterInfos()\n */\nconst findAllChapterInfos = async (options?: GetResourceOptions) => {\n const params = mergeApiOptions(options, defaultOptions);\n const { chapterInfos } = await fetcher<{\n chapterInfos: ChapterInfoResource[];\n }>('/resources/chapter_infos', params, options?.fetchFn);\n\n return chapterInfos;\n};\n\n/**\n * Get verse media.\n * @description https://quran.api-docs.io/v4/resources/verse_media\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findVerseMedia()\n */\nconst findVerseMedia = async (options?: GetResourceOptions) => {\n const params = mergeApiOptions(options, defaultOptions);\n const { verseMedia } = await fetcher<{\n verseMedia: VerseMediaResource;\n }>(`/resources/verse_media`, params, options?.fetchFn);\n\n return verseMedia;\n};\n\n/**\n * Get all chapter reciters.\n * @description https://quran.api-docs.io/v4/resources/list-of-chapter-reciters\n * @param {GetResourceOptions} options\n * @example\n * quran.v4.resources.findAllChapterReciters()\n */\nconst findAllChapterReciters = async (options?: GetResourceOptions) => {\n const params = mergeApiOptions(options, defaultOptions);\n const { reciters } = await fetcher<{\n reciters: ChapterReciterResource[];\n }>(`/resources/chapter_reciters`, params, options?.fetchFn);\n\n return reciters;\n};\n\nconst resources = {\n findAllRecitations,\n findAllTranslations,\n findAllTafsirs,\n findAllRecitationStyles,\n findAllLanguages,\n findVerseMedia,\n findAllChapterReciters,\n findAllChapterInfos,\n // findRecitationInfo\n // findTranslationInfo\n // findTafsirInfo\n};\n\nexport default resources;\n","import { Language, SearchResponse } from '../../types';\nimport { BaseApiOptions } from '../../types/BaseApiOptions';\nimport { fetcher, mergeApiOptions } from './_fetcher';\n\ntype SearchOptions = Partial<\n BaseApiOptions & {\n size: number;\n page: number;\n }\n>;\n\nconst defaultSearchOptions: SearchOptions = {\n language: Language.ARABIC,\n size: 30,\n};\n\n/**\n * Search\n * @description https://quran.api-docs.io/v4/search/KfCmk4KQYbtyK9adj\n * @param {string} q search query\n * @param {SearchOptions} options\n * @example\n * quran.v4.search.search('نور')\n * quran.v4.search.search('نور', { language: Language.ENGLISH })\n * quran.v4.search.search('نور', { language: Language.ENGLISH, size: 10 })\n * quran.v4.search.search('نور', { language: Language.ENGLISH, page: 2 })\n */\nconst search = async (q: string, options?: SearchOptions) => {\n const params = mergeApiOptions({ q, ...options }, defaultSearchOptions);\n const { search } = await fetcher<SearchResponse>(\n '/search',\n params,\n options?.fetchFn\n );\n\n return search;\n};\n\nconst searchApi = { search };\n\nexport default searchApi;\n","import chapters from './chapters';\nimport verses from './verses';\nimport juzs from './juzs';\nimport audio from './audio';\nimport resources from './resources';\nimport search from './search';\n\nconst v4 = {\n chapters,\n verses,\n juzs,\n audio,\n resources,\n search,\n};\n\nexport default v4;\n","import v4 from './v4';\nimport utils from './utils';\n\nconst quran = {\n v4,\n utils,\n};\n\nexport default quran;\n"]}
package/package.json CHANGED
@@ -5,58 +5,61 @@
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
8
- "version": "1.6.0",
8
+ "version": "1.7.0",
9
9
  "license": "MIT",
10
10
  "main": "dist/index.js",
11
11
  "typings": "dist/index.d.ts",
12
- "module": "dist/api.esm.js",
12
+ "module": "dist/index.mjs",
13
13
  "files": [
14
14
  "dist",
15
15
  "src"
16
16
  ],
17
17
  "scripts": {
18
- "start": "dts watch",
19
- "build": "dts build",
20
- "test": "dts test",
21
- "test:dev": "dts test --watch",
22
- "lint": "dts lint src test mocks",
18
+ "start": "tsup --watch",
19
+ "build": "tsup",
20
+ "test": "vitest run",
21
+ "test:dev": "vitest",
22
+ "test:coverage": "vitest run --coverage",
23
+ "lint": "eslint src/** test/** mocks/**",
23
24
  "prepare": "husky install",
24
25
  "size": "size-limit",
25
26
  "analyze": "size-limit --why"
26
27
  },
28
+ "dependencies": {
29
+ "humps": "^2.0.1"
30
+ },
27
31
  "devDependencies": {
32
+ "cross-fetch": "^3.1.5",
28
33
  "@size-limit/preset-small-lib": "^7.0.8",
29
34
  "@types/humps": "^2.0.1",
30
- "dts-cli": "^1.4.0",
35
+ "@typescript-eslint/eslint-plugin": "^5.42.0",
36
+ "@typescript-eslint/parser": "^5.42.0",
37
+ "@vitest/coverage-c8": "^0.24.4",
38
+ "eslint": "^8.26.0",
39
+ "eslint-config-prettier": "^8.5.0",
40
+ "eslint-plugin-prettier": "^4.2.1",
31
41
  "fast-check": "^3.3.0",
32
42
  "husky": "^7.0.4",
33
43
  "msw": "^0.39.2",
44
+ "prettier": "^2.7.1",
34
45
  "rollup-plugin-analyzer": "^4.0.0",
35
46
  "size-limit": "^7.0.8",
36
47
  "tslib": "^2.3.1",
37
- "typescript": "^4.6.2"
38
- },
39
- "prettier": {
40
- "printWidth": 80,
41
- "semi": true,
42
- "singleQuote": true,
43
- "trailingComma": "es5"
48
+ "tsup": "^6.3.0",
49
+ "typescript": "^4.6.2",
50
+ "vitest": "^0.24.4"
44
51
  },
45
52
  "size-limit": [
46
53
  {
47
- "path": "dist/api.cjs.production.min.js",
54
+ "path": "dist/index.js",
48
55
  "limit": "15 KB"
49
56
  },
50
57
  {
51
- "path": "dist/api.esm.js",
58
+ "path": "dist/index.mjs",
52
59
  "limit": "15 KB"
53
60
  }
54
61
  ],
55
62
  "engines": {
56
63
  "node": ">=12"
57
- },
58
- "dependencies": {
59
- "cross-fetch": "^3.1.5",
60
- "humps": "^2.0.1"
61
64
  }
62
65
  }
package/src/sdk/utils.ts CHANGED
@@ -1,3 +1,12 @@
1
+ import {
2
+ ChapterId,
3
+ HizbNumber,
4
+ JuzNumber,
5
+ PageNumber,
6
+ RubNumber,
7
+ VerseKey,
8
+ } from '../types';
9
+
1
10
  // this maps chapterNumber to verseCount
2
11
  export const versesMapping = {
3
12
  '1': 7,
@@ -126,7 +135,7 @@ export const versesMapping = {
126
135
  isValidChapterId('-1') // false
127
136
  isValidChapterId('200') // false
128
137
  */
129
- const isValidChapterId = (id: string | number) => {
138
+ const isValidChapterId = (id: string | number): id is ChapterId => {
130
139
  const parsedId = typeof id === 'number' ? id : Number(id);
131
140
  if (!parsedId || parsedId <= 0 || parsedId > 114) return false;
132
141
  return true;
@@ -142,7 +151,7 @@ const isValidChapterId = (id: string | number) => {
142
151
  isValidJuz('-1') // false
143
152
  isValidJuz('200') // false
144
153
  */
145
- const isValidJuz = (juz: string | number) => {
154
+ const isValidJuz = (juz: string | number): juz is JuzNumber => {
146
155
  const parsedJuz = typeof juz === 'number' ? juz : Number(juz);
147
156
  if (!parsedJuz || parsedJuz <= 0 || parsedJuz > 30) return false;
148
157
  return true;
@@ -158,7 +167,7 @@ const isValidJuz = (juz: string | number) => {
158
167
  isValidRub('-1') // false
159
168
  isValidRub('300') // false
160
169
  */
161
- const isValidRub = (rub: string | number) => {
170
+ const isValidRub = (rub: string | number): rub is RubNumber => {
162
171
  const parsedRub = typeof rub === 'number' ? rub : Number(rub);
163
172
  if (!parsedRub || parsedRub <= 0 || parsedRub > 240) return false;
164
173
  return true;
@@ -174,7 +183,7 @@ const isValidRub = (rub: string | number) => {
174
183
  isValidHizb('-1') // false
175
184
  isValidHizb('200') // false
176
185
  */
177
- const isValidHizb = (hizb: string | number) => {
186
+ const isValidHizb = (hizb: string | number): hizb is HizbNumber => {
178
187
  const parsedHizb = typeof hizb === 'number' ? hizb : Number(hizb);
179
188
  if (!parsedHizb || parsedHizb <= 0 || parsedHizb > 60) return false;
180
189
  return true;
@@ -190,7 +199,7 @@ const isValidHizb = (hizb: string | number) => {
190
199
  isValidQuranPage('-1') // false
191
200
  isValidQuranPage('1000') // false
192
201
  */
193
- const isValidQuranPage = (page: string | number) => {
202
+ const isValidQuranPage = (page: string | number): page is PageNumber => {
194
203
  const parsedPage = typeof page === 'number' ? page : Number(page);
195
204
  if (!parsedPage || parsedPage <= 0 || parsedPage > 604) return false;
196
205
  return true;
@@ -206,19 +215,19 @@ const isValidQuranPage = (page: string | number) => {
206
215
  isValidVerseKey('1:-') // false
207
216
  isValidVerseKey('1_1') // false
208
217
  */
209
- const isValidVerseKey = (key: string) => {
218
+ const isValidVerseKey = (key: string): key is VerseKey => {
210
219
  const [chapterId, verseId] = key.trim().split(':');
211
220
  if (!chapterId || !verseId || !isValidChapterId(chapterId)) return false;
212
221
 
213
222
  const parsedVerse = Number(verseId);
214
- const verseCount = (versesMapping as any)[chapterId];
223
+ const verseCount = (versesMapping as Record<string, number>)[chapterId];
215
224
  if (!parsedVerse || parsedVerse <= 0 || parsedVerse > verseCount)
216
225
  return false;
217
226
 
218
227
  return true;
219
228
  };
220
229
 
221
- const Utils = {
230
+ const utils = {
222
231
  isValidChapterId,
223
232
  isValidJuz,
224
233
  isValidRub,
@@ -227,4 +236,4 @@ const Utils = {
227
236
  isValidVerseKey,
228
237
  };
229
238
 
230
- export default Utils;
239
+ export default utils;
@@ -1,6 +1,6 @@
1
- import fetch from 'cross-fetch';
2
- import { camelizeKeys, decamelizeKeys } from 'humps';
3
- import stringify from '../../utils/qs-stringify';
1
+ import { camelizeKeys, decamelize, decamelizeKeys } from 'humps';
2
+ import { FetchFn } from '../../types';
3
+ import { BaseApiOptions } from '../../types/BaseApiOptions';
4
4
  import { removeBeginningSlash } from '../../utils/misc';
5
5
 
6
6
  export const API_BASE_URL = 'https://api.quran.com/api/v4/';
@@ -9,8 +9,15 @@ export const makeUrl = (url: string, params?: Record<string, unknown>) => {
9
9
  const baseUrl = `${API_BASE_URL}${removeBeginningSlash(url)}`;
10
10
  if (!params) return baseUrl;
11
11
 
12
- const decamelizedKeys = decamelizeKeys(params);
13
- const paramsString = stringify(decamelizedKeys);
12
+ const paramsWithDecamelizedKeys = decamelizeKeys(params) as Record<
13
+ string,
14
+ string
15
+ >;
16
+ const paramsString = new URLSearchParams(
17
+ Object.entries(paramsWithDecamelizedKeys).filter(
18
+ ([, value]) => value !== undefined
19
+ )
20
+ ).toString();
14
21
  if (!paramsString) return baseUrl;
15
22
 
16
23
  return `${baseUrl}?${paramsString}`;
@@ -18,11 +25,55 @@ export const makeUrl = (url: string, params?: Record<string, unknown>) => {
18
25
 
19
26
  export const fetcher = async <T extends object>(
20
27
  url: string,
21
- params: Record<string, unknown> = {}
28
+ params: Record<string, unknown> = {},
29
+ fetchFn?: FetchFn
22
30
  ) => {
31
+ if (fetchFn) {
32
+ const json = await fetchFn(makeUrl(url, params));
33
+ return camelizeKeys(json) as T;
34
+ }
35
+
36
+ if (typeof fetch === 'undefined') {
37
+ throw new Error('fetch is not defined');
38
+ }
39
+
40
+ // if there is no fetchFn, we use the global fetch
23
41
  const res = await fetch(makeUrl(url, params));
24
- if (res.status >= 400) throw new Error(`${res.status} ${res.statusText}`);
42
+
43
+ if (!res.ok || res.status >= 400) {
44
+ throw new Error(`${res.status} ${res.statusText}`);
45
+ }
46
+
25
47
  const json = await res.json();
26
48
 
27
49
  return camelizeKeys(json) as T;
28
50
  };
51
+
52
+ type MergeApiOptionsObject = Pick<BaseApiOptions, 'fetchFn'> & {
53
+ fields?: Record<string, boolean>;
54
+ } & Record<string, unknown>;
55
+
56
+ export const mergeApiOptions = (
57
+ options: MergeApiOptionsObject = {},
58
+ defaultOptions: Record<string, unknown> = {}
59
+ ) => {
60
+ // we can set it to undefined because `makeUrl` will filter it out
61
+ if (options.fetchFn) options.fetchFn = undefined;
62
+
63
+ const final: Record<string, unknown> = {
64
+ ...defaultOptions,
65
+ ...options,
66
+ };
67
+
68
+ if (final.fields) {
69
+ const fields: string[] = [];
70
+ Object.entries(final.fields).forEach(([key, value]) => {
71
+ if (value) fields.push(decamelize(key));
72
+ });
73
+
74
+ // convert `fields` to a string sperated by commas
75
+ final.fields = fields.join(',');
76
+ }
77
+
78
+ return final;
79
+ };