( book: Book, values: BookMetadataFormValues, )
| 214 | } |
| 215 | |
| 216 | export function buildBookMetadataUpdate( |
| 217 | book: Book, |
| 218 | values: BookMetadataFormValues, |
| 219 | ): { meta: BookMeta; tags: string[]; groupId?: string } { |
| 220 | const title = values.title.trim() || book.meta.title || "Untitled"; |
| 221 | const author = values.author.trim(); |
| 222 | const publisher = values.publisher.trim(); |
| 223 | const language = values.language.trim(); |
| 224 | const isbn = values.isbn.trim(); |
| 225 | const publishDate = values.publishDate.trim(); |
| 226 | const description = values.description.trim(); |
| 227 | const subjects = splitEditableList(values.subjectsText); |
| 228 | const rating = normalizeRating(values.rating); |
| 229 | const originalReviews = new Map((book.meta.reviews || []).map((review) => [review.id, review])); |
| 230 | const reviews = values.reviews |
| 231 | .map((review) => { |
| 232 | const content = review.content.trim(); |
| 233 | if (!content) return null; |
| 234 | const original = originalReviews.get(review.id); |
| 235 | const createdAt = review.createdAt || original?.createdAt || Date.now(); |
| 236 | const updatedAt = |
| 237 | original && original.content.trim() === content ? original.updatedAt : Date.now(); |
| 238 | return { |
| 239 | id: review.id || generateId(), |
| 240 | content, |
| 241 | createdAt, |
| 242 | updatedAt, |
| 243 | }; |
| 244 | }) |
| 245 | .filter((review): review is BookReview => Boolean(review)); |
| 246 | |
| 247 | return { |
| 248 | meta: { |
| 249 | ...book.meta, |
| 250 | title, |
| 251 | author, |
| 252 | coverUrl: values.coverUrl.trim(), |
| 253 | publisher: publisher || undefined, |
| 254 | language: language || undefined, |
| 255 | isbn: isbn || undefined, |
| 256 | publishDate: publishDate || undefined, |
| 257 | rating, |
| 258 | description: description || undefined, |
| 259 | reviews: reviews.length > 0 ? reviews : undefined, |
| 260 | subjects: subjects.length > 0 ? subjects : undefined, |
| 261 | }, |
| 262 | tags: splitEditableList(values.tagsText), |
| 263 | groupId: values.groupId || undefined, |
| 264 | }; |
| 265 | } |
no test coverage detected