import type { Event } from 'nostr-tools' import { extractTagsFromEvent } from '../nostrTagSystem' import { generatePublicationHashId } from '../hashIdGenerator' import type { ExtractedPublication } from './types' import { getMetadataFromEvent } from './metadataJson' import { firstNumber, firstString } from './utils' type PublicationPages = Array<{ number: number; type: 'markdown' | 'image'; content: string }> export async function extractPublicationFromEvent(event: Event): Promise { const tags = extractTagsFromEvent(event) if (tags.type !== 'publication') { return null } const metadata = getMetadataFromEvent(event) if (metadata?.type === 'publication') { const publicationData = buildPublicationDataFromMetadata({ event, tags, metadata }) const id = await generatePublicationHashId(publicationData) const pages = readPublicationPages(metadata) return buildExtractedPublication({ eventId: event.id, id, data: publicationData, pages }) } if (!tags.title) { return null } const publicationData = { pubkey: event.pubkey, title: tags.title, preview: (tags.preview as string) ?? event.content.substring(0, 200), category: tags.category ?? 'sciencefiction', zapAmount: tags.zapAmount ?? 800, ...(tags.seriesId ? { seriesId: tags.seriesId } : {}), ...(tags.bannerUrl ? { bannerUrl: tags.bannerUrl } : {}), } const id = await generatePublicationHashId(publicationData) return buildExtractedPublication({ eventId: event.id, id, data: publicationData, pages: undefined }) } function buildPublicationDataFromMetadata(params: { event: Event tags: ReturnType metadata: Record }): { pubkey: string title: string preview: string category: string seriesId?: string bannerUrl?: string zapAmount: number } { const base: { pubkey: string title: string preview: string category: string seriesId?: string bannerUrl?: string zapAmount: number } = { pubkey: firstString(params.metadata.pubkey, params.event.pubkey) ?? params.event.pubkey, title: firstString(params.metadata.title, params.tags.title) ?? '', preview: firstString(params.metadata.preview, params.tags.preview) ?? params.event.content.substring(0, 200), category: firstString(params.metadata.category, params.tags.category, 'sciencefiction') ?? 'sciencefiction', zapAmount: firstNumber(params.metadata.zapAmount, params.tags.zapAmount) ?? 800, } const seriesId = firstString(params.metadata.seriesId, params.tags.seriesId) if (seriesId) { base.seriesId = seriesId } const bannerUrl = firstString(params.metadata.bannerUrl, params.tags.bannerUrl) if (bannerUrl) { base.bannerUrl = bannerUrl } return base } function readPublicationPages(metadata: Record): PublicationPages | undefined { const pages = metadata.pages as PublicationPages | undefined return pages && Array.isArray(pages) && pages.length > 0 ? pages : undefined } function buildExtractedPublication(params: { eventId: string id: string data: { pubkey: string title: string preview: string category: string seriesId?: string bannerUrl?: string zapAmount: number } pages: PublicationPages | undefined }): ExtractedPublication { return { type: 'publication', id: params.id, pubkey: params.data.pubkey, title: params.data.title, preview: params.data.preview, category: params.data.category, zapAmount: params.data.zapAmount, eventId: params.eventId, ...(params.data.seriesId ? { seriesId: params.data.seriesId } : {}), ...(params.data.bannerUrl ? { bannerUrl: params.data.bannerUrl } : {}), ...(params.pages ? { pages: params.pages } : {}), } }