211 lines
5.7 KiB
TypeScript
211 lines
5.7 KiB
TypeScript
import {now, uniq, displayList, formatTimestampAsDate, formatTimestampRelative} from "@welshman/lib"
|
|
import {
|
|
FeedType,
|
|
Feed,
|
|
AddressFeed,
|
|
AuthorFeed,
|
|
CreatedAtFeed,
|
|
DVMFeed,
|
|
DifferenceFeed,
|
|
IDFeed,
|
|
IntersectionFeed,
|
|
GlobalFeed,
|
|
KindFeed,
|
|
ListFeed,
|
|
LabelFeed,
|
|
WOTFeed,
|
|
RelayFeed,
|
|
ScopeFeed,
|
|
SearchFeed,
|
|
TagFeed,
|
|
UnionFeed,
|
|
} from "./core.js"
|
|
import {getFeedArgs} from "./utils.js"
|
|
|
|
export const displayAddressFeed = (feed: AddressFeed) => {
|
|
const n = getFeedArgs(feed).length
|
|
|
|
return `${n} replaceable {n === 1 ? 'event' : 'events'}`
|
|
}
|
|
|
|
export const displayAuthorFeed = (feed: AuthorFeed) => {
|
|
const n = getFeedArgs(feed).length
|
|
|
|
return `from ${n} replaceable {n === 1 ? 'person' : 'people'}`
|
|
}
|
|
|
|
export const displayCreatedAtFeed = (feed: CreatedAtFeed) => {
|
|
const items = getFeedArgs(feed)
|
|
const descriptions: string[] = []
|
|
|
|
for (const {since, until, relative = []} of items) {
|
|
const parts: string[] = []
|
|
|
|
if (since) {
|
|
if (relative.includes("since")) {
|
|
parts.push(`after ${formatTimestampRelative(now() - since)}`)
|
|
} else {
|
|
parts.push(`after ${formatTimestampAsDate(since)}`)
|
|
}
|
|
}
|
|
|
|
if (until) {
|
|
if (relative.includes("until")) {
|
|
parts.push(`before ${formatTimestampRelative(now() - until)}`)
|
|
} else {
|
|
parts.push(`before ${formatTimestampAsDate(until)}`)
|
|
}
|
|
}
|
|
|
|
if (parts.length > 0) {
|
|
descriptions.push(parts.join(" and "))
|
|
}
|
|
}
|
|
|
|
if (descriptions.length === 0) {
|
|
return "from any time"
|
|
}
|
|
|
|
return displayList(descriptions, "or")
|
|
}
|
|
|
|
export const displayDVMFeed = (feed: DVMFeed) => {
|
|
const items = getFeedArgs(feed)
|
|
const descriptions: string[] = []
|
|
|
|
for (const {kind, tags = [], relays = []} of items) {
|
|
const parts: string[] = []
|
|
|
|
parts.push(`kind ${kind}`)
|
|
|
|
if (tags.length > 0) {
|
|
parts.push(`with ${tags.length} tag${tags.length === 1 ? "" : "s"}`)
|
|
}
|
|
|
|
if (relays.length > 0) {
|
|
parts.push(`from ${displayList(relays)}`)
|
|
}
|
|
|
|
descriptions.push(parts.join(" "))
|
|
}
|
|
|
|
return `from DVM requests of ${displayList(descriptions)}`
|
|
}
|
|
|
|
export const displayDifferenceFeed = (feed: DifferenceFeed) => {
|
|
const [base, ...excluded] = getFeedArgs(feed)
|
|
|
|
return `${displayFeed(base)}, excluding ${displayList(excluded.map(displayFeed))}`
|
|
}
|
|
|
|
export const displayIDFeed = (feed: IDFeed) => `matching ${getFeedArgs(feed).length} IDs`
|
|
|
|
export const displayIntersectionFeed = (feed: IntersectionFeed) =>
|
|
displayList(getFeedArgs(feed).map(displayFeed))
|
|
|
|
export const displayGlobalFeed = (feed: GlobalFeed) => "anything"
|
|
|
|
export const displayKindFeed = (feed: KindFeed) => `of kind ${displayList(getFeedArgs(feed))}`
|
|
|
|
export const displayListFeed = (feed: ListFeed) => {
|
|
const addresses = uniq(getFeedArgs(feed).flatMap(({addresses}) => addresses))
|
|
|
|
return `from ${addresses.length} list${addresses.length === 1 ? "" : "s"}`
|
|
}
|
|
|
|
export const displayLabelFeed = (feed: LabelFeed) => {
|
|
const items = getFeedArgs(feed)
|
|
const descriptions: string[] = []
|
|
|
|
for (const item of items) {
|
|
const parts: string[] = []
|
|
|
|
if (item.authors?.length) {
|
|
parts.push(`by ${item.authors.length} author${item.authors.length === 1 ? "" : "s"}`)
|
|
}
|
|
|
|
const tags = Object.entries(item)
|
|
.filter(([key]) => key.startsWith("#"))
|
|
.map(([key, values]) => `${key}=${displayList(values as string[])}`)
|
|
|
|
if (tags.length) {
|
|
parts.push(`with tags ${displayList(tags)}`)
|
|
}
|
|
|
|
if (item.relays?.length) {
|
|
parts.push(`from ${displayList(item.relays)}`)
|
|
}
|
|
|
|
descriptions.push(parts.join(" "))
|
|
}
|
|
|
|
return displayList(descriptions)
|
|
}
|
|
|
|
export const displayWOTFeed = (feed: WOTFeed) => {
|
|
const descriptions = getFeedArgs(feed).map(({min = 0, max = 1}) =>
|
|
min === max ? `WOT score of ${min}` : `WOT score between ${min} and ${max}`,
|
|
)
|
|
|
|
return `from authors with ${displayList(descriptions)}`
|
|
}
|
|
|
|
export const displayRelayFeed = (feed: RelayFeed) => `from ${displayList(getFeedArgs(feed))}`
|
|
|
|
export const displayScopeFeed = (feed: ScopeFeed) =>
|
|
`from ${displayList(getFeedArgs(feed).map(s => s.toLowerCase()))}`
|
|
|
|
export const displaySearchFeed = (feed: SearchFeed) =>
|
|
`matching ${displayList(getFeedArgs(feed).map(term => `"${term}"`))}`
|
|
|
|
export const displayTagFeed = (feed: TagFeed) => {
|
|
const [key, ...values] = getFeedArgs(feed)
|
|
|
|
return `with ${key} tag matching ${displayList(values, "or")}`
|
|
}
|
|
|
|
export const displayUnionFeed = (feed: UnionFeed) => displayList(getFeedArgs(feed).map(displayFeed))
|
|
|
|
export const displayFeed = (feed: Feed): string => {
|
|
switch (feed[0]) {
|
|
case FeedType.Address:
|
|
return displayAddressFeed(feed)
|
|
case FeedType.Author:
|
|
return displayAuthorFeed(feed)
|
|
case FeedType.CreatedAt:
|
|
return displayCreatedAtFeed(feed)
|
|
case FeedType.DVM:
|
|
return displayDVMFeed(feed)
|
|
case FeedType.Difference:
|
|
return displayDifferenceFeed(feed)
|
|
case FeedType.ID:
|
|
return displayIDFeed(feed)
|
|
case FeedType.Intersection:
|
|
return displayIntersectionFeed(feed)
|
|
case FeedType.Global:
|
|
return displayGlobalFeed(feed)
|
|
case FeedType.Kind:
|
|
return displayKindFeed(feed)
|
|
case FeedType.List:
|
|
return displayListFeed(feed)
|
|
case FeedType.Label:
|
|
return displayLabelFeed(feed)
|
|
case FeedType.WOT:
|
|
return displayWOTFeed(feed)
|
|
case FeedType.Relay:
|
|
return displayRelayFeed(feed)
|
|
case FeedType.Scope:
|
|
return displayScopeFeed(feed)
|
|
case FeedType.Search:
|
|
return displaySearchFeed(feed)
|
|
case FeedType.Tag:
|
|
return displayTagFeed(feed)
|
|
case FeedType.Union:
|
|
return displayUnionFeed(feed)
|
|
default:
|
|
return "[unknown feed type]"
|
|
}
|
|
}
|
|
|
|
export const displayFeeds = (feeds: Feed[]) => displayList(feeds.map(displayFeed))
|