Skip to content

feat: add optional Hardcover book metadata provider - #294

Open
TyceHerrman wants to merge 3 commits into
mProjectsCode:masterfrom
TyceHerrman:feat/hardcover-api
Open

TyceHerrman wants to merge 3 commits into
mProjectsCode:masterfrom
TyceHerrman:feat/hardcover-api

Conversation

@TyceHerrman

@TyceHerrman TyceHerrman commented Oct 14, 2026 •

Copy link
Copy Markdown

Adds Hardcover as an optional book provider, addressing #272. Users connect in their browser with authorization-code OAuth and S256 PKCE, then search by title or import by numeric book ID through the existing Media DB workflow.

OAuth requests only read:catalog. The callback validates state, issuer, client identity, expiration, and one-time use. Access and rotating refresh credentials are stored in Obsidian SecretStorage, with concurrent refreshes coordinated. Canceling sign-in or editing the client ID preserves completed token rotations; older refreshes cannot overwrite a newly authorized connection. Disconnect waits for an active refresh, revokes its current credentials, and then clears the connection. No manual token or client secret is used.

Imports include title, authors, publication year, description, genres, cover, average rating, pages, and ISBNs. Edition fields use the default physical edition, falling back to the default ebook edition. Searches are capped at 20 results and preserve ranking; requests are spaced to respect the per-minute quota. Hardcover is disabled by default.

Validation:

  • Tracked-file formatting, bun run typecheck, bun run lint, and bun run test passed: all 61 tests (14 provider tests and 16 OAuth tests). Seven OAuth regression tests cover cancellation and new sign-in during refresh, client edits, replacement connections, disconnect during refresh or authorization, and retrying failed revocation with rotated credentials.
  • bun run build passed.
  • git diff --cached --check passed before commit.
  • Regression coverage uses delayed mocked token exchanges; the new race scenarios have not been re-tested against the live service.

Live validation (Obsidian, 2026-10-15; isolated vault, source commit 8046b5a):

  • The account owner completed browser OAuth consent/return manually; the plugin connection was confirmed through the Obsidian CLI. Browser automation could not follow the custom-scheme navigation.
  • Live title search and numeric-ID lookup succeeded for The Left Hand of Darkness (Hardcover ID 377842). The preview was confirmed and the normal note-writing pipeline created Media DB/books/The Left Hand of Darkness (1969).md.
  • Saved catalog fields matched the live response, including author, year, description, genres, pages, rating, ISBNs, and source ID.
  • Refreshing note metadata preserved reading status, personal rating, last-read date, and body text.
  • Forcing local access-token expiry exercised a real refresh-token exchange: both credentials rotated and the stored expiry was restored. Concurrent token requests succeeded; settings contained neither token.
  • Reloading the plugin preserved the connection. A Wizard of Earthsea (ID 427401) imported with a local cover that decoded at 333 × 500 pixels.
  • Disconnect successfully called revocation, cleared SecretStorage credentials, and blocked further lookups. Invalid callbacks and unauthenticated lookups were rejected. No runtime errors were captured.

All test notes/settings were confined to the isolated vault. No live OAuth credentials remain in that vault.

Deployment: the OAuth public client ID is configurable for development. A production registration should be owned by the project maintainer; the contributor's test client ID is not included in source. Register obsidian://media-db-hardcover, allow only read:catalog, and leave Device Authorization Grant disabled.

AI assistance: implementation, tests, and this description were prepared with AI. results and pr reviewed and edited by me.

Closes #272

@TyceHerrman
TyceHerrman marked this pull request as ready for review October 15, 2026 22:51
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.

Hardcover API (or alternative APIs for books)

1 participant