Skip to content

fix(api): type the documented verse, word and translation fields - #111

Open
marouanebatrone wants to merge 1 commit into
quran:mainfrom
marouanebatrone:fix/verse-field-types
Open

marouanebatrone wants to merge 1 commit into
quran:mainfrom
marouanebatrone:fix/verse-field-types

Conversation

@marouanebatrone

Copy link
Copy Markdown
Contributor

Problem

The verse field-selection types are missing names that the field reference documents, so typed calls can't request them without a cast:

await client.verses.findByKey("1:2", {
  words: true,
  wordFields: { textIndopakNastaleeq: true },
  // TS2353: 'textIndopakNastaleeq' does not exist in type 'Partial<Record<WordField, boolean>>'
});

The word schema in openAPI/content/v4.json says to request IndoPak Nastaleeq word text with word_fields=text_indopak_nastaleeq, and it deprecates textIndopak in its favor. The response types don't declare what these fields return either, so verse.words?.[0]?.textIndopakNastaleeq doesn't compile.

TranslationField also offers "rubNumber", which is sent as translation_fields=rub_number. The API doesn't define that field: it returns the number as rub_el_hizb_number, so Translation.rubNumber is never set. Meanwhile TypeScript rejects the correct name, rubElHizbNumber, with "Did you mean 'hizbNumber'?".

These names from the field reference are missing:

Type Added
VerseField textQpcHafs, textQpcNastaleeqHafs, textQpcNastaleeq, pageNumber
WordField textIndopakNastaleeq, textUthmaniTajweed, textQpcHafs, textImlaeiSimple, textUthmaniSimple, verseId, chapterId, lineNumber, lineV1, lineV2
TranslationField rubElHizbNumber, rukuNumber, manzilNumber, id

I left out the deprecated qpc_uthmani_hafs alias.

Change

  • The names above are added to VerseField, WordField and TranslationField, and each is sent under its documented wire name.
  • The matching optional response properties are declared:
    • Verse: textQpcHafs, textQpcNastaleeqHafs, textQpcNastaleeq.
    • Word: textIndopakNastaleeq (string | null, as in the spec), textUthmaniTajweed, textQpcHafs, textImlaeiSimple, textUthmaniSimple, verseId, chapterId, v1Page, v2Page, lineV1, lineV2.
    • Translation: rubElHizbNumber, rukuNumber, manzilNumber.
  • "rubNumber" stays in TranslationField so existing code still compiles, with a comment that the API doesn't know it. Translation.rubNumber is marked @deprecated in favor of rubElHizbNumber.
  • This is a types-only change with no runtime effect. A patch changeset is added.

Tests

A new test in test/verse-fields.test.ts requests every added field through client.verses.findByKey() and checks two things:

  • The query uses the documented names: fields=page_number,text_qpc_hafs,…, word_fields=chapter_id,line_number,line_v1,line_v2,text_imlaei_simple,text_indopak_nastaleeq,… and translation_fields=id,manzil_number,rub_el_hizb_number,ruku_number.
  • The camelized response properties are typed and populated.

On main, pnpm typecheck reports 16 errors in this test: TS2353 on the field maps, and TS2339 or TS2551 on the response properties. With the change it passes.

The public v4 endpoint also returns these documented fields:

  • for verses: text_qpc_hafs and text_qpc_nastaleeq(_hafs);
  • for words: verse_id, chapter_id, text_uthmani_tajweed, text_qpc_hafs, line_v1 and line_v2;
  • for translations: rub_el_hizb_number.

Checks run locally on current main (Node 26.8.1, pnpm 9.15.4)

  • pnpm test (vitest, build and package smoke test): 30 files, 357 tests passed.
  • pnpm lint --quiet, pnpm typecheck and pnpm build --filter=./packages/*: passed.
  • pnpm --filter @quranjs/api size: unchanged.
  • Prettier on the changed files: no changes needed.

The field selection unions were missing names that the API's field
reference documents, so typed calls could not request them without a
cast. `wordFields: { textIndopakNastaleeq: true }`, which the spec gives
as the way to get IndoPak Nastaleeq word text, failed with TS2353. The
response types did not declare what those fields return either.

`TranslationField` also offered `rubNumber`, which is sent as
`rub_number`. The API does not know that field and returns the number
as `rub_el_hizb_number`, so `Translation.rubNumber` was never set.

- add the missing `VerseField`, `WordField` and `TranslationField` names
- declare the matching optional properties on `Verse`, `Word` and
  `Translation`
- keep `rubNumber` for compatibility, noted as unknown to the API, and
  deprecate `Translation.rubNumber` in favor of `rubElHizbNumber`

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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