You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

123 lines
3.1 KiB

import type { NDKTag } from '@nostr-dev-kit/ndk'
import { last } from 'ramda'
export const TOPIC = 'topic'
export const LINK = 'link'
export const LINKCOLLECTION = 'link[]'
export const HTML = 'html'
export const INVOICE = 'invoice'
export const NOSTR_NOTE = 'nostr:note'
export const NOSTR_NEVENT = 'nostr:nevent'
export const NOSTR_NPUB = 'nostr:npub'
export const NOSTR_NPROFILE = 'nostr:nprofile'
export const NOSTR_NADDR = 'nostr:naddr'
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const first = (list: any) => (list ? list[0] : undefined)
export const fromNostrURI = (s: string) => s.replace(/^[\w+]+:\/?\/?/, '')
export const urlIsMedia = (url: string) =>
!url.match(/\.(apk|docx|xlsx|csv|dmg)/) &&
last(url.split('://'))?.includes('/')
export type ContentArgs = {
content: string
tags?: Array<NDKTag>
}
export type ParsedPart = ParsedNewLine | ParsedText
export const NEWLINE = 'newline'
export type ParsedNewLine = {
type: 'newline'
value: string
}
export const isParsedNewLine = (part: ParsedPart): part is ParsedNewLine => {
return part.type == 'newline'
}
export const TEXT = 'text'
export type ParsedText = {
type: 'text'
value: string
}
export const isParsedText = (part: ParsedPart): part is ParsedText => {
return part.type == 'text'
}
export const parseContent = ({ content }: ContentArgs): ParsedPart[] => {
const result: ParsedPart[] = []
let text = content.trim()
let buffer = ''
const parseNewline = () => {
const newline = first(text.match(/^\n+/))
if (newline) {
return [NEWLINE, newline, newline]
}
}
while (text) {
// The order that this runs matters
const part = parseNewline()
if (part) {
if (buffer) {
result.push({ type: 'text', value: buffer })
buffer = ''
}
const [type, raw, value] = part
result.push({ type, value })
text = text.slice(raw.length)
} else {
// Instead of going character by character and re-running all the above regular expressions
// a million times, try to match the next word and add it to the buffer
const match = first(text.match(/^[\w\d]+ ?/i)) || text[0]
buffer += match
text = text.slice(match.length)
}
}
if (buffer) {
result.push({ type: TEXT, value: buffer })
}
return result
}
/** this doesn't work for all patch formats and options */
export const extractPatchMessage = (s: string): string | undefined => {
try {
const t = s.split('\nSubject: [')[1].split('] ')[1]
if (t.split('\n\n---\n ').length > 1) return t.split('\n\n---\n ')[0]
return t.split('\n\ndiff --git ')[0].split('\n\n ').slice(0, -1).join('')
} catch {
return undefined
}
}
/** this doesn't work for all patch formats and options */
export const extractPatchTitle = (s: string): string | undefined => {
const msg = extractPatchMessage(s)
if (!msg) return undefined
return s.split('\n')[0]
}
export const extractIssueTitle = (s: string): string => {
return s.split('\n')[0] || ''
}
export const extractIssueDescription = (s: string): string => {
const split = s.split('\n')
if (split.length === 0) return ''
return s.substring(split[0].length) || ''
}