From 58215f6703a9cbac580507f0cc2344ac49c90bd2 Mon Sep 17 00:00:00 2001 From: Yasuhiro SHIMIZU Date: Mon, 13 Jul 2020 18:07:21 +0900 Subject: [PATCH 1/2] add extra items support --- .../__snapshots__/atom1.spec.ts.snap | 7 ++++- src/__tests__/__snapshots__/rss2.spec.ts.snap | 28 ++++++++++++++++--- src/__tests__/setup.ts | 28 +++++++++++++++++++ src/atom1.ts | 16 +++++++++++ src/feed.ts | 10 ++++++- src/rss2.ts | 15 ++++++++++ src/typings/index.ts | 7 +++++ 7 files changed, 105 insertions(+), 6 deletions(-) diff --git a/src/__tests__/__snapshots__/atom1.spec.ts.snap b/src/__tests__/__snapshots__/atom1.spec.ts.snap index 569cf1d..45b3ee1 100644 --- a/src/__tests__/__snapshots__/atom1.spec.ts.snap +++ b/src/__tests__/__snapshots__/atom1.spec.ts.snap @@ -2,7 +2,7 @@ exports[`atom 1.0 should generate a valid feed 1`] = ` " - + http://example.com/ Feed Title 2013-07-13T23:00:00.000Z @@ -25,6 +25,8 @@ exports[`atom 1.0 should generate a valid feed 1`] = ` johancruyff@example.com https://example.com/johancruyff + + Joe Gargery/Fabrikam Images <![CDATA[Hello World]]> https://example.com/hello-world?id=this&that=true @@ -58,6 +60,9 @@ exports[`atom 1.0 should generate a valid feed 1`] = ` https://example.com/reggiemiller 2013-07-10T23:00:00.000Z + + Joe Gargery/Fabrikam Images + " `; diff --git a/src/__tests__/__snapshots__/rss2.spec.ts.snap b/src/__tests__/__snapshots__/rss2.spec.ts.snap index 6cb59bc..e757763 100644 --- a/src/__tests__/__snapshots__/rss2.spec.ts.snap +++ b/src/__tests__/__snapshots__/rss2.spec.ts.snap @@ -2,7 +2,7 @@ exports[`rss 2.0 should generate a valid feed 1`] = ` " - + Feed Title http://example.com/ @@ -20,6 +20,8 @@ exports[`rss 2.0 should generate a valid feed 1`] = ` All rights reserved 2013, John Doe Technology + + Joe Gargery/Fabrikam Images <![CDATA[Hello World]]> https://example.com/hello-world?link=sanitized&value=2 @@ -32,6 +34,9 @@ exports[`rss 2.0 should generate a valid feed 1`] = ` Grateful Dead MSFT + + Joe Gargery/Fabrikam Images + " @@ -39,7 +44,7 @@ exports[`rss 2.0 should generate a valid feed 1`] = ` exports[`rss 2.0 should generate a valid feed with audio 1`] = ` " - + Feed Title http://example.com/ @@ -57,6 +62,8 @@ exports[`rss 2.0 should generate a valid feed with audio 1`] = ` All rights reserved 2013, John Doe Technology + + Joe Gargery/Fabrikam Images <![CDATA[Hello World]]> https://example.com/hello-world?link=sanitized&value=2 @@ -69,6 +76,9 @@ exports[`rss 2.0 should generate a valid feed with audio 1`] = ` Grateful Dead MSFT + + Joe Gargery/Fabrikam Images + <![CDATA[Hello World]]> @@ -115,7 +125,7 @@ exports[`rss 2.0 should generate a valid feed with audio 1`] = ` exports[`rss 2.0 should generate a valid feed with enclosure 1`] = ` " - + Feed Title http://example.com/ @@ -133,6 +143,8 @@ exports[`rss 2.0 should generate a valid feed with enclosure 1`] = ` All rights reserved 2013, John Doe Technology + + Joe Gargery/Fabrikam Images <![CDATA[Hello World]]> https://example.com/hello-world?link=sanitized&value=2 @@ -145,6 +157,9 @@ exports[`rss 2.0 should generate a valid feed with enclosure 1`] = ` Grateful Dead MSFT + + Joe Gargery/Fabrikam Images + <![CDATA[Hello World]]> @@ -178,7 +193,7 @@ exports[`rss 2.0 should generate a valid feed with enclosure 1`] = ` exports[`rss 2.0 should generate a valid feed with image properties 1`] = ` " - + Feed Title http://example.com/ @@ -196,6 +211,8 @@ exports[`rss 2.0 should generate a valid feed with image properties 1`] = ` All rights reserved 2013, John Doe Technology + + Joe Gargery/Fabrikam Images <![CDATA[Hello World]]> https://example.com/hello-world?link=sanitized&value=2 @@ -208,6 +225,9 @@ exports[`rss 2.0 should generate a valid feed with image properties 1`] = ` Grateful Dead MSFT + + Joe Gargery/Fabrikam Images + <![CDATA[Hello World]]> diff --git a/src/__tests__/setup.ts b/src/__tests__/setup.ts index 79d77f7..78949f9 100644 --- a/src/__tests__/setup.ts +++ b/src/__tests__/setup.ts @@ -24,6 +24,11 @@ export const sampleFeed = new Feed({ name: "John Doe", email: "johndoe@example.com", link: "https://example.com/johndoe?link=sanitized&value=2" + }, + + namespaces: { + "xmlns:dcterms": "https://purl.org/dc/terms/", + "xmlns:media": "https://search.yahoo.com/mrss/" } }); @@ -97,6 +102,16 @@ sampleFeed.addItem({ image: "https://example.com/hello-world.jpg", enclosure: { url: "https://example.com/hello-world.jpg", length: 12665, type: "image/jpeg" }, published, + extra: { + 'media:content': { + _attributes: { + url: 'https://v3spec.msn.com/image1.jpg', + type: 'image/jpeg', + medium: 'image' + }, + 'media:credit': 'Joe Gargery/Fabrikam Images' + } + } }); sampleFeed.addExtension({ @@ -106,3 +121,16 @@ sampleFeed.addExtension({ dummy: "example", }, }); + +sampleFeed.addExtra( + 'media:content', + { + _attributes: { + url: 'https://v3spec.msn.com/image1.jpg', + type: 'image/jpeg', + medium: 'image' + } + } +) + +sampleFeed.addExtra('media:credit', 'Joe Gargery/Fabrikam Images') diff --git a/src/atom1.ts b/src/atom1.ts index 3bfe29b..7b79de0 100644 --- a/src/atom1.ts +++ b/src/atom1.ts @@ -22,6 +22,12 @@ export default (ins: Feed) => { } }; + + const namespaces = options.namespaces || {} + for (const key in namespaces) { + base.feed._attributes[key] = namespaces[key]; + } + if (options.author) { base.feed.author = formatAuthor(options.author); } @@ -79,6 +85,10 @@ export default (ins: Feed) => { // icon + for (const key in ins.extra) { + base.feed[key] = ins.extra[key]; + } + base.feed.entry = []; /************************************************************************** @@ -160,6 +170,12 @@ export default (ins: Feed) => { entry.rights = item.copyright; } + if (item.extra) { + for (const key in item.extra) { + entry[key] = item.extra[key]; + } + } + base.feed.entry.push(entry); }); diff --git a/src/feed.ts b/src/feed.ts index 1038a8c..fb24d33 100644 --- a/src/feed.ts +++ b/src/feed.ts @@ -1,7 +1,7 @@ import renderAtom from "./atom1"; import renderJSON from "./json"; import renderRSS from "./rss2"; -import { Author, Extension, FeedOptions, Item } from "./typings"; +import { Author, Extension, ExtraItem, FeedOptions, Item } from "./typings"; export { Author, Extension, FeedOptions, Item }; @@ -14,6 +14,7 @@ export class Feed { categories: string[] = []; contributors: Author[] = []; extensions: Extension[] = []; + extra: { [key: string]: ExtraItem } = {}; constructor(options: FeedOptions) { this.options = options; @@ -43,6 +44,13 @@ export class Feed { */ public addExtension = (extension: Extension) => this.extensions.push(extension); + /** + * Adds an extra custom item + * @param key + * @param value + */ + public addExtra = (key: string, value: ExtraItem) => this.extra[key] = value; + /** * Returns a Atom 1.0 feed */ diff --git a/src/rss2.ts b/src/rss2.ts index cd940a1..7f06532 100644 --- a/src/rss2.ts +++ b/src/rss2.ts @@ -27,6 +27,11 @@ export default (ins: Feed) => { }, }; + const namespaces = options.namespaces || {} + for (const key in namespaces) { + base.rss._attributes[key] = namespaces[key]; + } + /** * Channel language * https://validator.w3.org/feed/docs/rss2.html#ltlanguagegtSubelementOfLtchannelgt @@ -109,6 +114,10 @@ export default (ins: Feed) => { }; } + for (const key in ins.extra) { + base.rss.channel[key] = ins.extra[key]; + } + /** * Channel Categories * https://validator.w3.org/feed/docs/rss2.html#hrelementsOfLtitemgt @@ -193,6 +202,12 @@ export default (ins: Feed) => { item.enclosure = formatEnclosure(entry.video, "video"); } + if (entry.extra) { + for (const key in entry.extra) { + item[key] = entry.extra[key]; + } + } + base.rss.channel.item.push(item); }); diff --git a/src/typings/index.ts b/src/typings/index.ts index ac7e8c3..5df6ace 100644 --- a/src/typings/index.ts +++ b/src/typings/index.ts @@ -1,3 +1,5 @@ +import { Element, ElementCompact } from 'xml-js'; + export interface Item { title: string; id?: string; @@ -22,6 +24,8 @@ export interface Item { copyright?: string; extensions?: Extension[]; + + extra?: { [key: string]: ExtraItem }; } export interface Enclosure { @@ -52,6 +56,7 @@ export interface FeedOptions { generator?: string; language?: string; ttl?: number; + namespaces?: Record; feed?: string; feedLinks?: any; @@ -70,3 +75,5 @@ export interface Extension { name: string; objects: any; } + +export type ExtraItem = Element | ElementCompact; From c50d7a82c5b6141039830d615b19b760e173e231 Mon Sep 17 00:00:00 2001 From: Yasuhiro SHIMIZU Date: Mon, 13 Jul 2020 18:40:18 +0900 Subject: [PATCH 2/2] ExtraItem could be string --- src/typings/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/typings/index.ts b/src/typings/index.ts index 5df6ace..f8802ab 100644 --- a/src/typings/index.ts +++ b/src/typings/index.ts @@ -76,4 +76,4 @@ export interface Extension { objects: any; } -export type ExtraItem = Element | ElementCompact; +export type ExtraItem = Element | ElementCompact | string;