feat: add wishlist
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
import { z } from 'zod'
|
||||
|
||||
const coverSchema = z.object({
|
||||
cover: z.string().regex(OPEN_LIBRARY_COVER, 'Not an Open Library cover')
|
||||
})
|
||||
|
||||
// Public: anyone can fill in a missing cover, but only with an Open Library cover URL.
|
||||
export default defineEventHandler(async (event) => {
|
||||
const id = Number(getRouterParam(event, 'id'))
|
||||
const body = coverSchema.safeParse(await readBody(event))
|
||||
if (!Number.isInteger(id) || !body.success) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Invalid cover' })
|
||||
}
|
||||
|
||||
const table = wishlistTable(event)
|
||||
const rows = await listRows<WishlistRow>(event, table)
|
||||
const row = rows.find(row => row.id === id)
|
||||
if (!row) throw createError({ statusCode: 404, statusMessage: 'No such book' })
|
||||
if (row.cover) return toWishlistBook(row)
|
||||
|
||||
return toWishlistBook(await updateRow<WishlistRow>(event, table, id, { cover: body.data.cover }))
|
||||
})
|
||||
@@ -0,0 +1,4 @@
|
||||
export default defineEventHandler(async (event) => {
|
||||
const rows = await listRows<WishlistRow>(event, wishlistTable(event))
|
||||
return rows.map(toWishlistBook).filter(book => book.title)
|
||||
})
|
||||
@@ -0,0 +1,41 @@
|
||||
import type { H3Event } from 'h3'
|
||||
|
||||
interface LinkValue {
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface WishlistRow {
|
||||
id: number
|
||||
isbn: string | null
|
||||
thalia: string | null
|
||||
cover?: string | null
|
||||
books: LinkValue[]
|
||||
authors: LinkValue[]
|
||||
title: LinkValue[]
|
||||
}
|
||||
|
||||
export function wishlistTable(event: H3Event): string {
|
||||
const { baserowWishlistTableId } = useRuntimeConfig(event)
|
||||
if (!baserowWishlistTableId) {
|
||||
throw createError({ statusCode: 500, statusMessage: 'NUXT_BASEROW_WISHLIST_TABLE_ID is not set' })
|
||||
}
|
||||
return baserowWishlistTableId
|
||||
}
|
||||
|
||||
export const OPEN_LIBRARY_COVER = /^https:\/\/covers\.openlibrary\.org\/b\/id\/\d+-M\.jpg$/
|
||||
|
||||
function values(links: LinkValue[] | null | undefined): string[] {
|
||||
return (links ?? []).map(link => link.value?.trim()).filter((value): value is string => !!value)
|
||||
}
|
||||
|
||||
export function toWishlistBook(row: WishlistRow): WishlistBook {
|
||||
const germanTitle = values(row.title).join(' / ')
|
||||
return {
|
||||
id: row.id,
|
||||
isbn: (row.isbn ?? '').trim(),
|
||||
thalia: row.thalia?.trim() || null,
|
||||
cover: row.cover?.trim() || null,
|
||||
title: germanTitle || values(row.books).join(' / '),
|
||||
authors: [...new Set(values(row.authors))]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user