2026-01-13 14:49:19 +01:00

94 lines
3.4 KiB
TypeScript

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<ExtractedReview | null> {
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<typeof extractTagsFromEvent>
metadata: Record<string, unknown> | null
}): Promise<ExtractedReview | null> {
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<typeof extractTagsFromEvent> }): Promise<ExtractedReview | null> {
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<typeof extractTagsFromEvent>
metadata: Record<string, unknown>
}): { 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<ExtractedReview> {
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 } : {}) }
}