From d7c866b9d84eb627443541f7ca6c4a1257434568 Mon Sep 17 00:00:00 2001 From: memdmp Date: Wed, 18 Feb 2026 04:03:01 +0100 Subject: feat: we now use rsstrogen from npm --- src/lib/vendor/rss/rss.ts | 231 ---------------------------------------------- 1 file changed, 231 deletions(-) delete mode 100644 src/lib/vendor/rss/rss.ts (limited to 'src/lib/vendor/rss/rss.ts') diff --git a/src/lib/vendor/rss/rss.ts b/src/lib/vendor/rss/rss.ts deleted file mode 100644 index f44a6d2..0000000 --- a/src/lib/vendor/rss/rss.ts +++ /dev/null @@ -1,231 +0,0 @@ -import { XMLElement, XMLRootElement, XMLTagType, XMLText } from './xml'; - -class XMLElementWithRSSUtil extends XMLElement { - protected replaceChildByTagName(tag: string) { - const existingEl = this.findElementChild(v => v.tagName === tag); - if (existingEl) { - existingEl.children.length = 0; - existingEl.attributes.clear(); - } - const el = existingEl ?? new XMLElement(tag); - if (!existingEl) - this.child(el) - return el - } -} -export class RSSItemElement extends XMLElementWithRSSUtil { - public constructor(title: string | null, description: string | null, link: string | URL | null) { - super("item"); - if (title !== null) - this.title(title); - if (description !== null) - this.description(description) - if (link !== null) - this.link(link) - } - /** Replaces the title of the item */ - public title(title: string) { - this.replaceChildByTagName('title').child(new XMLText(title)) - return this; - } - /** Replaces the link to the item */ - public link(link: string | URL) { - this.replaceChildByTagName('link').child(new XMLText(typeof link === 'string' ? link : link.href)) - return this; - } - /** Sets the description of the item, replacing it if it already exists */ - public description(description: string) { - this.replaceChildByTagName('description').child(new XMLText(description)) - return this; - } - /** Sets the URL for the comment section of an item, replacing it if it already exists */ - public comments(comments: string | URL) { - return this.child(new XMLElement('comments').child(new XMLText(typeof comments === 'string' ? comments : comments.href))); - } - /** Sets the timestamp where the most recent item in the channel was published, replacing it if it already exists */ - public pubDate(pubDate: Date) { - this.replaceChildByTagName('pubDate').child(new XMLText(pubDate.toUTCString())) - return this; - } - /** Specifies a third-party source for the item. */ - public source(sourceName: string, sourceUrl: string | URL) { - return this.child(new XMLElement('source').attribute('url', typeof sourceUrl === 'string' ? sourceUrl : sourceUrl.href).child(new XMLText(sourceName))) - } - /** Adds a category to the post */ - public category( - category: string, - ) { - return this.child(new XMLElement('category').child(new XMLText(category))); - } - /** Adds a author to the post */ - public author( - author: string, - ) { - return this.child(new XMLElement('author').child(new XMLText(author))); - } - /** Adds a unique ID to the post. This ID must be globally unique, but has no format specifications. */ - public guid( - id: string, - /** If this is a permanent link to the post. If true, this must be a URL that permanently points to this item. */ - isPermaLink: boolean - ) { - return this.child(new XMLElement('guid').child(new XMLText(id)).attribute('isPermaLink', isPermaLink ? 'true' : 'false')); - } - /** Adds a media file to be included with an item */ - public enclosure( - url: string, - mimeType: string, - /** in bytes */ - length: number - ) { - return this.child( - new XMLElement('enclosure') - .attribute('url', url) - .attribute('length', length.toString()) - .attribute('type', mimeType) - ) - } -} -export class RSSChannelElement extends XMLElementWithRSSUtil { - public constructor(title: string | null, description: string | null, link: URL | string | null) { - super("channel"); - if (title !== null) - this.title(title); - if (description !== null) - this.description(description) - if (link !== null) - this.link(link) - } - /** Replaces the title of the channel */ - public title(title: string) { - this.replaceChildByTagName('title').child(new XMLText(title)) - return this; - } - /** Replaces the link to the channel */ - public link(link: string | URL) { - this.replaceChildByTagName('link').child(new XMLText(typeof link === 'string' ? link : link.href)) - return this; - } - /** Sets the description of the channel, replacing it if it already exists */ - public description(description: string) { - this.replaceChildByTagName('description').child(new XMLText(description)) - return this; - } - /** Sets the timestamp where the most recent item in the channel was published, replacing it if it already exists */ - public pubDate(pubDate: Date) { - this.replaceChildByTagName('pubDate').child(new XMLText(pubDate.toUTCString())) - return this; - } - /** Sets the timestamp where the RSS file was last modified in any way, replacing it if it already exists */ - public lastBuildDate(lastBuildDate: Date) { - this.replaceChildByTagName('lastBuildDate').child(new XMLText(lastBuildDate.toUTCString())) - return this; - } - /** Sets the time to live for the channel - the maximum time until clients should re-fetch it, replacing it if it already exists */ - public ttl(ttl: number) { - this.replaceChildByTagName('ttl').child(new XMLText(ttl.toString())) - return this; - } - /** Adds the copyright information of the channel */ - public copyright(copyright: string) { - return this.child(new XMLElement('copyright').child(new XMLText(copyright))) - } - /** Adds the generator used for this RSS feed - we recommend calling this and keeping it at .rsstrogen() - Can be called multiple times */ - public generator(generator: string = 'rsstrogen') { - return this.child(new XMLElement('generator').child(new XMLText(generator))); - } - /** Adds the webmaster managing this feed's email address */ - public webmaster(webmaster: string) { - return this.child(new XMLElement('webMaster').child(new XMLText(webmaster))) - } - /** Adds the managing editor managing this feed's email address */ - public managingEditor(managingEditor: string) { - return this.child(new XMLElement('managingEditor').child(new XMLText(managingEditor))) - } - /** - * Adds a URL of an image to be displayed when aggregators present a feed - * - * **Note:** The image must be of type GIF, JPEG or PNG. - */ - public image(image: { - /** Defines the hyperlink to the website that offers the channel */ - link: string; - /** Defines the text to display if the image could not be shown and/or for screen readers */ - alt: string; - /** Specifies the URL to the image */ - url: URL | string; - /** Specifies the text in the HTML title attribute of the link around the image. Defaults to the value of alt */ - description?: string | null; - /** The resolution of the image. Per Spec: Default is 88x31, Max is 144x400. */ - resolution?: [width: number, height: number] - }) { - const img = new XMLElement('image').child( - new XMLElement('link').child(new XMLText(image.link)), - new XMLElement('title').child(new XMLText(image.alt)), - new XMLElement('url').child(new XMLText(typeof image.url === 'string' ? image.url : image.url.href)), - ); - if (image.description !== null) - img.child( - new XMLElement('description').child(new XMLText(image.description ?? image.alt)), - ); - if (image.resolution) - img.child( - new XMLElement('width').child(new XMLText(image.resolution[0].toString())), - new XMLElement('height').child(new XMLText(image.resolution[1].toString())), - ); - return this.child(img); - } - /** Sets (or specifies an additional) language for the feed */ - public language(language: RSSLanguageCode) { - return this.child(new XMLElement('language').child(new XMLText(language))); - } - /** Specifies a search engine/text input should be specified with the feed */ - public search(engine: { - /** @default "Search" */ - title?: string, - /** @example "Search Neobot Systems" */ - description: string, - /** @example "https://search.example.com/search?" */ - link: string, - /** @example "query" */ - param: string, - }) { - this.replaceChildByTagName('textInput').child( - new XMLElement('title').child(new XMLText(engine.title ?? 'Search')), - new XMLElement('description').child(new XMLText(engine.description)), - new XMLElement('link').child(new XMLText(engine.link)), - new XMLElement('name').child(new XMLText(engine.param)), - ); - return this; - } - /** Adds a category to the feed */ - public category( - category: string, - /** Optional - A string or URL that identifies a categorization taxonomy. */ - domain?: string - ) { - const cat = new XMLElement('category'); - if (domain !== undefined) cat.attribute('domain', domain) - this.child(cat.child(new XMLText(category))) - return this; - } - // TODO: add more tags - /** Adds items to the RSS feed */ - public items(...items: RSSItemElement[]) { - return this.child(...items); - } -} -export class RSSRootElement extends XMLRootElement { - public constructor() { - super("rss") - this - .attribute("version", "2.0") - .xmlns("content", "http://purl.org/rss/1.0/modules/content/") - } - public channel(...channels: RSSChannelElement[]) { - return this.child(...channels) - } -} - -/** @link https://www.rssboard.org/rss-language-codes */ -export type RSSLanguageCode = 'af' | 'sq' | 'eu' | 'be' | 'bg' | 'ca' | 'zh-cn' | 'zh-tw' | 'hr' | 'cs' | 'da' | 'nl' | 'nl-be' | 'nl-nl' | 'en' | 'en-au' | 'en-bz' | 'en-ca' | 'en-ie' | 'en-jm' | 'en-nz' | 'en-ph' | 'en-za' | 'en-tt' | 'en-gb' | 'en-us' | 'en-zw' | ' et' | 'fo' | 'fi' | 'fr' | 'fr-be' | 'fr-ca' | 'fr-fr' | 'fr-lu' | 'fr-mc' | 'fr-ch' | 'gl' | 'gd' | 'de' | 'de-at' | 'de-de' | 'de-li' | 'de-lu' | 'de-ch' | 'el' | 'haw' | 'hu' | 'is' | 'in' | 'ga' | 'it' | 'it-it' | 'it-ch' | 'ja' | 'ko' | 'mk' | 'no' | 'pl' | 'pt' | 'pt-br' | 'pt-pt' | 'ro' | 'ro-mo' | 'ro-ro' | 'ru' | 'ru-mo' | 'ru-ru' | 'sr' | 'sk' | 'sl' | 'es' | 'es-ar' | 'es-bo' | 'es-cl' | 'es-co' | 'es-cr' | 'es-do' | 'es-ec' | 'es-sv' | 'es-gt' | 'es-hn' | 'es-mx' | 'es-ni' | 'es-pa' | 'es-py' | 'es-pe' | 'es-pr' | 'es-es' | 'es-uy' | 'es-ve' | 'sv' | 'sv-fi' | 'sv-se' | 'tr' | 'uk' -- cgit v1.2.3