aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/vendor/rss/rss.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/vendor/rss/rss.ts')
-rw-r--r--src/lib/vendor/rss/rss.ts231
1 files changed, 0 insertions, 231 deletions
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'