react-rss
Advanced tools
Comparing version 0.0.1 to 1.0.0
import React from 'react'; | ||
import { InjectionRSSProps, InjectionRSSUrlProps } from '../types'; | ||
export declare const rssEnhancer: <T, E extends string | null = null>(Component: ((props: T & InjectionRSSProps) => JSX.Element | null) | (new (props: T & InjectionRSSProps) => React.Component<T & InjectionRSSProps, {}, any>), url?: E) => (props: Pick<T, Exclude<keyof T, "rss">> & InjectionRSSUrlProps) => JSX.Element; | ||
import { InjectionRSSProps, InjectionRSSUrlProps, Standard2RSSFormatItem, Standard2RSSFormatHeader } from '../types'; | ||
/** | ||
* Higher-order component enhancer for rss feed | ||
* @param Component Component to enhance | ||
* @param url Static url from which to draw | ||
* @param requestEnhancer You can use this to statically enhance requests by setting request headers, method etc. | ||
* @param headerEnhancer Use this function to add properties to resulting rss object. You can use standard media queries on rssElement to do so. | ||
* @param itemEnhacer Use this to enhance individual news from feed. You can use standard media queries on item to do so. | ||
*/ | ||
export declare const rssEnhancer: <T, E extends string | null = null>(Component: ((props: T & InjectionRSSProps<{}, {}>) => JSX.Element | null) | (new (props: T & InjectionRSSProps<{}, {}>) => React.Component<T & InjectionRSSProps<{}, {}>, {}, any>), url?: E, requestEnhancer?: ((url: string) => ({ | ||
input: RequestInfo; | ||
init?: RequestInit; | ||
})) | undefined, headerEnhancer?: (<F extends Standard2RSSFormatHeader>(rssElement: Element, standard: Standard2RSSFormatHeader) => Standard2RSSFormatHeader | F) | undefined, itemEnhancer?: (<K extends Standard2RSSFormatItem>(item: Element, standard: Standard2RSSFormatItem) => Standard2RSSFormatItem | K) | undefined) => (props: Pick<T, Exclude<keyof T, "rss">> & InjectionRSSUrlProps) => JSX.Element; |
@@ -85,2 +85,3 @@ "use strict"; | ||
var getRss_1 = require("../utils/getRss"); | ||
var enhanceUrl = function (url, requestEnhancer) { return requestEnhancer ? requestEnhancer(url) : { input: url }; }; | ||
var RSS = /** @class */ (function (_super) { | ||
@@ -95,8 +96,9 @@ __extends(RSS, _super); | ||
}; | ||
return _this; | ||
} | ||
RSS.prototype.componentDidMount = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var props, contents, subscription, e_1; | ||
var _this = this; | ||
_this.clearInterval = function () { | ||
if (_this.interval !== null) { | ||
clearInterval(_this.interval); | ||
} | ||
}; | ||
_this.getRss = function () { return __awaiter(_this, void 0, void 0, function () { | ||
var props, enhanced, contents; | ||
return __generator(this, function (_a) { | ||
@@ -106,2 +108,16 @@ switch (_a.label) { | ||
props = this.props; | ||
enhanced = enhanceUrl(props.url, props.requestEnhancer); | ||
return [4 /*yield*/, getRss_1.getRss(enhanced, window.fetch, props.headerEnhancer, props.itemEnhancer)]; | ||
case 1: | ||
contents = _a.sent(); | ||
return [2 /*return*/, contents]; | ||
} | ||
}); | ||
}); }; | ||
_this.sendRequest = function () { return __awaiter(_this, void 0, void 0, function () { | ||
var props, contents, e_1; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
props = this.props; | ||
this.setState({ loading: true }); | ||
@@ -114,3 +130,3 @@ _a.label = 1; | ||
} | ||
return [4 /*yield*/, getRss_1.getRss(props.url, window.fetch)]; | ||
return [4 /*yield*/, this.getRss()]; | ||
case 2: | ||
@@ -120,26 +136,3 @@ contents = _a.sent(); | ||
if (props.subscribe) { | ||
subscription = parseInt(contents.header.ttl, 10); | ||
this.interval = window.setInterval(function () { return __awaiter(_this, void 0, void 0, function () { | ||
var contents_1, e_2; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
if (!props.url) { | ||
throw Error('Cannot set up rss feed of nonexistent url!'); | ||
} | ||
this.setState({ loading: true }); | ||
return [4 /*yield*/, getRss_1.getRss(props.url, window.fetch)]; | ||
case 1: | ||
contents_1 = _a.sent(); | ||
this.setState({ contents: contents_1, loading: false, error: null }); | ||
return [3 /*break*/, 3]; | ||
case 2: | ||
e_2 = _a.sent(); | ||
this.setState({ error: e_2, loading: false }); | ||
return [3 /*break*/, 3]; | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
}); }, (isNaN(subscription) ? 10 : subscription) * 60 * 1000); | ||
this.setupSubscription(contents); | ||
} | ||
@@ -154,9 +147,50 @@ return [3 /*break*/, 4]; | ||
}); | ||
}); }; | ||
_this.setupSubscription = function (contents) { | ||
var props = _this.props; | ||
var subscription = parseInt(contents.header.ttl, 10); | ||
_this.interval = window.setInterval(function () { return __awaiter(_this, void 0, void 0, function () { | ||
var contents_1, e_2; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
if (!props.url) { | ||
throw Error('Cannot set up rss feed of nonexistent url!'); | ||
} | ||
this.setState({ loading: true }); | ||
return [4 /*yield*/, this.getRss()]; | ||
case 1: | ||
contents_1 = _a.sent(); | ||
this.setState({ contents: contents_1, loading: false, error: null }); | ||
return [3 /*break*/, 3]; | ||
case 2: | ||
e_2 = _a.sent(); | ||
this.setState({ error: e_2, loading: false }); | ||
return [3 /*break*/, 3]; | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
}); }, (isNaN(subscription) ? 10 : subscription) * 60 * 1000); | ||
}; | ||
return _this; | ||
} | ||
RSS.prototype.componentDidMount = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
this.sendRequest(); | ||
return [2 /*return*/]; | ||
}); | ||
}); | ||
}; | ||
RSS.prototype.componentWillUnmount = function () { | ||
if (this.interval !== null) { | ||
clearInterval(this.interval); | ||
RSS.prototype.componentDidUpdate = function (prevProps) { | ||
var props = this.props; | ||
if (prevProps.subscribe !== props.subscribe || prevProps.url !== props.url) { | ||
this.clearInterval(); | ||
this.sendRequest(); | ||
} | ||
}; | ||
RSS.prototype.componentWillUnmount = function () { | ||
this.clearInterval(); | ||
}; | ||
RSS.prototype.render = function () { | ||
@@ -183,7 +217,15 @@ var _a = this, state = _a.state, props = _a.props; | ||
}(react_1.Component)); | ||
exports.rssEnhancer = function (Component, url) { | ||
/** | ||
* Higher-order component enhancer for rss feed | ||
* @param Component Component to enhance | ||
* @param url Static url from which to draw | ||
* @param requestEnhancer You can use this to statically enhance requests by setting request headers, method etc. | ||
* @param headerEnhancer Use this function to add properties to resulting rss object. You can use standard media queries on rssElement to do so. | ||
* @param itemEnhacer Use this to enhance individual news from feed. You can use standard media queries on item to do so. | ||
*/ | ||
exports.rssEnhancer = function (Component, url, requestEnhancer, headerEnhancer, itemEnhancer) { | ||
if (url === void 0) { url = null; } | ||
return function (props) { | ||
return (react_1.default.createElement(RSS, { url: (props.url || url), loadingComponent: props.loadingComponent, errorComponent: props.errorComponent }, function (rss) { return (react_1.default.createElement(Component, __assign({}, props, { rss: rss }))); })); | ||
return (react_1.default.createElement(RSS, { url: (props.url || url), loadingComponent: props.loadingComponent, errorComponent: props.errorComponent, requestEnhancer: requestEnhancer, headerEnhancer: headerEnhancer, itemEnhancer: itemEnhancer }, function (rss) { return (react_1.default.createElement(Component, __assign({}, props, { rss: rss }))); })); | ||
}; | ||
}; |
{ | ||
"name": "react-rss", | ||
"version": "0.0.1", | ||
"version": "1.0.0", | ||
"description": "React component capable of reading and rendering any RSS feed", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -6,3 +6,3 @@ # react-rss | ||
So far this feed only supports standart RSS params defined in: https://validator.w3.org/feed/docs/rss2.html. | ||
So far this feed only supports standard RSS params defined in: https://validator.w3.org/feed/docs/rss2.html. | ||
@@ -126,2 +126,57 @@ ## Example of usage | ||
### Changes since 1.0.0 | ||
Fixed typos in typings of this package. Added enhancers, which allow you to pick custom xml elements (using query selectors) out of RSS and add them to the component props. | ||
Also, fixed default parsing of RSS XML document and added component update mechanism when passed url changes. | ||
#### Example of use | ||
```JSX | ||
/** | ||
* Props injected have a two-type template: first is header enhancement, second one is with what is each item enhanced. | ||
*/ | ||
class SourcedRSSComponent extends Component<{ label: string } & InjectionRSSProps<{ hasImage: boolean }, { mediaUrl?: string }>> { | ||
public render() { | ||
const { props } = this; | ||
return ( | ||
<div> | ||
<h2>{props.label}</h2> | ||
<a href={props.rss.header.link}> | ||
{props.rss.header.title} | ||
{props.rss.header.hasImage && ' Has image!'} | ||
</a> | ||
<ul> | ||
{props.rss.items.map(item => ( | ||
<li> | ||
{item.description} | ||
{item.mediaUrl && <span>Url: {item.mediaUrl}</span>} | ||
</li> | ||
))} | ||
</ul> | ||
</div> | ||
); | ||
} | ||
}; | ||
export default rssEnhancer( | ||
SourcedRSSComponent, | ||
null, // Default url is null, which means resulting component will need an url passed in its props. | ||
url => ({ input: url, init: { method: 'POST' } }), // Enhances the used url request by any optional parameter, such as headers, method, etc. | ||
(rss, header) => { // Enhances header portion of result | ||
return { ...header, hasImage: Boolean(rss.querySelector('image')) }; | ||
}, | ||
(rssItem, item) => { // Enhances each item by certain query | ||
const mediaUrl = rssItem.querySelector('content')?.getAttribute('url'); | ||
if (mediaUrl) { | ||
return { ...item, mediaUrl }; | ||
} | ||
return item; | ||
} | ||
); | ||
``` | ||
## Addendum | ||
@@ -128,0 +183,0 @@ |
/// <reference types="react" /> | ||
export interface Standart2RSSFormat { | ||
header: Standart2RSSFormatHeader; | ||
items: Standart2RSSFormatItem[]; | ||
export interface Standard2RSSFormat { | ||
header: Standard2RSSFormatHeader; | ||
items: Standard2RSSFormatItem[]; | ||
} | ||
export interface InjectionRSSProps { | ||
export interface InjectionRSSProps<T = {}, K = {}> { | ||
/** | ||
* Formatted RSS2 standard feed | ||
*/ | ||
rss: Standart2RSSFormat; | ||
rss: { | ||
header: T & Standard2RSSFormatHeader; | ||
} & { | ||
items: (K & Standard2RSSFormatItem)[]; | ||
}; | ||
} | ||
@@ -28,11 +32,21 @@ export interface InjectionRSSUrlProps { | ||
*/ | ||
errorComponent?: (props: { | ||
errorComponent?: <T extends Standard2RSSFormat = Standard2RSSFormat>(props: { | ||
error: any; | ||
contents: Standart2RSSFormat | null; | ||
contents: T | null; | ||
}) => JSX.Element; | ||
} | ||
export interface RSSProps extends InjectionRSSUrlProps { | ||
children: (rss: Standart2RSSFormat) => JSX.Element | null; | ||
export interface RSSProps<T = {}, K = {}> extends InjectionRSSUrlProps { | ||
requestEnhancer?: (url: string) => ({ | ||
input: RequestInfo; | ||
init?: RequestInit; | ||
}); | ||
headerEnhancer?: (rssElement: Element, standard: Standard2RSSFormatHeader) => T & Standard2RSSFormatHeader; | ||
itemEnhancer?: (item: Element, standard: Standard2RSSFormatItem) => K & Standard2RSSFormatItem; | ||
children: (rss: Standard2RSSFormat & { | ||
header: T; | ||
} & { | ||
items: K[]; | ||
}) => JSX.Element | null; | ||
} | ||
export interface Standart2RSSFormatHeader { | ||
export interface Standard2RSSFormatHeader { | ||
title: string; | ||
@@ -49,7 +63,2 @@ image?: { | ||
language: string; | ||
blogChannel: { | ||
blogRoll: string; | ||
mySubscriptions: string; | ||
blink: string; | ||
}; | ||
copyright: string; | ||
@@ -67,3 +76,3 @@ lastBuildDate: string; | ||
} | ||
export interface Standart2RSSFormatItem { | ||
export interface Standard2RSSFormatItem { | ||
description: string; | ||
@@ -70,0 +79,0 @@ pubDate: string; |
@@ -1,1 +0,9 @@ | ||
export declare const getRss: (url: string, fetch: (input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>) => Promise<import("../types").Standart2RSSFormat>; | ||
import { Standard2RSSFormat, Standard2RSSFormatItem, Standard2RSSFormatHeader } from "../types"; | ||
export declare const getRss: <T, E>(enhanced: { | ||
input: RequestInfo; | ||
init?: RequestInit; | ||
}, fetch: (input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>, headerEnhancer?: ((rssElement: Element, standard: Standard2RSSFormatHeader) => T & Standard2RSSFormatHeader) | undefined, itemEnhancer?: ((item: Element, standard: Standard2RSSFormatItem) => E & Standard2RSSFormatItem) | undefined) => Promise<Standard2RSSFormat & { | ||
header: T; | ||
} & { | ||
items: E[]; | ||
}>; |
@@ -41,3 +41,3 @@ "use strict"; | ||
var parseXml_1 = require("./parseXml"); | ||
exports.getRss = function (url, fetch) { return __awaiter(void 0, void 0, void 0, function () { | ||
exports.getRss = function (enhanced, fetch, headerEnhancer, itemEnhancer) { return __awaiter(void 0, void 0, void 0, function () { | ||
var result, xml; | ||
@@ -50,3 +50,3 @@ return __generator(this, function (_a) { | ||
} | ||
return [4 /*yield*/, fetch(url)]; | ||
return [4 /*yield*/, fetch(enhanced.input, enhanced.init)]; | ||
case 1: | ||
@@ -57,5 +57,5 @@ result = _a.sent(); | ||
xml = _a.sent(); | ||
return [2 /*return*/, parseXml_1.parseXml(xml)]; | ||
return [2 /*return*/, parseXml_1.parseXml(xml, headerEnhancer, itemEnhancer)]; | ||
} | ||
}); | ||
}); }; |
@@ -1,2 +0,6 @@ | ||
import { Standart2RSSFormat } from "../types"; | ||
export declare const parseXml: (xml: string) => Standart2RSSFormat; | ||
import { Standard2RSSFormat, Standard2RSSFormatItem, Standard2RSSFormatHeader } from "../types"; | ||
export declare const parseXml: <T, E>(xml: string, enhancer?: ((rssElement: Element, standard: Standard2RSSFormatHeader) => T & Standard2RSSFormatHeader) | undefined, itemEnhancer?: ((item: Element, standard: Standard2RSSFormatItem) => E & Standard2RSSFormatItem) | undefined) => Standard2RSSFormat & { | ||
header: T; | ||
} & { | ||
items: E[]; | ||
}; |
@@ -12,15 +12,11 @@ "use strict"; | ||
}; | ||
exports.parseXml = function (xml) { | ||
exports.parseXml = function (xml, enhancer, itemEnhancer) { | ||
var _a; | ||
var doc = new DOMParser().parseFromString(xml, 'text/xml'); | ||
try { | ||
var channel = doc.querySelector('rss').querySelector('channel'); | ||
var rssElement = doc.querySelector('rss'); | ||
var channel = rssElement.querySelector('channel'); | ||
var image = channel.querySelector('image'); | ||
var rss = { | ||
header: { | ||
blogChannel: { | ||
blink: getFromChannel(channel, 'blogChannel\\:blink'), | ||
blogRoll: getFromChannel(channel, 'blogChannel\\:blogRoll'), | ||
mySubscriptions: getFromChannel(channel, 'blogChannel\\:mySubscriptions'), | ||
}, | ||
category: { | ||
@@ -52,3 +48,3 @@ category: getFromChannel(channel, 'category'), | ||
var source = item.querySelector('source'); | ||
return { | ||
var result = { | ||
author: getFromChannel(item, 'author'), | ||
@@ -72,4 +68,11 @@ category: getFromChannel(item, 'category'), | ||
}; | ||
if (itemEnhancer) { | ||
return itemEnhancer(item, result); | ||
} | ||
return result; | ||
}), | ||
}; | ||
if (enhancer) { | ||
return { header: enhancer(rssElement, rss.header), items: rss.items }; | ||
} | ||
return rss; | ||
@@ -76,0 +79,0 @@ } |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
29457
498
1
187