UNPKG

16.4 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
7var dompurify = require('dompurify');
8var useSWR = _interopDefault(require('swr'));
9var htmlparser2 = require('htmlparser2');
10
11/** searches for a tag in the node list, prevents recursive searches */
12
13var findByTag = function findByTag(nodes, tagName) {
14 return Array.from(nodes).find(function (e) {
15 return e.nodeName === tagName;
16 });
17};
18/** searches for nodes which have a matching tagName, prevents recursive searches */
19
20
21var filterByTag = function filterByTag(nodes, tagName) {
22 return Array.from(nodes).filter(function (e) {
23 return e.nodeName === tagName;
24 });
25};
26/** shortcut method for `findByTag()` that accesses children */
27
28
29var findChildTag = function findChildTag(parent, tagName) {
30 return findByTag(parent.children, tagName);
31};
32/** shortcut method for `filterByTag()` that accesses children */
33
34
35var filterChildTags = function filterChildTags(parent, tagName) {
36 return filterByTag(parent.children, tagName);
37};
38/** parses the feed */
39
40
41function parseAtomFeed(data) {
42 var parser = new DOMParser();
43 var xml = parser.parseFromString(data, 'text/xml');
44 var feed = findChildTag(xml, 'feed');
45
46 if (feed) {
47 var _sanitizeTextContent, _findChildTag$textCon, _findChildTag, _sanitizeTextContent2;
48
49 return {
50 id: (_sanitizeTextContent = sanitizeTextContent(findChildTag(feed, 'id'))) != null ? _sanitizeTextContent : '',
51 title: parseAtomText(findChildTag(feed, 'title')),
52 updated: new Date((_findChildTag$textCon = (_findChildTag = findChildTag(feed, 'updated')) == null ? void 0 : _findChildTag.textContent) != null ? _findChildTag$textCon : 0),
53 entries: filterChildTags(feed, 'entry').map(function (e) {
54 return parseAtomEntry(e);
55 }),
56 author: filterChildTags(feed, 'author').map(function (author) {
57 return parseAtomPerson(author);
58 }),
59 link: filterChildTags(feed, 'link').map(function (link) {
60 return parseAtomLink(link);
61 }),
62 category: filterChildTags(feed, 'category').map(function (category) {
63 return parseAtomCategory(category);
64 }),
65 contributor: filterChildTags(feed, 'contributor').map(function (contributor) {
66 return parseAtomPerson(contributor);
67 }),
68 generator: {
69 value: (_sanitizeTextContent2 = sanitizeTextContent(findChildTag(feed, 'generator'))) != null ? _sanitizeTextContent2 : '',
70 uri: sanitizeTextAttribute(findChildTag(feed, 'generator'), 'uri'),
71 version: sanitizeTextAttribute(findChildTag(feed, 'generator'), 'version')
72 },
73 icon: sanitizeTextContent(findChildTag(feed, 'icon')),
74 logo: sanitizeTextContent(findChildTag(feed, 'logo')),
75 rights: parseAtomText(findChildTag(feed, 'rights')),
76 subtitle: sanitizeTextContent(findChildTag(feed, 'subtitle'))
77 };
78 }
79
80 throw Error('No <feed> tag found.');
81}
82function parseAtomEntry(entry) {
83 var _sanitizeTextContent3, _findChildTag$textCon2, _findChildTag2, _findChildTag$textCon3, _findChildTag3;
84
85 return {
86 id: (_sanitizeTextContent3 = sanitizeTextContent(findChildTag(entry, 'id'))) != null ? _sanitizeTextContent3 : '',
87 title: parseAtomText(findChildTag(entry, 'title')),
88 updated: new Date((_findChildTag$textCon2 = (_findChildTag2 = findChildTag(entry, 'updated')) == null ? void 0 : _findChildTag2.textContent) != null ? _findChildTag$textCon2 : 0),
89 author: filterChildTags(entry, 'author').map(function (author) {
90 return parseAtomPerson(author);
91 }),
92 content: parseAtomContent(findChildTag(entry, 'content')),
93 link: filterChildTags(entry, 'link').map(function (link) {
94 return parseAtomLink(link);
95 }),
96 summary: parseAtomText(findChildTag(entry, 'summary')),
97 category: filterChildTags(entry, 'category').map(function (category) {
98 return parseAtomCategory(category);
99 }),
100 contributor: filterChildTags(entry, 'contributor').map(function (contributor) {
101 return parseAtomPerson(contributor);
102 }),
103 published: findChildTag(entry, 'published') ? new Date((_findChildTag$textCon3 = (_findChildTag3 = findChildTag(entry, 'published')) == null ? void 0 : _findChildTag3.textContent) != null ? _findChildTag$textCon3 : 0) : undefined,
104 rights: parseAtomText(findChildTag(entry, 'rights')),
105 source: parseAtomSource(findChildTag(entry, 'source'))
106 };
107}
108/** safely decode text content */
109
110function safelyDecodeAtomText(type, element) {
111 if (element !== undefined) {
112 var _element$textContent;
113
114 // If type="xhtml", then this element contains inline xhtml, wrapped in a div element.
115 // This means that the existing `.innerHTML` is ready to be santized
116 if (type === 'xhtml') return dompurify.sanitize(element.innerHTML); // If type="html", then this element contains entity escaped html.
117 // using `.textContent` will un-escape the text
118 else if (type === 'html') return dompurify.sanitize((_element$textContent = element.textContent) != null ? _element$textContent : ''); // If type="text", then this element contains plain text with no entity escaped html.
119 // This means that the content of `.innerHTML` are **intended** to be safe.
120 // However, we don't want to leave an attack vector open, so we're going to sanitize it anyway.
121 else if (type === 'text') return dompurify.sanitize(element.innerHTML);
122 }
123
124 return '';
125}
126/** shortcut for safely decoding the `.textContent` value of an element */
127
128function sanitizeTextContent(element) {
129 var _element$textContent2;
130
131 return element !== undefined ? dompurify.sanitize((_element$textContent2 = element == null ? void 0 : element.textContent) != null ? _element$textContent2 : '') : undefined;
132}
133/** shortcut for safely decoding the an attribute value of an element */
134
135function sanitizeTextAttribute(element, attributeName) {
136 return element !== undefined ? element.getAttribute(attributeName) !== null ? dompurify.sanitize(element.getAttribute(attributeName)) : undefined : undefined;
137}
138function parseAtomContent(content) {
139 var _sanitizeTextAttribut;
140
141 var type = (_sanitizeTextAttribut = sanitizeTextAttribute(content, 'type')) != null ? _sanitizeTextAttribut : undefined;
142 return {
143 type: type,
144 src: sanitizeTextAttribute(content, 'src'),
145 value: safelyDecodeAtomText(type, content)
146 };
147}
148function parseAtomText(text) {
149 var _sanitizeTextAttribut2;
150
151 var type = (_sanitizeTextAttribut2 = sanitizeTextAttribute(text, 'type')) != null ? _sanitizeTextAttribut2 : undefined;
152 return {
153 type: type,
154 value: safelyDecodeAtomText(type, text)
155 };
156}
157function parseAtomPerson(person) {
158 var _findChildTag$textCon4, _findChildTag4;
159
160 return {
161 name: dompurify.sanitize((_findChildTag$textCon4 = (_findChildTag4 = findChildTag(person, 'name')) == null ? void 0 : _findChildTag4.textContent) != null ? _findChildTag$textCon4 : ''),
162 uri: sanitizeTextContent(findChildTag(person, 'uri')),
163 email: sanitizeTextContent(findChildTag(person, 'email'))
164 };
165}
166function parseAtomLink(link) {
167 var _sanitizeTextAttribut3;
168
169 return {
170 href: (_sanitizeTextAttribut3 = sanitizeTextAttribute(link, 'href')) != null ? _sanitizeTextAttribut3 : '',
171 rel: sanitizeTextAttribute(link, 'ref'),
172 type: sanitizeTextAttribute(link, 'type'),
173 hreflang: sanitizeTextAttribute(link, 'hreflang'),
174 title: sanitizeTextAttribute(link, 'title'),
175 length: sanitizeTextAttribute(link, 'length')
176 };
177}
178function parseAtomCategory(category) {
179 var _sanitizeTextAttribut4, _sanitizeTextAttribut5, _sanitizeTextAttribut6;
180
181 return {
182 term: (_sanitizeTextAttribut4 = sanitizeTextAttribute(category, 'term')) != null ? _sanitizeTextAttribut4 : '',
183 scheme: (_sanitizeTextAttribut5 = sanitizeTextAttribute(category, 'scheme')) != null ? _sanitizeTextAttribut5 : undefined,
184 label: (_sanitizeTextAttribut6 = sanitizeTextAttribute(category, 'label')) != null ? _sanitizeTextAttribut6 : undefined
185 };
186}
187function parseAtomSource(source) {
188 if (source !== undefined) {
189 var _sanitizeTextContent4, _sanitizeTextContent5, _findChildTag$textCon5, _findChildTag5;
190
191 return {
192 id: (_sanitizeTextContent4 = sanitizeTextContent(findChildTag(source, 'id'))) != null ? _sanitizeTextContent4 : '',
193 title: (_sanitizeTextContent5 = sanitizeTextContent(findChildTag(source, 'title'))) != null ? _sanitizeTextContent5 : '',
194 updated: new Date((_findChildTag$textCon5 = (_findChildTag5 = findChildTag(source, 'title')) == null ? void 0 : _findChildTag5.textContent) != null ? _findChildTag$textCon5 : 0)
195 };
196 }
197
198 return undefined;
199}
200
201var Parser = {
202 __proto__: null,
203 parseAtomFeed: parseAtomFeed,
204 parseAtomEntry: parseAtomEntry,
205 safelyDecodeAtomText: safelyDecodeAtomText,
206 sanitizeTextContent: sanitizeTextContent,
207 sanitizeTextAttribute: sanitizeTextAttribute,
208 parseAtomContent: parseAtomContent,
209 parseAtomText: parseAtomText,
210 parseAtomPerson: parseAtomPerson,
211 parseAtomLink: parseAtomLink,
212 parseAtomCategory: parseAtomCategory,
213 parseAtomSource: parseAtomSource
214};
215
216function isAtomFeed(obj, _argumentName) {
217 return (obj !== null && typeof obj === "object" || typeof obj === "function") && typeof obj.id === "string" && isAtomTitle(obj.title) && obj.updated instanceof Date && Array.isArray(obj.entries) && obj.entries.every(function (e) {
218 return isAtomEntry(e);
219 }) && (typeof obj.author === "undefined" || Array.isArray(obj.author) && obj.author.every(function (e) {
220 return isAtomAuthor(e);
221 })) && (typeof obj.link === "undefined" || Array.isArray(obj.link) && obj.link.every(function (e) {
222 return isAtomLink(e);
223 })) && (typeof obj.category === "undefined" || Array.isArray(obj.category) && obj.category.every(function (e) {
224 return isAtomCategory(e);
225 })) && (typeof obj.contributor === "undefined" || Array.isArray(obj.contributor) && obj.contributor.every(function (e) {
226 return isAtomContributor(e);
227 })) && (typeof obj.generator === "undefined" || isAtomGenerator(obj.generator)) && (typeof obj.icon === "undefined" || typeof obj.icon === "string") && (typeof obj.logo === "undefined" || typeof obj.logo === "string") && (typeof obj.rights === "undefined" || isAtomRights(obj.rights)) && (typeof obj.subtitle === "undefined" || typeof obj.subtitle === "string");
228}
229function isAtomGenerator(obj, _argumentName) {
230 return (obj !== null && typeof obj === "object" || typeof obj === "function") && typeof obj.value === "string" && (typeof obj.uri === "undefined" || typeof obj.uri === "string") && (typeof obj.version === "undefined" || typeof obj.version === "string");
231}
232function isAtomEntry(obj, _argumentName) {
233 return (obj !== null && typeof obj === "object" || typeof obj === "function") && typeof obj.id === "string" && isAtomTitle(obj.title) && obj.updated instanceof Date && (typeof obj.author === "undefined" || Array.isArray(obj.author) && obj.author.every(function (e) {
234 return isAtomAuthor(e);
235 })) && (typeof obj.content === "undefined" || isAtomContent(obj.content)) && (typeof obj.link === "undefined" || Array.isArray(obj.link) && obj.link.every(function (e) {
236 return isAtomLink(e);
237 })) && (typeof obj.summary === "undefined" || isAtomSummary(obj.summary)) && (typeof obj.category === "undefined" || Array.isArray(obj.category) && obj.category.every(function (e) {
238 return isAtomCategory(e);
239 })) && (typeof obj.contributor === "undefined" || Array.isArray(obj.contributor) && obj.contributor.every(function (e) {
240 return isAtomContributor(e);
241 })) && (typeof obj.published === "undefined" || obj.published instanceof Date) && (typeof obj.rights === "undefined" || isAtomRights(obj.rights)) && (typeof obj.source === "undefined" || isAtomSource(obj.source));
242}
243function isAtomSource(obj, _argumentName) {
244 return (obj !== null && typeof obj === "object" || typeof obj === "function") && typeof obj.id === "string" && typeof obj.title === "string" && obj.updated instanceof Date;
245}
246function isAtomCategory(obj, _argumentName) {
247 return (obj !== null && typeof obj === "object" || typeof obj === "function") && typeof obj.term === "string" && (typeof obj.scheme === "undefined" || typeof obj.scheme === "string") && (typeof obj.label === "undefined" || typeof obj.label === "string");
248}
249function isAtomContent(obj, _argumentName) {
250 return (obj !== null && typeof obj === "object" || typeof obj === "function") && (typeof obj.type === "undefined" || obj.type === "text" || obj.type === "html" || obj.type === "xhtml") && (typeof obj.src === "undefined" || typeof obj.src === "string") && typeof obj.value === "string";
251}
252function isAtomLink(obj, _argumentName) {
253 return (obj !== null && typeof obj === "object" || typeof obj === "function") && typeof obj.href === "string" && (typeof obj.rel === "undefined" || obj.rel === "alternate" || obj.rel === "enclosure" || obj.rel === "related" || obj.rel === "self" || obj.rel === "via") && (typeof obj.type === "undefined" || typeof obj.type === "string") && (typeof obj.hreflang === "undefined" || typeof obj.hreflang === "string") && (typeof obj.title === "undefined" || typeof obj.title === "string") && (typeof obj.length === "undefined" || typeof obj.length === "string");
254}
255function isAtomPerson(obj, _argumentName) {
256 return (obj !== null && typeof obj === "object" || typeof obj === "function") && typeof obj.name === "string" && (typeof obj.uri === "undefined" || typeof obj.uri === "string") && (typeof obj.email === "undefined" || typeof obj.email === "string");
257}
258function isAtomLinkRelType(obj, _argumentName) {
259 return obj === "alternate" || obj === "enclosure" || obj === "related" || obj === "self" || obj === "via";
260}
261function isAtomAuthor(obj, _argumentName) {
262 return isAtomPerson(obj);
263}
264function isAtomContributor(obj, _argumentName) {
265 return isAtomPerson(obj);
266}
267function isAtomText(obj, _argumentName) {
268 return (obj !== null && typeof obj === "object" || typeof obj === "function") && (typeof obj.type === "undefined" || obj.type === "text" || obj.type === "html" || obj.type === "xhtml") && typeof obj.value === "string";
269}
270function isAtomTextType(obj, _argumentName) {
271 return obj === "text" || obj === "html" || obj === "xhtml";
272}
273function isAtomTitle(obj, _argumentName) {
274 return isAtomText(obj);
275}
276function isAtomSummary(obj, _argumentName) {
277 return isAtomText(obj);
278}
279function isAtomRights(obj, _argumentName) {
280 return isAtomText(obj);
281}
282
283var index_guard = {
284 __proto__: null,
285 isAtomFeed: isAtomFeed,
286 isAtomGenerator: isAtomGenerator,
287 isAtomEntry: isAtomEntry,
288 isAtomSource: isAtomSource,
289 isAtomCategory: isAtomCategory,
290 isAtomContent: isAtomContent,
291 isAtomLink: isAtomLink,
292 isAtomPerson: isAtomPerson,
293 isAtomLinkRelType: isAtomLinkRelType,
294 isAtomAuthor: isAtomAuthor,
295 isAtomContributor: isAtomContributor,
296 isAtomText: isAtomText,
297 isAtomTextType: isAtomTextType,
298 isAtomTitle: isAtomTitle,
299 isAtomSummary: isAtomSummary,
300 isAtomRights: isAtomRights
301};
302
303/**
304 * The React hook used for reading the Atom feed.
305 * @param feedURL The URL of the Atom feed
306 * @param options Options that are passed to `useSWR()` behind the scenes.
307 * More info: https://swr.vercel.app/docs/options#options
308 * @returns The decoded Atom feed or any errors seen along the way
309 */
310
311function useAtomFeed(feedURL, options) {
312 var fetcher = function fetcher(url) {
313 return fetch(url).then(function (res) {
314 return res.text();
315 });
316 };
317
318 var _useSWR = useSWR(feedURL, fetcher, options),
319 data = _useSWR.data,
320 error = _useSWR.error,
321 isValidating = _useSWR.isValidating; // if data is defined
322
323
324 if (data) {
325 // attempt to decode
326 try {
327 var decoded = htmlparser2.parseFeed(data, {
328 xmlMode: true
329 }); // return a good decode
330
331 return {
332 data: decoded,
333 error: error,
334 isValidating: isValidating
335 };
336 } catch (parseError) {
337 // return a decode failure
338 return {
339 data: undefined,
340 error: parseError,
341 isValidating: isValidating
342 };
343 }
344 } else {
345 // data is undefined
346 return {
347 data: undefined,
348 error: error,
349 isValidating: isValidating
350 };
351 }
352}
353
354exports.Guards = index_guard;
355exports.Parser = Parser;
356exports.useAtomFeed = useAtomFeed;
357//# sourceMappingURL=use-atom-feed.cjs.development.js.map