diff --git a/src/index.d.ts b/src/index.d.ts index d3939ea..39fbcf6 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -7,7 +7,7 @@ * @property {number} pageCount - The number of pages in the book. * @property {string} printType - The print type of the book. Always "BOOK" for this context. * @property {string[]} categories - The subjects or categories of the book. - * @property {string} thumbnail - The thumbnail image link of the book. + * @property {string | undefined} [thumbnail] - The thumbnail image link of the book. * @property {string} [link] - The link of the book. */ /** @@ -73,7 +73,7 @@ export type Book = { /** * - The thumbnail image link of the book. */ - thumbnail: string; + thumbnail?: string | undefined; /** * - The link of the book. */ diff --git a/src/index.js b/src/index.js index f0d6ef7..8456f41 100644 --- a/src/index.js +++ b/src/index.js @@ -13,7 +13,7 @@ import { * @property {number} pageCount - The number of pages in the book. * @property {string} printType - The print type of the book. Always "BOOK" for this context. * @property {string[]} categories - The subjects or categories of the book. - * @property {string} thumbnail - The thumbnail image link of the book. + * @property {string | undefined} [thumbnail] - The thumbnail image link of the book. * @property {string} [link] - The link of the book. */ diff --git a/src/providers/google.js b/src/providers/google.js index 1beff43..8544331 100644 --- a/src/providers/google.js +++ b/src/providers/google.js @@ -38,12 +38,22 @@ export async function resolveGoogle(isbn, options) { throw new Error(`No volume info found for book with isbn: ${isbn}`); } const book = books.items[0]; - return standardize(book.volumeInfo, book.id, isbn); + return standardize(book.volumeInfo, isbn); } catch (error) { throw new Error(error.message); } } +/** + * @typedef {object} ImageLinks + * @property {string} [extraLarge] - extraLarge + * @property {string} [large] - large + * @property {string} [medium] - medium + * @property {string} [small] - small + * @property {string} [thumbnail] - thumbnail + * @property {string} [smallThumbnail] - smallThumbnail + */ + /** * @typedef {object} GoogleBook * @property {string} title - The title of the book. @@ -63,7 +73,7 @@ export async function resolveGoogle(isbn, options) { * @property {boolean} allowAnonLogging - The allow anon logging of the book. * @property {string} contentVersion - The content version of the book. * @property {object} panelizationSummary - The panelization summary of the book. - * @property {object} imageLinks - The image links of the book. + * @property {ImageLinks} [imageLinks] - The image links of the book. * @property {string} language - The language of the book. * @property {string} previewLink - The preview link of the book. * @property {string} infoLink - The info link of the book. @@ -76,11 +86,10 @@ export async function resolveGoogle(isbn, options) { /** * Standardizes a book object by extracting relevant information from the provided book object. * @param {GoogleBook} book - The book object to be standardized. - * @param {string} id - The book's id. * @param {string} isbn - The book's ISBN. - * @returns {Book} - The standardized book object. + * @returns {Book} The standardized book object. */ -export function standardize(book, id, isbn) { +export function standardize(book, isbn) { const standardBook = { title: book.title, authors: book.authors, @@ -88,10 +97,35 @@ export function standardize(book, id, isbn) { pageCount: book.pageCount, printType: book.printType, categories: book.categories, - thumbnail: `https://books.google.com/books?id=${id}&printsec=frontcover&img=1&zoom=6&edge=curl&source=gbs_api`, + thumbnail: getLargestThumbnail(book.imageLinks), link: book.canonicalVolumeLink, isbn, }; return standardBook; } + +/** + * Get the largest available thumbnail from a book's image links. + * @param {ImageLinks} [imageLinks] - The image links object. + * @returns {string|undefined} The URL of the largest thumbnail, or undefined if not found. + */ +function getLargestThumbnail(imageLinks) { + const sizes = [ + "extraLarge", + "large", + "medium", + "small", + "thumbnail", + "smallThumbnail", + ]; + + if (!imageLinks) return; + + for (const size of sizes) { + if (size in imageLinks) { + // @ts-ignore + return imageLinks[size]; + } + } +} diff --git a/test/end-to-end.test.js b/test/end-to-end.test.js index be3a873..78ed781 100644 --- a/test/end-to-end.test.js +++ b/test/end-to-end.test.js @@ -24,7 +24,7 @@ describe("End to end", () => { "link": "https://books.google.com/books/about/Annihilation.html?hl=&id=2cl7AgAAQBAJ", "pageCount": 209, "printType": "BOOK", - "thumbnail": "https://books.google.com/books?id=2cl7AgAAQBAJ&printsec=frontcover&img=1&zoom=6&edge=curl&source=gbs_api", + "thumbnail": "http://books.google.com/books/content?id=2cl7AgAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api", "title": "Annihilation", } `); @@ -107,7 +107,7 @@ describe("End to end", () => { "link": "https://books.google.com/books/about/Annihilation.html?hl=&id=2cl7AgAAQBAJ", "pageCount": 209, "printType": "BOOK", - "thumbnail": "https://books.google.com/books?id=2cl7AgAAQBAJ&printsec=frontcover&img=1&zoom=6&edge=curl&source=gbs_api", + "thumbnail": "http://books.google.com/books/content?id=2cl7AgAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api", "title": "Annihilation", } `); diff --git a/test/index.test.js b/test/index.test.js index 919db53..0ccbaf5 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -48,7 +48,7 @@ describe("ISBN Resolver API", () => { "link": "https://books.google.com/books/about/Annihilation.html?hl=&id=2cl7AgAAQBAJ", "pageCount": 209, "printType": "BOOK", - "thumbnail": "https://books.google.com/books?id=2cl7AgAAQBAJ&printsec=frontcover&img=1&zoom=6&edge=curl&source=gbs_api", + "thumbnail": "http://books.google.com/books/content?id=2cl7AgAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api", "title": "Annihilation", } `); @@ -236,7 +236,7 @@ describe("ISBN Resolver API", () => { "link": "https://books.google.com/books/about/Annihilation.html?hl=&id=2cl7AgAAQBAJ", "pageCount": 209, "printType": "BOOK", - "thumbnail": "https://books.google.com/books?id=2cl7AgAAQBAJ&printsec=frontcover&img=1&zoom=6&edge=curl&source=gbs_api", + "thumbnail": "http://books.google.com/books/content?id=2cl7AgAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api", "title": "Annihilation", } `); @@ -268,7 +268,7 @@ describe("ISBN Resolver API", () => { "link": "https://books.google.com/books/about/Annihilation.html?hl=&id=2cl7AgAAQBAJ", "pageCount": 209, "printType": "BOOK", - "thumbnail": "https://books.google.com/books?id=2cl7AgAAQBAJ&printsec=frontcover&img=1&zoom=6&edge=curl&source=gbs_api", + "thumbnail": "http://books.google.com/books/content?id=2cl7AgAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api", "title": "Annihilation", } `); diff --git a/test/providers/google.test.js b/test/providers/google.test.js index bc534d8..0d1dada 100644 --- a/test/providers/google.test.js +++ b/test/providers/google.test.js @@ -28,20 +28,20 @@ describe("resolveGoogle", () => { const book = await resolveGoogle(isbn, {}); expect(book).toMatchInlineSnapshot(` -{ - "authors": [ - "Test Author", - ], - "categories": undefined, - "description": undefined, - "isbn": "1234567890", - "link": undefined, - "pageCount": undefined, - "printType": undefined, - "thumbnail": "https://books.google.com/books?id=11223344000&printsec=frontcover&img=1&zoom=6&edge=curl&source=gbs_api", - "title": "Test Book", -} -`); + { + "authors": [ + "Test Author", + ], + "categories": undefined, + "description": undefined, + "isbn": "1234567890", + "link": undefined, + "pageCount": undefined, + "printType": undefined, + "thumbnail": undefined, + "title": "Test Book", + } + `); }); it("should throw an error if no books are found", async () => { @@ -55,7 +55,7 @@ describe("resolveGoogle", () => { }); await expect(resolveGoogle(isbn, {})).rejects.toThrow( - `No books found with isbn: ${isbn}`, + `No books found with isbn: ${isbn}` ); }); @@ -71,7 +71,7 @@ describe("resolveGoogle", () => { }); await expect(resolveGoogle(isbn, {})).rejects.toThrow( - `Wrong response code: 404`, + `Wrong response code: 404` ); }); @@ -87,7 +87,7 @@ describe("resolveGoogle", () => { }); await expect(resolveGoogle(isbn, {})).rejects.toThrow( - `No volume info found for book with isbn: ${isbn}`, + `No volume info found for book with isbn: ${isbn}` ); }); }); diff --git a/tsconfig.json b/tsconfig.json index 115ef6b..4e1b0e4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,6 +12,6 @@ "target": "es2022", "useUnknownInCatchVariables": false }, - "include": ["src/*.js"], - "exclude": ["src/*.d.ts"] + "include": ["src/**/*.js"], + "exclude": ["**/*.d.ts"] }