110 lines
3.7 KiB
TypeScript
110 lines
3.7 KiB
TypeScript
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<ExtractedPublication | null> {
|
|
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<typeof extractTagsFromEvent>
|
|
metadata: Record<string, unknown>
|
|
}): {
|
|
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<string, unknown>): 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 } : {}),
|
|
}
|
|
}
|