open-library-client
Version:
A modern TypeScript API wrapper for the OpenLibrary REST API
273 lines • 9.42 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenLibraryClient = void 0;
const axios_1 = __importDefault(require("axios"));
/**
* Main client for interacting with the OpenLibrary API
*/
class OpenLibraryClient {
/**
* Create a new OpenLibrary client instance
* @param config - Configuration options for the client
*/
constructor(config = {}) {
this.config = {
baseURL: config.baseURL || 'https://openlibrary.org',
timeout: config.timeout || 10000,
headers: config.headers || {},
};
this.httpClient = axios_1.default.create({
baseURL: this.config.baseURL,
timeout: this.config.timeout,
headers: {
'Content-Type': 'application/json',
'User-Agent': 'open-library-client/1.0.0',
...this.config.headers,
},
});
this.setupInterceptors();
}
/**
* Setup request and response interceptors
*/
setupInterceptors() {
this.httpClient.interceptors.request.use((config) => {
return config;
}, (error) => {
return Promise.reject(this.handleError(error));
});
this.httpClient.interceptors.response.use((response) => {
return response;
}, (error) => {
return Promise.reject(this.handleError(error));
});
}
/**
* Handle and format API errors
*/
handleError(error) {
if (error.response) {
return {
error: error.response.data?.error || 'API Error',
message: error.response.data?.message || error.message,
status: error.response.status,
};
}
else if (error.request) {
return {
error: 'Network Error',
message: 'No response received from server',
};
}
else {
return {
error: 'Request Error',
message: error.message,
};
}
}
/**
* Search for books using the OpenLibrary search API
* @param params - Search parameters
* @returns Promise resolving to search results
*
* @example
* ```typescript
* const client = new OpenLibraryClient();
* const results = await client.searchBooks({
* q: 'The Lord of the Rings',
* author: 'Tolkien',
* limit: 5
* });
* ```
*/
async searchBooks(params) {
try {
const queryParams = new URLSearchParams();
if (params.title)
queryParams.append('title', params.title);
if (params.author)
queryParams.append('author', params.author);
if (params.isbn)
queryParams.append('isbn', params.isbn);
if (params.subject)
queryParams.append('subject', params.subject);
if (params.lang)
queryParams.append('lang', params.lang);
if (params.fields)
queryParams.append('fields', params.fields);
let queryString = params.q;
if (params.first_publish_year) {
if (typeof params.first_publish_year === 'number') {
queryString += ` first_publish_year:${params.first_publish_year}`;
}
else {
queryString += ` first_publish_year:[${params.first_publish_year.start} TO ${params.first_publish_year.end}]`;
}
}
if (params.publish_year) {
if (typeof params.publish_year === 'number') {
queryString += ` publish_year:${params.publish_year}`;
}
else {
queryString += ` publish_year:[${params.publish_year.start} TO ${params.publish_year.end}]`;
}
}
queryParams.set('q', queryString);
if (params.sort) {
queryParams.append('sort', params.sort);
}
queryParams.append('limit', String(params.limit || 10));
queryParams.append('offset', String(params.offset || 0));
queryParams.append('format', 'json');
const response = await this.httpClient.get(`/search.json?${queryParams.toString()}`);
return {
data: response.data,
status: response.status,
statusText: response.statusText,
};
}
catch (error) {
throw error;
}
}
/**
* Get detailed information about a specific work
* @param workKey - The OpenLibrary work key (e.g., "OL45804W")
* @returns Promise resolving to work details
*
* @example
* ```typescript
* const client = new OpenLibraryClient();
* const work = await client.getWork("OL45804W");
* console.log(work.data.title);
* ```
*/
async getWork(workKey) {
try {
// Remove '/works/' prefix if provided and ensure it starts with 'OL'
const cleanKey = workKey.replace('/works/', '').replace(/^\//, '');
if (!cleanKey.startsWith('OL')) {
throw new Error('Work key must start with "OL" (e.g., "OL45804W")');
}
const response = await this.httpClient.get(`/works/${cleanKey}.json`);
return {
data: response.data,
status: response.status,
statusText: response.statusText,
};
}
catch (error) {
throw error;
}
}
/**
* Get detailed information about a specific edition
* @param editionKey - The OpenLibrary edition key (e.g., "OL7353617M")
* @returns Promise resolving to edition details
*
* @example
* ```typescript
* const client = new OpenLibraryClient();
* const edition = await client.getEdition("OL7353617M");
* console.log(edition.data.title);
* ```
*/
async getEdition(editionKey) {
try {
// Remove '/books/' prefix if provided and ensure it starts with 'OL'
const cleanKey = editionKey.replace('/books/', '').replace(/^\//, '');
if (!cleanKey.startsWith('OL')) {
throw new Error('Edition key must start with "OL" (e.g., "OL7353617M")');
}
const response = await this.httpClient.get(`/books/${cleanKey}.json`);
return {
data: response.data,
status: response.status,
statusText: response.statusText,
};
}
catch (error) {
throw error;
}
}
/**
* Get book information by ISBN
* @param isbn - The ISBN (10 or 13 digits)
* @returns Promise resolving to book details
*
* @example
* ```typescript
* const client = new OpenLibraryClient();
* const book = await client.getBookByISBN("9780140328721");
* console.log(book.data.title);
* ```
*/
async getBookByISBN(isbn) {
try {
const cleanISBN = isbn.replace(/[-\s]/g, '');
if (!/^\d{10}$/.test(cleanISBN) && !/^\d{13}$/.test(cleanISBN)) {
throw new Error('ISBN must be 10 or 13 digits');
}
const response = await this.httpClient.get(`/isbn/${cleanISBN}.json`);
return {
data: response.data,
status: response.status,
statusText: response.statusText,
};
}
catch (error) {
throw error;
}
}
/**
* Generate cover image URL from cover ID
* @param coverId - The cover ID number
* @param size - Size of the cover image ('S', 'M', or 'L')
* @returns Cover image URL
*
* @example
* ```typescript
* const client = new OpenLibraryClient();
* const coverUrl = client.getCoverUrl(8739161, 'M');
* console.log(coverUrl); // https://covers.openlibrary.org/b/id/8739161-M.jpg
* ```
*/
getCoverUrl(coverId, size = 'M') {
return `https://covers.openlibrary.org/b/id/${coverId}-${size}.jpg`;
}
/**
* Generate cover image URL from ISBN
* @param isbn - The ISBN (10 or 13 digits)
* @param size - Size of the cover image ('S', 'M', or 'L')
* @returns Cover image URL
*
* @example
* ```typescript
* const client = new OpenLibraryClient();
* const coverUrl = client.getCoverUrlByISBN('9780547928227', 'L');
* console.log(coverUrl); // https://covers.openlibrary.org/b/isbn/9780547928227-L.jpg
* ```
*/
getCoverUrlByISBN(isbn, size = 'M') {
const cleanISBN = isbn.replace(/[-\s]/g, '');
return `https://covers.openlibrary.org/b/isbn/${cleanISBN}-${size}.jpg`;
}
/**
* Get the current client configuration
*/
getConfig() {
return { ...this.config };
}
/**
* Get the base URL being used by the client
*/
getBaseURL() {
return this.config.baseURL;
}
}
exports.OpenLibraryClient = OpenLibraryClient;
//# sourceMappingURL=OpenLibraryClient.js.map