@jukasdrj/bookstrack-api-client
v1.0.1
Published
TypeScript SDK for BooksTrack API - Auto-generated from OpenAPI specification
Maintainers
Readme
@bookstrack/api-client
Official TypeScript SDK for BooksTrack API
Auto-generated from OpenAPI specification using openapi-typescript + openapi-fetch.
Features
- Type-Safe - Full TypeScript support with auto-generated types
- Lightweight - ~2KB gzipped client (tree-shakable)
- Modern - Uses native
fetchAPI (works in browser, Node.js, Cloudflare Workers) - Auto-Generated - Always in sync with API contract via OpenAPI spec
Installation
npm install @bookstrack/api-clientNote: This package is published to GitHub Packages. Ensure your .npmrc is configured:
@bookstrack:registry=https://npm.pkg.github.comQuick Start
Basic Usage
import { createBooksTrackClient } from '@bookstrack/api-client'
const client = createBooksTrackClient({
baseUrl: 'https://api.oooefam.net'
})
// Search by ISBN
const { data, error } = await client.GET('/v1/search/isbn', {
params: { query: { isbn: '9780439708180' } }
})
if (error) {
console.error('API Error:', error)
} else {
console.log('Book:', data.data)
}Advanced Usage
Custom Headers (Authentication)
const client = createBooksTrackClient({
baseUrl: 'https://api.oooefam.net',
headers: {
'Authorization': 'Bearer YOUR_TOKEN'
}
})POST Requests (Batch Enrichment)
const { data, error } = await client.POST('/v1/enrich/batch', {
body: {
workIds: ['OL123W', 'OL456W'],
force: false
}
})
if (error) {
console.error('Failed to enrich:', error)
} else {
console.log('Job ID:', data.data.jobId)
}WebSocket Progress Tracking
// Start batch job
const { data: job } = await client.POST('/v1/enrich/batch', {
body: { workIds: [...] }
})
const jobId = job.data.jobId
// Connect to WebSocket
const ws = new WebSocket(`wss://api.oooefam.net/ws/progress?jobId=${jobId}`)
ws.onmessage = (event) => {
const progress = JSON.parse(event.data)
console.log(`Progress: ${progress.progress * 100}%`)
}Polling Job Status (Fallback)
const { data } = await client.GET('/v1/jobs/{jobId}/status', {
params: { path: { jobId: 'job-uuid' } }
})
console.log('Job Status:', data.data.status)
console.log('Progress:', data.data.progress)API Reference
Client Creation
createBooksTrackClient(options?: {
baseUrl?: string
headers?: HeadersInit
credentials?: RequestCredentials
})Available Endpoints
All endpoints are fully typed. Use TypeScript autocomplete to explore:
GET /health- Health checkGET /v1/search/isbn- Search by ISBNGET /v1/search/title- Search by titlePOST /v1/enrich/batch- Batch enrichmentPOST /v2/import/workflow- CSV import workflowGET /v1/jobs/{jobId}/status- Job status pollingGET /ws/progress- WebSocket progress (upgrade)
Response Format
All API responses follow the canonical ResponseEnvelope format:
Success:
{
success: true,
data: { /* canonical book object */ },
metadata: {
source: 'google_books',
cached: true,
timestamp: '2025-01-10T12:00:00Z'
}
}Error:
{
success: false,
error: {
code: 'RATE_LIMIT_EXCEEDED',
message: 'Too many requests',
statusCode: 429,
retryable: true,
retryAfterMs: 60000
}
}Error Handling
Circuit Breaker Errors
The API uses circuit breakers for external providers. Handle these gracefully:
const { data, error } = await client.GET('/v1/search/isbn', {
params: { query: { isbn: '...' } }
})
if (error) {
if (error.code === 'CIRCUIT_OPEN') {
// Provider is temporarily unavailable
console.warn('Provider down, try again in 60s')
} else if (error.retryable) {
// Safe to retry after retryAfterMs
setTimeout(() => retry(), error.retryAfterMs)
}
}Common Error Codes
MISSING_ISBN- Required parameter missingRATE_LIMIT_EXCEEDED- Too many requestsCIRCUIT_OPEN- External provider circuit breaker openNOT_FOUND- Book not foundAPI_ERROR- External API failureINTERNAL_ERROR- Server error
Development
Generating Types
The SDK is auto-generated from docs/openapi.yaml:
npm run generateThis creates src/schema.ts with all API types.
Building
npm run buildOutput: dist/index.js and dist/index.d.ts
Publishing (Automated via CI/CD)
Publishing is handled automatically by GitHub Actions when:
- Pushing to
mainbranch - Creating a new release/tag
Manual publish:
npm run prepublishOnly
npm publishFramework Examples
React (with React Query)
import { useQuery } from '@tanstack/react-query'
import { client } from '@bookstrack/api-client'
function BookSearch({ isbn }: { isbn: string }) {
const { data, error, isLoading } = useQuery({
queryKey: ['book', isbn],
queryFn: async () => {
const res = await client.GET('/v1/search/isbn', {
params: { query: { isbn } }
})
if (res.error) throw new Error(res.error.message)
return res.data.data
}
})
if (isLoading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
return <div>{data?.title}</div>
}Vue 3 (with Composition API)
import { ref } from 'vue'
import { client } from '@bookstrack/api-client'
export function useBookSearch(isbn: string) {
const book = ref(null)
const error = ref(null)
const loading = ref(false)
async function search() {
loading.value = true
const res = await client.GET('/v1/search/isbn', {
params: { query: { isbn } }
})
if (res.error) {
error.value = res.error
} else {
book.value = res.data.data
}
loading.value = false
}
return { book, error, loading, search }
}Svelte
import { writable } from 'svelte/store'
import { client } from '@bookstrack/api-client'
export function createBookStore() {
const { subscribe, set, update } = writable({
book: null,
loading: false,
error: null
})
async function searchByISBN(isbn: string) {
update(s => ({ ...s, loading: true }))
const { data, error } = await client.GET('/v1/search/isbn', {
params: { query: { isbn } }
})
if (error) {
set({ book: null, loading: false, error })
} else {
set({ book: data.data, loading: false, error: null })
}
}
return { subscribe, searchByISBN }
}Migration from Legacy API
If you're migrating from the old /search/* endpoints (deprecated March 1, 2026):
Before (Legacy)
const res = await fetch('https://api.oooefam.net/search/isbn?isbn=123')
const book = await res.json()After (SDK)
import { client } from '@bookstrack/api-client'
const { data } = await client.GET('/v1/search/isbn', {
params: { query: { isbn: '123' } }
})
const book = data.dataKey Changes:
- All responses now use
ResponseEnvelopeformat - Success/error discriminator via
successfield - Metadata includes source, cache status, timestamp
- Error responses include structured error codes
Support
- Documentation: https://github.com/yourusername/bendv3/tree/main/docs
- API Contract: https://github.com/yourusername/bendv3/blob/main/docs/API_CONTRACT.md
- Issues: https://github.com/yourusername/bendv3/issues
License
MIT
Generated from OpenAPI Spec Version: (auto-updated on publish) Last Updated: 2025-11-28
