diff --git a/index.ts b/index.ts index b531571..ddab118 100644 --- a/index.ts +++ b/index.ts @@ -20,6 +20,8 @@ type LibraryThingBook = { genre: string[], summary: string, language: string[], + originalisbn: string, + asin: string } type LibraryThingExport = Record @@ -52,6 +54,8 @@ type BookImport = { genre?: { id: number }[], // id of the genre already stored in DB summary?: string, authors?: { id: number }[], // id of the author already stored in DB + isbn?: string, + asin?: string, } type BookRecord = BookImport & { @@ -59,6 +63,13 @@ type BookRecord = BookImport & { genre: GenreRecord[] } +type CopyRecord = { + id: number, + condition: number, + book: { id: number }, + repository: { id: number }, +} + const getAuthToken = async () => { const creds = { @@ -124,7 +135,7 @@ const importAuthors = async (authors: AuthorMap, authToken: string) => { return await axios.post( - `${process.env.BASE_URL}/api/authors`, + `${process.env.BASE_URL}/apallBooksInDbi/authors`, a, { headers, withCredentials: true } ).then(saveResponse => { const savedAuthor = saveResponse?.data?.doc as AuthorRecord || null @@ -195,7 +206,9 @@ const parseBooks = (libraryThingData: LibraryThingExport, genreRecords: GenreRec publication: curr.publication, summary: curr.summary, genre: [] as { id: number }[], - authors: [] as { id: number }[] + authors: [] as { id: number }[], + isbn: curr.originalisbn, + asin: curr.asin, } const formatedPages = parseInt(curr.pages?.trim() || '', 10) @@ -223,38 +236,101 @@ const parseBooks = (libraryThingData: LibraryThingExport, genreRecords: GenreRec return books } -const importBooks = async (books: BookImport[], authToken: string) => { +const importBooks = async (books: BookImport[], authToken: string, options?: { updateFields: (keyof BookRecord)[] }) => { const headers = { 'Authorization': authToken, 'Content-Type': 'application/json', } + const shouldUpdate = !!options?.updateFields?.length + const allBooksInDb = await axios.get(`${process.env.BASE_URL}/api/books?limit=10000`, { headers }) const alreadyAddedBooks = (allBooksInDb?.data?.docs || []) as BookRecord[] - books.forEach(async b => { - const foundExistingBook = alreadyAddedBooks.find(added => added.books_id === b.books_id) - if (foundExistingBook) return - const importBookResponse = await axios.post(`${process.env.BASE_URL}/api/books`, b, { headers }) + for (let i = 0; i < books.length; i++) { + const foundExistingBook = alreadyAddedBooks.find(added => added.books_id === books[i].books_id) + if (foundExistingBook && shouldUpdate) { + + let newBookProps: Partial = {} + options.updateFields.forEach(key => { + (newBookProps as any)[key as keyof BookRecord] = (books[i] as any)[key] // This is stupid, why cant TS just knoe that keyof is valid for square brakets? + }); + + console.log('Updating book: ', foundExistingBook.id, newBookProps) + const updateBookResponse = await axios.patch(`${process.env.BASE_URL}/api/books/${foundExistingBook.id}`, newBookProps, { headers }) + const updatededBook = updateBookResponse?.data?.doc || null + console.log('Updated book: ', updatededBook) + continue + } else if (foundExistingBook && !shouldUpdate) continue + + const importBookResponse = await axios.post(`${process.env.BASE_URL}/api/books`, books[i], { headers }) const importedBook = importBookResponse?.data?.doc || null console.log('Added book: ', importedBook) - }); - + } } +const copyAllExistingDbBooksIntoRepo = async (repoId: number, authToken: string) => { + const headers = { + 'Authorization': authToken, + 'Content-Type': 'application/json', + } + + const allBooksInDbResponse = await axios.get(`${process.env.BASE_URL}/api/books?limit=10000`, { headers }) + const allBooksInDb = (allBooksInDbResponse?.data?.docs || []) as BookRecord[] + + const allCopiesInDb = await axios.get(`${process.env.BASE_URL}/api/copies?limit=10000`, { headers }) + const alreadyAddedCopies = (allCopiesInDb?.data?.docs || []) as CopyRecord[] + + for (let i = 0; i < allBooksInDb.length; i++) { + const foundExistingCopy = alreadyAddedCopies.find(c => { + return c.book.id === allBooksInDb[i].id + }) + if (foundExistingCopy) continue + + const copyProps: Partial = { + book: { id: allBooksInDb[i].id }, + repository: { id: repoId }, + } + const createCopyResponse = await axios.post(`${process.env.BASE_URL}/api/copies`, copyProps, { headers }) + const importedCopy = createCopyResponse?.data?.doc || null + console.log('Added copy: ', importedCopy.id) + } +} + + const main = async () => { + console.log("Reading LIbray Thing JSON") const libraryThingData = JSON.parse(readFileSync('./libraryThingExport.json', 'utf8')) as LibraryThingExport + + console.log("Logging in...") const authToken = await getAuthToken() + + console.log("Parsing Authors...") const authors = parseAuthors(libraryThingData) + console.log("Importing Authors...") const authorRecords = await importAuthors(authors, authToken) + console.log(`Parsed ${authorRecords.length} Authors`) + console.log("Parsing Genres...") const genres = parseGenre(libraryThingData) + console.log("Importing Genres...") const genreRecords = await importGenres(genres, authToken) + console.log(`Parsed ${genreRecords.length} Genres`) + console.log("Parsing Books...") const books = parseBooks(libraryThingData, genreRecords, authorRecords) - importBooks(books, authToken) + console.log("Importing Books...") + await importBooks(books, authToken) + //importBooks(books, authToken, { + // updateFields: ['asin', 'isbn'] + //}) + console.log("Imported/Updated books") + + console.log("Copying Books into Repo...") + await copyAllExistingDbBooksIntoRepo(1, authToken) + console.log("Copied Books") } main()