rss-parser
Advanced tools
Comparing version 3.9.0 to 3.10.0
@@ -10,10 +10,10 @@ import { Options } from 'xml2js'; | ||
type CustomFieldItem = string | { keepArray: boolean } | ||
type CustomFieldItem<U> = keyof U | { keepArray: boolean } | ||
export interface CustomFields { | ||
readonly feed?: string[]; | ||
readonly item?: CustomFieldItem[] | CustomFieldItem[][]; | ||
export interface CustomFields<T, U> { | ||
readonly feed?: Array<keyof T>; | ||
readonly item?: CustomFieldItem<U>[] | CustomFieldItem<U>[][]; | ||
} | ||
export interface ParserOptions { | ||
export interface ParserOptions<T, U> { | ||
readonly xml2js?: Options; | ||
@@ -24,3 +24,3 @@ readonly requestOptions?: RequestOptions; | ||
readonly maxRedirects?: number; | ||
readonly customFields?: CustomFields; | ||
readonly customFields?: CustomFields<T, U>; | ||
readonly timeout?: number; | ||
@@ -36,3 +36,2 @@ } | ||
export interface Item { | ||
[key: string]: any; | ||
link?: string; | ||
@@ -50,4 +49,3 @@ guid?: string; | ||
export interface Output { | ||
[key: string]: any; | ||
export interface Output<U> { | ||
image?: { | ||
@@ -60,3 +58,3 @@ link?: string; | ||
title?: string; | ||
items?: Item[]; | ||
items: (U & Item)[]; | ||
feedUrl?: string; | ||
@@ -83,7 +81,7 @@ description?: string; | ||
*/ | ||
declare class Parser { | ||
declare class Parser<T = {[key: string]: any}, U = {[key: string]: any}> { | ||
/** | ||
* @param options - Parser options. | ||
*/ | ||
constructor(options?: Parser.ParserOptions); | ||
constructor(options?: Parser.ParserOptions<T, U>); | ||
/** | ||
@@ -99,4 +97,4 @@ * Parse XML content to JSON. | ||
xml: string, | ||
callback?: (err: Error, feed: Parser.Output) => void | ||
): Promise<Parser.Output>; | ||
callback?: (err: Error, feed: Parser.Output<U>) => void | ||
): Promise<T & Parser.Output<U>>; | ||
@@ -118,7 +116,7 @@ /** | ||
feedUrl: string, | ||
callback?: (err: Error, feed: Parser.Output) => void, | ||
callback?: (err: Error, feed: Parser.Output<U>) => void, | ||
redirectCount?: number | ||
): Promise<Parser.Output>; | ||
): Promise<T & Parser.Output<U>>; | ||
} | ||
export = Parser; |
@@ -129,29 +129,31 @@ "use strict"; | ||
} | ||
(xmlObj.feed.entry || []).forEach(entry => { | ||
let item = {}; | ||
utils.copyFromXML(entry, item, this.options.customFields.item); | ||
if (entry.title) { | ||
let title = entry.title[0] || ''; | ||
if (title._) title = title._; | ||
if (title) item.title = title; | ||
} | ||
if (entry.link && entry.link.length) { | ||
item.link = utils.getLink(entry.link, 'alternate', 0); | ||
} | ||
if (entry.published && entry.published.length && entry.published[0].length) item.pubDate = new Date(entry.published[0]).toISOString(); | ||
if (!item.pubDate && entry.updated && entry.updated.length && entry.updated[0].length) item.pubDate = new Date(entry.updated[0]).toISOString(); | ||
if (entry.author && entry.author.length && entry.author[0].name && entry.author[0].name.length) item.author = entry.author[0].name[0]; | ||
if (entry.content && entry.content.length) { | ||
item.content = utils.getContent(entry.content[0]); | ||
item.contentSnippet = utils.getSnippet(item.content) | ||
} | ||
if (entry.id) { | ||
item.id = entry.id[0]; | ||
} | ||
this.setISODate(item); | ||
feed.items.push(item); | ||
}); | ||
feed.items = (xmlObj.feed.entry || []).map(entry => this.parseItemAtom(entry)); | ||
return feed; | ||
} | ||
parseItemAtom(entry) { | ||
let item = {}; | ||
utils.copyFromXML(entry, item, this.options.customFields.item); | ||
if (entry.title) { | ||
let title = entry.title[0] || ''; | ||
if (title._) title = title._; | ||
if (title) item.title = title; | ||
} | ||
if (entry.link && entry.link.length) { | ||
item.link = utils.getLink(entry.link, 'alternate', 0); | ||
} | ||
if (entry.published && entry.published.length && entry.published[0].length) item.pubDate = new Date(entry.published[0]).toISOString(); | ||
if (!item.pubDate && entry.updated && entry.updated.length && entry.updated[0].length) item.pubDate = new Date(entry.updated[0]).toISOString(); | ||
if (entry.author && entry.author.length && entry.author[0].name && entry.author[0].name.length) item.author = entry.author[0].name[0]; | ||
if (entry.content && entry.content.length) { | ||
item.content = utils.getContent(entry.content[0]); | ||
item.contentSnippet = utils.getSnippet(item.content) | ||
} | ||
if (entry.id) { | ||
item.id = entry.id[0]; | ||
} | ||
this.setISODate(item); | ||
return item; | ||
} | ||
buildRSS0_9(xmlObj) { | ||
@@ -198,23 +200,25 @@ var channel = xmlObj.rss.channel[0]; | ||
utils.copyFromXML(channel, feed, feedFields); | ||
items.forEach(xmlItem => { | ||
let item = {}; | ||
utils.copyFromXML(xmlItem, item, itemFields); | ||
if (xmlItem.enclosure) { | ||
item.enclosure = xmlItem.enclosure[0].$; | ||
} | ||
if (xmlItem.description) { | ||
item.content = utils.getContent(xmlItem.description[0]); | ||
item.contentSnippet = utils.getSnippet(item.content); | ||
} | ||
if (xmlItem.guid) { | ||
item.guid = xmlItem.guid[0]; | ||
if (item.guid._) item.guid = item.guid._; | ||
} | ||
if (xmlItem.category) item.categories = xmlItem.category; | ||
this.setISODate(item); | ||
feed.items.push(item); | ||
}); | ||
feed.items = items.map(xmlItem => this.parseItemRss(xmlItem, itemFields)); | ||
return feed; | ||
} | ||
parseItemRss(xmlItem, itemFields) { | ||
let item = {}; | ||
utils.copyFromXML(xmlItem, item, itemFields); | ||
if (xmlItem.enclosure) { | ||
item.enclosure = xmlItem.enclosure[0].$; | ||
} | ||
if (xmlItem.description) { | ||
item.content = utils.getContent(xmlItem.description[0]); | ||
item.contentSnippet = utils.getSnippet(item.content); | ||
} | ||
if (xmlItem.guid) { | ||
item.guid = xmlItem.guid[0]; | ||
if (item.guid._) item.guid = item.guid._; | ||
} | ||
if (xmlItem.category) item.categories = xmlItem.category; | ||
this.setISODate(item); | ||
return item; | ||
} | ||
/** | ||
@@ -255,7 +259,14 @@ * Add iTunes specific fields from XML to extracted JSON | ||
if(channel['itunes:category']) { | ||
channel['itunes:category'].forEach((category) => { | ||
categories.push(category.$.text); | ||
if (channel['itunes:category']) { | ||
const categoriesWithSubs = channel['itunes:category'].map((category) => { | ||
return { | ||
name: category.$.text, | ||
subs: category['itunes:category'] ? | ||
category['itunes:category'] | ||
.map((subcategory) => ({ name: subcategory.$.text })) : null, | ||
}; | ||
}); | ||
feed.itunes.categories = categories; | ||
feed.itunes.categories = categoriesWithSubs.map((category) => category.name); | ||
feed.itunes.categoriesWithSubs = categoriesWithSubs; | ||
} | ||
@@ -273,3 +284,8 @@ | ||
} | ||
if (keywords) feed.itunes.keywords = keywords.split(','); | ||
if (keywords && keywords.$ && keywords.$.text) { | ||
feed.itunes.keywords = keywords.$.text.split(',') | ||
} else if (typeof keywords === "string") { | ||
feed.itunes.keywords = keywords.split(','); | ||
} | ||
} | ||
@@ -276,0 +292,0 @@ } |
{ | ||
"name": "rss-parser", | ||
"version": "3.9.0", | ||
"version": "3.10.0", | ||
"main": "index.js", | ||
@@ -20,3 +20,3 @@ "types": "index.d.ts", | ||
"mocha": "^5.2.0", | ||
"puppeteer": "^1.16.0", | ||
"puppeteer": "^5.2.1", | ||
"webpack": "^4.41.0", | ||
@@ -23,0 +23,0 @@ "webpack-cli": "^3.3.9" |
@@ -10,4 +10,4 @@ # rss-parser | ||
[npm-link]: https://npmjs.org/package/rss-parser | ||
[build-image]: https://travis-ci.org/bobby-brennan/rss-parser.svg?branch=master | ||
[build-link]: https://travis-ci.org/bobby-brennan/rss-parser | ||
[build-image]: https://github.com/rbren/rss-parser/workflows/tests/badge.svg | ||
[build-link]: https://github.com/rbren/rss-parser/actions | ||
@@ -45,2 +45,30 @@ A small library for turning RSS XML feeds into JavaScript objects. | ||
### TypeScript | ||
When using TypeScript, you can set a type to control the custom fields: | ||
```typescript | ||
import Parser from 'rss-parser'; | ||
type CustomFeed = {foo: string}; | ||
type CustomItem = {bar: number}; | ||
const parser: Parser<CustomFeed, CustomItem> = new Parser({ | ||
customFields: { | ||
feed: ['foo', 'baz'], | ||
// ^ will error because `baz` is not a key of CustomFeed | ||
item: ['bar'] | ||
} | ||
}); | ||
(async () => { | ||
const feed = await parser.parseURL('https://www.reddit.com/.rss'); | ||
console.log(feed.title); // feed will have a `foo` property, type as a string | ||
feed.items.forEach(item => { | ||
console.log(item.title + ':' + item.link) // item will have a `bar` property type as a number | ||
}); | ||
})(); | ||
``` | ||
### Web | ||
@@ -47,0 +75,0 @@ > We recommend using a bundler like [webpack](https://webpack.js.org/), but we also provide |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1816857
17
11688
272