Skip to content

feat: migrate SDK to Quran Foundation Content APIs with OAuth2 support #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: dev
Choose a base branch
from

Conversation

basit3407
Copy link

This PR completes the migration of the @quranjs/api SDK to the new Quran Foundation Content APIs.

✅ Summary of changes:

  • Replaced legacy Quran.com endpoints with Quran Foundation's /content/api/v4 endpoints
  • Implemented OAuth2 Client Credentials flow with built-in token caching
  • Added a global configure() method for user-supplied credentials
  • Created new qf.* namespace for all updated wrappers (chapters, verses, search, etc.)
  • Updated internal fetcher and token manager to support headers and query serialization
  • Verified all endpoints via manual tests (search, audio, chapters, verses, juzs, etc.)
  • README changes prepared but not yet published

📝 Note:
This PR does not publish to npm yet. Final publish and README release will follow once documentation is live on api-docs.quran.foundation.

basit3407 added 10 commits July 1, 2025 23:35
with OAuth2 support

- Migrated API base URL from Quran.com to Quran Foundation's Content APIs.
- Implemented OAuth2 Client Credentials flow using `configure()` and `tokenManager.ts`.
- Added global SDK config via `configure()` and `getConfig()` functions.
- Updated fetcher logic to include automatic token injection and refresh.
- Created `src/sdk/qf/` namespace for new API wrappers (chapters, verses, etc.).
- Updated endpoint wrappers to use new API base (`/content/api/v4`) and auth headers.
- Preserved legacy `v4` namespace for backward compatibility.
- Reorganized project to support modular endpoint structure.

BREAKING CHANGE: Users must now call `configure({ clientId, clientSecret })` before using the SDK.
APIs (pre-publish)

- Refactored internal fetcher and token manager to support Quran Foundation Content APIs
- Implemented OAuth2 Client Credentials flow using configure() setup
- Migrated all wrappers (chapters, verses, search, juzs, audio, etc.) to qf.* namespace
- Updated response parsing and added internal test coverage for all major endpoints

Note: README and npm publish are deferred until documentation is migrated and finalized.
…rapper

Update README for Quran Foundation SDK
Copy link

vercel bot commented Jul 3, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
api ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 3, 2025 5:30pm

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR migrates the existing @quranjs/api SDK to use Quran Foundation’s v4 Content APIs with OAuth2 client-credentials support, introduces a global configure() call, and restructures everything under a qf namespace.

  • Swap out legacy endpoints for /content/api/v4 and wrap calls under quran.qf.*
  • Implement OAuth2 Client Credentials flow with token caching
  • Convert all response types and parameters to snake_case and add a mergeApiOptions helper

Reviewed Changes

Copilot reviewed 35 out of 37 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/manual.test.ts Added a manual smoke-test script for all qf endpoints
src/utils/misc.ts Introduced mergeApiOptions helper
src/types/api/*.ts Updated all API type interfaces to snake_case
src/sdk/qf/* Updated wrapper modules (chapters, verses, etc.) to v4 endpoints and merged options
src/auth/tokenManager.ts Added OAuth2 token manager with caching and retries
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (3)

test/manual.test.ts:30

  • There's an extra } in the template literal (${verseById.text_uthmani}}). It should be ${verseById.text_uthmani}.
    console.log(`✅ Verse 1 text: ${verseById.text_uthmani}}`);

test/manual.test.ts:41

  • This reuses findAll() for Juz but logs "Juz 1"—likely you intended to call a method for fetching a single Juz mapping or by ID rather than listing all.
    const juz = await quran.qf.juzs.findAll();

src/types/api/Resources.ts:74

  • The closing brace is on the same line as translated_name, making this invalid syntax. Move the } to its own line.
  translated_name: TranslatedName;}

@@ -1,3 +1,7 @@
export const removeBeginningSlash = (url: string) => {
return url.startsWith('/') ? url.slice(1) : url;
};

export function mergeApiOptions<T>(defaults: T, overrides?: Partial<T>): T {
Copy link
Preview

Copilot AI Jul 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mergeApiOptions expects (defaults, overrides), but callers often pass (options, defaultOptions), inverting merge priority. Swap arguments in calls or adjust the function signature to ensure user-provided options override defaults.

Suggested change
export function mergeApiOptions<T>(defaults: T, overrides?: Partial<T>): T {
export function mergeApiOptions<T>(overrides?: Partial<T>, defaults: T): T {

Copilot uses AI. Check for mistakes.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed the function calls.

};

const mergeVerseOptions = (options: GetVerseOptions = {}) => {
const result = mergeApiOptions(options, defaultOptions);
Copy link
Preview

Copilot AI Jul 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here options and defaultOptions are passed in the wrong order to mergeApiOptions, causing defaults to override user input. Swap to mergeApiOptions(defaultOptions, options).

Suggested change
const result = mergeApiOptions(options, defaultOptions);
const result = mergeApiOptions(defaultOptions, options);

Copilot uses AI. Check for mistakes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant