UNPKG

feed

Version:

Feed is a RSS, Atom and JSON feed generator for Node.js, making content syndication simple and intuitive!

1 lines 29.5 kB
{"version":3,"file":"feed.js","names":["url: string | undefined","ins: Feed","base: any","category: string","contributor: Author","item: Item","entry: convert.ElementCompact","author: Author","category: Category","out: { name?: string; email?: string; uri?: string }","enclosure: string | Enclosure","ins: Feed","feed: any","e: Extension","item: Item","feedItem: any","author: Author | Author[]","category: Category","ins: Feed","base: any","entry: Item","item: any","author: Author","category: Category","extension: Extension","e: Extension","enclosure: string | Enclosure","duration: number","options: FeedOptions","item: Item","category: string","contributor: Author","extension: Extension"],"sources":["../src/config/index.ts","../src/utils.ts","../src/atom1.ts","../src/json.ts","../src/rss2.ts","../src/feed.ts"],"sourcesContent":["export const generator = \"https://github.com/jpmonette/feed\";\n","export function sanitize(url: string | undefined): string | undefined {\n if (typeof url === \"undefined\") {\n return;\n }\n return url.replace(/&/g, \"&\");\n}\n","import * as convert from \"xml-js\";\nimport { generator } from \"./config\";\nimport type { Feed } from \"./feed\";\nimport type { Author, Category, Enclosure, Item } from \"./typings\";\nimport { sanitize } from \"./utils\";\n\n/**\n * Returns an Atom feed\n * @param ins\n */\nexport default (ins: Feed) => {\n const { options } = ins;\n\n const base: any = {\n _declaration: { _attributes: { version: \"1.0\", encoding: \"utf-8\" } },\n feed: {\n _attributes: { xmlns: \"http://www.w3.org/2005/Atom\" },\n id: options.id,\n title: options.title,\n updated: options.updated ? options.updated.toISOString() : new Date().toISOString(),\n generator: sanitize(options.generator || generator),\n },\n };\n\n if (options.author) {\n base.feed.author = formatAuthor(options.author);\n }\n\n base.feed.link = [];\n\n // link (rel=\"alternate\")\n if (options.link) {\n base.feed.link.push({ _attributes: { rel: \"alternate\", href: sanitize(options.link) } });\n }\n\n // link (rel=\"self\")\n const atomLink = options.feed || (options.feedLinks && options.feedLinks.atom);\n\n if (atomLink) {\n base.feed.link.push({ _attributes: { rel: \"self\", href: sanitize(atomLink) } });\n }\n\n // link (rel=\"hub\")\n if (options.hub) {\n base.feed.link.push({ _attributes: { rel: \"hub\", href: sanitize(options.hub) } });\n }\n\n /**************************************************************************\n * \"feed\" node: optional elements\n *************************************************************************/\n\n if (options.description) {\n base.feed.subtitle = options.description;\n }\n\n if (options.image) {\n base.feed.logo = options.image;\n }\n\n if (options.favicon) {\n base.feed.icon = options.favicon;\n }\n\n if (options.copyright) {\n base.feed.rights = options.copyright;\n }\n\n base.feed.category = [];\n\n ins.categories.map((category: string) => {\n base.feed.category.push({ _attributes: { term: category } });\n });\n\n base.feed.contributor = [];\n\n ins.contributors.map((contributor: Author) => {\n base.feed.contributor.push(formatAuthor(contributor));\n });\n\n // icon\n\n base.feed.entry = [];\n\n /**************************************************************************\n * \"entry\" nodes\n *************************************************************************/\n ins.items.map((item: Item) => {\n //\n // entry: required elements\n //\n\n const entry: convert.ElementCompact = {\n title: { _attributes: { type: \"html\" }, _cdata: item.title },\n id: sanitize(item.id || item.link),\n link: [{ _attributes: { href: sanitize(item.link) } }],\n updated: item.date.toISOString(),\n };\n\n //\n // entry: recommended elements\n //\n if (item.description) {\n entry.summary = {\n _attributes: { type: \"html\" },\n _cdata: item.description,\n };\n }\n\n if (item.content) {\n entry.content = {\n _attributes: { type: \"html\" },\n _cdata: item.content,\n };\n }\n\n // entry author(s)\n if (Array.isArray(item.author)) {\n entry.author = [];\n\n item.author.map((author: Author) => {\n entry.author.push(formatAuthor(author));\n });\n }\n\n // content\n\n // link - relative link to article\n\n //\n // entry: optional elements\n //\n\n // category\n if (Array.isArray(item.category)) {\n entry.category = [];\n\n item.category.map((category: Category) => {\n entry.category.push(formatCategory(category));\n });\n }\n\n /**\n * Item Enclosure\n * https://validator.w3.org/feed/docs/atom.html#link\n */\n if (item.enclosure) {\n entry.link.push(formatEnclosure(item.enclosure));\n }\n\n if (item.image) {\n entry.link.push(formatEnclosure(item.image, \"image\"));\n }\n\n if (item.audio) {\n entry.link.push(formatEnclosure(item.audio, \"audio\"));\n }\n\n if (item.video) {\n entry.link.push(formatEnclosure(item.video, \"video\"));\n }\n\n // contributor\n if (item.contributor && Array.isArray(item.contributor)) {\n entry.contributor = [];\n\n item.contributor.map((contributor: Author) => {\n entry.contributor.push(formatAuthor(contributor));\n });\n }\n\n // published\n if (item.published) {\n entry.published = item.published.toISOString();\n }\n\n // source\n\n // rights\n if (item.copyright) {\n entry.rights = item.copyright;\n }\n\n base.feed.entry.push(entry);\n });\n\n return convert.js2xml(base, { compact: true, ignoreComment: true, spaces: 4 });\n};\n\n/**\n * Returns a formatted author\n * @param author\n */\nconst formatAuthor = (author: Author) => {\n const { name, email, link } = author;\n\n const out: { name?: string; email?: string; uri?: string } = { name };\n if (email) {\n out.email = email;\n }\n\n if (link) {\n out.uri = sanitize(link);\n }\n\n return out;\n};\n\n/**\n * Returns a formated enclosure\n * @param enclosure\n * @param mimeCategory\n */\nconst formatEnclosure = (enclosure: string | Enclosure, mimeCategory = \"image\") => {\n if (typeof enclosure === \"string\") {\n const type = new URL(enclosure).pathname.split(\".\").slice(-1)[0];\n return { _attributes: { rel: \"enclosure\", href: enclosure, type: `${mimeCategory}/${type}` } };\n }\n\n const type = new URL(enclosure.url).pathname.split(\".\").slice(-1)[0];\n return {\n _attributes: {\n rel: \"enclosure\",\n href: enclosure.url,\n title: enclosure.title,\n type: `${mimeCategory}/${type}`,\n length: enclosure.length,\n },\n };\n};\n\n/**\n * Returns a formatted category\n * @param category\n */\nconst formatCategory = (category: Category) => {\n const { name, scheme, term } = category;\n\n return {\n _attributes: {\n label: name,\n scheme,\n term,\n },\n };\n};\n","import type { Feed } from \"./feed\";\nimport type { Author, Category, Extension, Item } from \"./typings\";\n\n/**\n * Returns a JSON feed\n * @param ins\n */\nexport default (ins: Feed) => {\n const { options, items, extensions } = ins;\n\n const feed: any = {\n version: \"https://jsonfeed.org/version/1\",\n title: options.title,\n };\n\n if (options.link) {\n feed.home_page_url = options.link;\n }\n\n if (options.feedLinks && options.feedLinks.json) {\n feed.feed_url = options.feedLinks.json;\n }\n\n if (options.description) {\n feed.description = options.description;\n }\n\n if (options.image) {\n feed.icon = options.image;\n }\n\n if (options.author) {\n feed.author = {};\n if (options.author.name) {\n feed.author.name = options.author.name;\n }\n if (options.author.link) {\n feed.author.url = options.author.link;\n }\n if (options.author.avatar) {\n feed.author.avatar = options.author.avatar;\n }\n }\n\n extensions.map((e: Extension) => {\n feed[e.name] = e.objects;\n });\n\n feed.items = items.map((item: Item) => {\n const feedItem: any = {\n id: item.id,\n // json_feed distinguishes between html and text content\n // but since we only take a single type, we'll assume HTML\n content_html: item.content ?? item.description,\n };\n if (item.link) {\n feedItem.url = item.link;\n }\n if (item.title) {\n feedItem.title = item.title;\n }\n if (item.description && item.content) {\n feedItem.summary = item.description;\n }\n\n if (item.image) {\n feedItem.image = item.image;\n }\n\n if (item.date) {\n feedItem.date_modified = item.date.toISOString();\n }\n if (item.published) {\n feedItem.date_published = item.published.toISOString();\n }\n\n if (item.author) {\n let author: Author | Author[] = item.author;\n if (author instanceof Array) {\n // json feed only supports 1 author per post\n author = author[0];\n }\n feedItem.author = {};\n if (author.name) {\n feedItem.author.name = author.name;\n }\n if (author.link) {\n feedItem.author.url = author.link;\n }\n if (author.avatar) {\n feedItem.author.avatar = author.avatar;\n }\n }\n\n if (Array.isArray(item.category)) {\n feedItem.tags = [];\n item.category.map((category: Category) => {\n if (category.name) {\n feedItem.tags.push(category.name);\n }\n });\n }\n\n if (item.extensions) {\n item.extensions.map((e: Extension) => {\n feedItem[e.name] = e.objects;\n });\n }\n\n return feedItem;\n });\n\n return JSON.stringify(feed, null, 4);\n};\n","import * as convert from \"xml-js\";\nimport { generator } from \"./config\";\nimport type { Feed } from \"./feed\";\nimport type { Author, Category, Enclosure, Extension, Item } from \"./typings\";\nimport { sanitize } from \"./utils\";\n\n/**\n * Returns a RSS 2.0 feed\n */\nexport default (ins: Feed) => {\n const { options, extensions } = ins;\n let isAtom = false;\n let isContent = false;\n\n const base: any = {\n _declaration: { _attributes: { version: \"1.0\", encoding: \"utf-8\" } },\n rss: {\n _attributes: { version: \"2.0\" },\n channel: {\n title: { _text: options.title },\n link: { _text: sanitize(options.link) },\n description: { _text: options.description },\n lastBuildDate: { _text: options.updated ? options.updated.toUTCString() : new Date().toUTCString() },\n docs: { _text: options.docs ? options.docs : \"https://validator.w3.org/feed/docs/rss2.html\" },\n generator: { _text: options.generator || generator },\n },\n },\n };\n\n /**\n * Channel language\n * https://validator.w3.org/feed/docs/rss2.html#ltlanguagegtSubelementOfLtchannelgt\n */\n if (options.language) {\n base.rss.channel.language = { _text: options.language };\n }\n\n /**\n * Channel ttl\n * https://validator.w3.org/feed/docs/rss2.html#ltttlgtSubelementOfLtchannelgt\n */\n if (options.ttl) {\n base.rss.channel.ttl = { _text: options.ttl };\n }\n\n /**\n * Channel Image\n * https://validator.w3.org/feed/docs/rss2.html#ltimagegtSubelementOfLtchannelgt\n */\n if (options.image) {\n base.rss.channel.image = {\n title: { _text: options.title },\n url: { _text: options.image },\n link: { _text: sanitize(options.link) },\n };\n }\n\n /**\n * Channel Copyright\n * https://validator.w3.org/feed/docs/rss2.html#optionalChannelElements\n */\n if (options.copyright) {\n base.rss.channel.copyright = { _text: options.copyright };\n }\n\n /**\n * Channel Categories\n * https://validator.w3.org/feed/docs/rss2.html#comments\n */\n ins.categories.map((category) => {\n if (!base.rss.channel.category) {\n base.rss.channel.category = [];\n }\n base.rss.channel.category.push({ _text: category });\n });\n\n /**\n * Feed URL\n * http://validator.w3.org/feed/docs/warning/MissingAtomSelfLink.html\n */\n const atomLink = options.feed || (options.feedLinks && options.feedLinks.rss);\n if (atomLink) {\n isAtom = true;\n base.rss.channel[\"atom:link\"] = [\n {\n _attributes: {\n href: sanitize(atomLink),\n rel: \"self\",\n type: \"application/rss+xml\",\n },\n },\n ];\n }\n\n /**\n * Hub for PubSubHubbub\n * https://code.google.com/p/pubsubhubbub/\n */\n if (options.hub) {\n isAtom = true;\n if (!base.rss.channel[\"atom:link\"]) {\n base.rss.channel[\"atom:link\"] = [];\n }\n base.rss.channel[\"atom:link\"] = {\n _attributes: {\n href: sanitize(options.hub),\n rel: \"hub\",\n },\n };\n }\n\n /**\n * Channel Categories\n * https://validator.w3.org/feed/docs/rss2.html#hrelementsOfLtitemgt\n */\n base.rss.channel.item = [];\n\n ins.items.map((entry: Item) => {\n const item: any = {};\n\n if (entry.title) {\n item.title = { _cdata: entry.title };\n }\n\n if (entry.link) {\n item.link = { _text: sanitize(entry.link) };\n }\n\n if (entry.guid) {\n item.guid = { _text: entry.guid, _attributes: { isPermaLink: false } };\n } else if (entry.id) {\n item.guid = { _text: entry.id, _attributes: { isPermaLink: false } };\n } else if (entry.link) {\n item.guid = { _text: sanitize(entry.link), _attributes: { isPermaLink: true } };\n }\n\n if (entry.date) {\n item.pubDate = { _text: entry.date.toUTCString() };\n }\n\n if (entry.published) {\n item.pubDate = { _text: entry.published.toUTCString() };\n }\n\n if (entry.description) {\n item.description = { _cdata: entry.description };\n }\n\n if (entry.content) {\n isContent = true;\n item[\"content:encoded\"] = { _cdata: entry.content };\n }\n /**\n * Item Author\n * https://validator.w3.org/feed/docs/rss2.html#ltauthorgtSubelementOfLtitemgt\n */\n if (Array.isArray(entry.author)) {\n item.author = [];\n entry.author.map((author: Author) => {\n if (author.email && author.name) {\n item.author.push({ _text: author.email + \" (\" + author.name + \")\" });\n }\n });\n }\n /**\n * Item Category\n * https://validator.w3.org/feed/docs/rss2.html#ltcategorygtSubelementOfLtitemgt\n */\n if (Array.isArray(entry.category)) {\n item.category = [];\n entry.category.map((category: Category) => {\n item.category.push(formatCategory(category));\n });\n }\n\n /**\n * Item Enclosure\n * https://validator.w3.org/feed/docs/rss2.html#ltenclosuregtSubelementOfLtitemgt\n */\n if (entry.enclosure) {\n item.enclosure = formatEnclosure(entry.enclosure);\n }\n\n if (entry.image) {\n item.enclosure = formatEnclosure(entry.image, \"image\");\n }\n\n if (entry.audio) {\n let duration = undefined;\n if (options.podcast && typeof entry.audio !== \"string\" && entry.audio.duration) {\n duration = entry.audio.duration;\n entry.audio.duration = undefined;\n }\n item.enclosure = formatEnclosure(entry.audio, \"audio\");\n\n if (duration) {\n item[\"itunes:duration\"] = formatDuration(duration);\n }\n }\n\n if (entry.video) {\n item.enclosure = formatEnclosure(entry.video, \"video\");\n }\n\n if (entry.extensions) {\n entry.extensions.forEach((extension: Extension) => {\n item[extension.name] = extension.objects;\n });\n }\n\n base.rss.channel.item.push(item);\n });\n\n if (isContent) {\n base.rss._attributes[\"xmlns:dc\"] = \"http://purl.org/dc/elements/1.1/\";\n base.rss._attributes[\"xmlns:content\"] = \"http://purl.org/rss/1.0/modules/content/\";\n }\n\n // rss2() support `extensions`\n if (extensions)\n extensions.map((e: Extension) => {\n base.rss.channel[e.name] = e.objects;\n });\n\n if (isAtom) {\n base.rss._attributes[\"xmlns:atom\"] = \"http://www.w3.org/2005/Atom\";\n }\n\n /**\n * Podcast extensions\n * https://support.google.com/podcast-publishers/answer/9889544?hl=en\n */\n if (options.podcast) {\n base.rss._attributes[\"xmlns:googleplay\"] = \"http://www.google.com/schemas/play-podcasts/1.0\";\n base.rss._attributes[\"xmlns:itunes\"] = \"http://www.itunes.com/dtds/podcast-1.0.dtd\";\n if (options.category) {\n base.rss.channel[\"googleplay:category\"] = options.category;\n base.rss.channel[\"itunes:category\"] = options.category;\n }\n if (options.author?.email) {\n base.rss.channel[\"googleplay:owner\"] = options.author.email;\n base.rss.channel[\"itunes:owner\"] = {\n \"itunes:email\": options.author.email,\n };\n }\n if (options.author?.name) {\n base.rss.channel[\"googleplay:author\"] = options.author.name;\n base.rss.channel[\"itunes:author\"] = options.author.name;\n }\n if (options.image) {\n base.rss.channel[\"googleplay:image\"] = {\n _attributes: { href: sanitize(options.image) },\n };\n }\n }\n\n return convert.js2xml(base, { compact: true, ignoreComment: true, spaces: 4 });\n};\n\n/**\n * Returns a formated enclosure\n * @param enclosure\n * @param mimeCategory\n */\nconst formatEnclosure = (enclosure: string | Enclosure, mimeCategory = \"image\") => {\n if (typeof enclosure === \"string\") {\n const type = new URL(sanitize(enclosure)!).pathname.split(\".\").slice(-1)[0];\n return { _attributes: { url: enclosure, length: 0, type: `${mimeCategory}/${type}` } };\n }\n\n const type = new URL(sanitize(enclosure.url)!).pathname.split(\".\").slice(-1)[0];\n return { _attributes: { length: 0, type: `${mimeCategory}/${type}`, ...enclosure } };\n};\n\n/**\n * Returns a formated category\n * @param category\n */\nconst formatCategory = (category: Category) => {\n const { name, domain } = category;\n return {\n _text: name,\n _attributes: {\n domain,\n },\n };\n};\n\n/**\n * Returns a formated duration from seconds\n * @param duration\n */\nconst formatDuration = (duration: number) => {\n const seconds = duration % 60;\n const totalMinutes = Math.floor(duration / 60);\n const minutes = totalMinutes % 60;\n const hours = Math.floor(totalMinutes / 60);\n const notHours = (\"0\" + minutes).substr(-2) + \":\" + (\"0\" + seconds).substr(-2);\n return hours > 0 ? hours + \":\" + notHours : notHours;\n};\n","import renderAtom from \"./atom1\";\nimport renderJSON from \"./json\";\nimport renderRSS from \"./rss2\";\nimport type { Author, Category, Enclosure, Extension, FeedOptions, Item } from \"./typings\";\n\nexport type { Author, Category, Enclosure, Extension, FeedOptions, Item };\n\n/**\n * Class used to generate Feeds\n */\nexport class Feed {\n options: FeedOptions;\n items: Item[] = [];\n categories: string[] = [];\n contributors: Author[] = [];\n extensions: Extension[] = [];\n\n constructor(options: FeedOptions) {\n this.options = options;\n }\n\n /**\n * Add a feed item\n * @param item\n */\n public addItem = (item: Item) => this.items.push(item);\n\n /**\n * Add a category\n * @param category\n */\n public addCategory = (category: string) => this.categories.push(category);\n\n /**\n * Add a contributor\n * @param contributor\n */\n public addContributor = (contributor: Author) => this.contributors.push(contributor);\n\n /**\n * Adds an extension\n * @param extension\n */\n public addExtension = (extension: Extension) => this.extensions.push(extension);\n\n /**\n * Returns a Atom 1.0 feed\n */\n public atom1 = (): string => renderAtom(this);\n\n /**\n * Returns a RSS 2.0 feed\n */\n public rss2 = (): string => renderRSS(this);\n\n /**\n * Returns a JSON1 feed\n */\n public json1 = (): string => renderJSON(this);\n}\n"],"mappings":"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"}