import type { Event } from 'nostr-tools' import { extractTagsFromEvent } from '../nostrTagSystem' import { generateReviewHashId } from '../hashIdGenerator' import type { ExtractedReview } from './types' import { getMetadataFromEvent } from './metadataJson' import { firstString } from './utils' export async function extractReviewFromEvent(event: Event): Promise { const tags = extractTagsFromEvent(event) if (tags.type !== 'quote') { return null } const metadata = getMetadataFromEvent(event) const fromMetadata = await extractReviewFromMetadata({ event, tags, metadata }) if (fromMetadata) { return fromMetadata } return extractReviewFromTags({ event, tags }) } async function extractReviewFromMetadata(params: { event: Event tags: ReturnType metadata: Record | null }): Promise { if (params.metadata?.type !== 'review') { return null } const reviewData = buildReviewDataFromMetadata({ event: params.event, tags: params.tags, metadata: params.metadata }) if (!reviewData) { return null } const id = await generateReviewHashId(reviewData) return { type: 'review', id, ...reviewData, eventId: params.event.id } } async function extractReviewFromTags(params: { event: Event; tags: ReturnType }): Promise { if (!params.tags.articleId || !params.tags.reviewerPubkey) { return null } const base = { pubkey: params.event.pubkey, articleId: params.tags.articleId, reviewerPubkey: params.tags.reviewerPubkey, content: params.event.content, ...(params.tags.title ? { title: params.tags.title } : {}), eventId: params.event.id, } return buildExtractedReviewFromTags(base) } function buildReviewDataFromMetadata(params: { event: Event tags: ReturnType metadata: Record }): { pubkey: string; articleId: string; reviewerPubkey: string; content: string; title?: string } | null { const articleId = firstString(params.metadata.articleId, params.tags.articleId) ?? '' const reviewerPubkey = firstString(params.metadata.reviewerPubkey, params.tags.reviewerPubkey, params.event.pubkey) ?? params.event.pubkey if (!articleId || !reviewerPubkey) { return null } const title = firstString(params.metadata.title, params.tags.title) const base: { pubkey: string; articleId: string; reviewerPubkey: string; content: string; title?: string } = { pubkey: firstString(params.metadata.pubkey, params.event.pubkey) ?? params.event.pubkey, articleId, reviewerPubkey, content: firstString(params.metadata.content, params.event.content) ?? params.event.content, } if (title) { base.title = title } return base } async function buildExtractedReviewFromTags(params: { pubkey: string articleId: string reviewerPubkey: string content: string title?: string eventId: string }): Promise { const id = await generateReviewHashId({ pubkey: params.pubkey, articleId: params.articleId, reviewerPubkey: params.reviewerPubkey, content: params.content, ...(params.title ? { title: params.title } : {}), }) return { type: 'review', id, pubkey: params.pubkey, articleId: params.articleId, reviewerPubkey: params.reviewerPubkey, content: params.content, eventId: params.eventId, ...(params.title ? { title: params.title } : {}) } }