UNPKG

@economia/feed-to-json-promise

Version:

Feed to Json: RSS and Atom feed parser

111 lines (96 loc) 2.21 kB
const axios = require('axios') const xml2js = require('xml2js') const RssParser = require('./parsers/RssParser') class Feed { /** * @param {Object} options */ constructor (options = {}) { this.client = axios this.options = options this.xmlParser = new xml2js.Parser({trim: false, normalize: true, mergeAttrs: true}) } /** * @returns {Object} */ get options () { return this._options || { timeout: 1000, count: null, headers: {} } } /** * @param {Object} options */ set options (options) { this._options = Object.assign({}, this.options, options) } /** * @param {String} url * @param {Object} options * @returns {Promise} */ load (url, options = {}) { this.options = options return this.sendRequest(url) .then(response => { return this.parseXmlToJson(response.data) }).then(json => { return this.parseFeed(json) }) } /** * @param {String} url * @returns {Promise} */ sendRequest (url) { this.options.headers = Object.assign({}, this.options.headers, { Accept: 'application/rss+xml' }) return this.client.get(url, this.options) } /** * @param {String} xml * @returns {Promise} */ parseXmlToJson (xml) { return new Promise((resolve, reject) => { const escaped = xml.replace(/\s&\s/g, ' & ') this.xmlParser.parseString(escaped, (error, json) => { if (error) { return reject(error) } return resolve(json) }) }) } /** * @param {Object} data * @returns {Promise} */ parseFeed (data) { return new Promise((resolve, reject) => { if (data.rss) { const rssParser = new RssParser(this.options) return resolve(rssParser.parse(data.rss.channel[0])) } return reject(new Error('Unknown feed type')) }) } /** * * @return {axios} */ get client () { return this._client } /** * * @param value */ set client (value) { this._client = value; } } module.exports = Feed