Skip to content

feat(core): add image search pagination and curated VOTD images - #470

Open
camrun91 wants to merge 5 commits into
mainfrom
feat/ype-6425-image-search
Open

camrun91 wants to merge 5 commits into
mainfrom
feat/ype-6425-image-search

Conversation

@camrun91

@camrun91 camrun91 commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Why

Resolve YPE-6425 so JavaScript and React consumers can page image search and resolve the curated Verse of the Day image. Extend the existing core clients with optional inputs that preserve current callers.

What changed

  • Add SearchClient.searchImages and searchImages with validated pages, opaque IDs and continuation tokens, including empty pages with continuation.
  • Add optional VOTD language ranges on the canonical hyphenated routes and normalize missing or null image IDs to null.
  • Add public exports, MSW client workflows, README examples and minor changesets.

Scope

  • Core API support, plus the UI package's export and route fixture.
  • No new hooks or UI behavior. Developer Hub examples must adopt the new API after the SDK release.

Blast Radius

VOTD requests move from the underscore routes to the stable hyphenated routes and now reject malformed response bodies. Existing call arguments remain valid. Core methods return VOTDResponse with guaranteed image_id: string | null. Existing VOTD values and hook overrides can still omit the field; VOTDInput aliases that compatible shape. Search retains 200 empty envelopes and does not reuse the image listing's 204 handling.

Verification

  • pnpm test, pnpm typecheck and pnpm lint pass after rebasing onto current main. The suite passes 1,089 tests across core, hooks and UI.
  • Independent verification found no blocking defects. Focused MSW workflows, package builds, packed ESM/CommonJS imports, export parity, and compiled/executed README examples pass.
  • Storybook VOTD browser journeys could not be verified. They fail alongside an unrelated control story; VOTD unit tests pass.

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; the previous compatibility issue is fixed and no new blocking issues were found.

Summary

Adds paginated image search and curated Verse of the Day image support.

  • Search results include verse-art images that callers can page through.
  • Verse of the Day reads can filter by language and return curated image IDs.

Reviews (4) · Last reviewed commit: "fix(core): preserve legacy VOTD value co..." · Reviewed by Greptile

Add searchImages for GET /v1/search-images. Callers keep the same query, version id, and pageSize, and pass nextPageToken back as pageToken. An empty page can still include a token. HTTP 204 is an error.

Verse-of-the-day reads use GET /v1/verse-of-the-days. language_ranges sends repeated language_ranges[] values. image_id is null when the API omits it or sends null.

Re-export searchImages from the UI package so the public export check stays aligned.

Signed-off-by: camrun01 <cameron.b.llewellyn@gmail.com>
@changeset-bot

changeset-bot Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cf7b6fb

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@youversion/platform-react-ui Minor
@youversion/platform-core Minor
vite-react Patch
@youversion/platform-react-hooks Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Comment thread packages/core/src/schemas/votd.ts Resolved

@bmanquen bmanquen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed against the PR description and the YPE-6425 scope. Two blocking items below (the public VOTD type and the changeset), plus one non-blocking cleanup.

Comment thread packages/core/src/schemas/votd.ts Resolved
Comment thread .changeset/search-images-votd.md Resolved
Comment thread packages/core/src/bible-reads.ts Resolved

@bmanquen bmanquen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Requesting changes for the two issue (blocking) comments in my previous review (#470 (review)):

  1. packages/core/src/schemas/votd.ts: the public VOTD return type should guarantee image_id: string | null.
  2. .changeset/search-images-votd.md: note that VOTD reads now validate responses and can throw, and that the route changed from verse_of_the_days to verse-of-the-days.

The bible-reads.ts duplication comment is non-blocking.

Comment thread packages/core/src/schemas/votd.ts Resolved
@camrun91
camrun91 requested a review from bmanquen November 4, 2026 15:01

export type VOTD = Readonly<z.infer<typeof VOTDSchema>>;
export type VOTD = Readonly<z.input<typeof VOTDSchema>>;
export type VOTDInput = VOTD;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

issue (blocking): VOTDInput adds permanent public API with no consumer

VOTDInput is an exact alias of VOTD and nothing in the monorepo uses it. It is re-exported from types/index.ts, so once this ships as a minor, removing it becomes a breaking change. VOTD already is the input-compatible shape (z.input<typeof VOTDSchema>), and VOTDResponse covers the normalized output, so the alias doesn't distinguish anything.

Please drop the alias, its re-export in packages/core/src/types/index.ts, and the sentence about it in .changeset/search-images-votd.md. If a separate input name is wanted later, it can be added without breaking anyone.


const response = await client.get<unknown>('/v1/search-images', params);
const parsed = SearchImagesWireSchema.safeParse(response);
if (!parsed.success) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

suggestion (non-blocking): Make the HTTP 204 failure identifiable

The contract says "HTTP 204 is an error", but right now it only throws as a side effect: ApiClient.get returns '' for a 204, the schema rejects it, and the caller gets the same generic Unexpected search-images API response: … as a malformed body, with no status attached. Callers can't distinguish "the API returned no content" from "the API returned garbage", and getHttpStatus returns undefined for both.

Consider checking for the empty-body case before parsing and throwing a specific message (e.g. search-images returned no content (HTTP 204)), mirroring how images.ts explicitly handles the 204 case rather than relying on schema failure. The existing 204 test could then assert on that message.

* Fetches the verse of the day calendar for an entire year.
* @returns A collection of VOTD objects for all days of the year.
* @param options Optional `language_ranges`. When omitted, the request sends no language query.
* When set, the request repeats `language_ranges[]` in that order.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nitpick (non-blocking): JSDoc implies ranges are sent as given

"the request repeats language_ranges[] in that order" reads as values pass through verbatim, but parseLanguageRanges trims, lowercases, and converts _ to - (' EN ' → en, en_US → en-us), and rejects anything outside the Basic Language Range grammar. Worth saying so here (and on getVOTD + the README VOTD paragraph) so callers aren't surprised by validation errors or by what shows up in request logs.

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.

2 participants