Skip to content

Commit 673856a

Browse files
committed
Migrate from xml to xml-js
1 parent 919ad32 commit 673856a

File tree

10 files changed

+882
-933
lines changed

10 files changed

+882
-933
lines changed

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "feed",
3-
"version": "2.0.4",
3+
"version": "3.0.0",
44
"description": "Feed is a RSS, Atom and JSON feed generator for Node.js, making content syndication simple and intuitive!",
55
"homepage": "https://github.com/jpmonette",
66
"author": "Jean-Philippe Monette <[email protected]>",
@@ -23,8 +23,7 @@
2323
"blog"
2424
],
2525
"dependencies": {
26-
"luxon": "^1.3.3",
27-
"xml": "^1.0.1"
26+
"xml-js": "^1.6.11"
2827
},
2928
"devDependencies": {
3029
"@types/jest": "^23.3.1",

src/__tests__/__snapshots__/atom1.spec.ts.snap

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ exports[`atom 1.0 should generate a valid feed 1`] = `
1717
<subtitle>This is my personnal feed!</subtitle>
1818
<logo>http://example.com/image.png</logo>
1919
<rights>All rights reserved 2013, John Doe</rights>
20-
<category term=\\"Technology\\">
21-
</category>
20+
<category term=\\"Technology\\"/>
2221
<contributor>
2322
<name>Johan Cruyff</name>
2423
<email>[email protected]</email>
@@ -27,8 +26,7 @@ exports[`atom 1.0 should generate a valid feed 1`] = `
2726
<entry>
2827
<title type=\\"html\\"><![CDATA[Hello World]]></title>
2928
<id>https://example.com/hello-world</id>
30-
<link href=\\"https://example.com/hello-world\\">
31-
</link>
29+
<link href=\\"https://example.com/hello-world\\"/>
3230
<updated>2013-07-13T23:00:00.000Z</updated>
3331
<summary type=\\"html\\"><![CDATA[This is an article about Hello World.]]></summary>
3432
<content type=\\"html\\"><![CDATA[Content of my item]]></content>

src/__tests__/__snapshots__/rss2.spec.ts.snap

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ exports[`rss 2.0 should generate a valid feed 1`] = `
2828
<content:encoded><![CDATA[Content of my item]]></content:encoded>
2929
<author>[email protected] (Jane Doe)</author>
3030
<author>[email protected] (Joe Smith)</author>
31-
<enclosure url=\\"https://example.com/hello-world.jpg\\">
32-
</enclosure>
31+
<enclosure url=\\"https://example.com/hello-world.jpg\\"/>
3332
</item>
3433
</channel>
3534
</rss>"

src/atom1.ts

Lines changed: 68 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,109 +1,120 @@
1-
/// <reference path="types/index.ts" />
2-
3-
import * as xml from "xml";
41
import { generator } from "./config";
5-
6-
const DOCTYPE = '<?xml version="1.0" encoding="utf-8"?>\n';
2+
import * as convert from "xml-js";
3+
import { Feed } from "./feed";
4+
import { Author, Item } from "./typings";
75

86
export default (ins: Feed) => {
97
const { options } = ins;
108

11-
let feed: any = [];
12-
13-
feed.push({ _attr: { xmlns: "http://www.w3.org/2005/Atom" } });
14-
feed.push({ id: options.id });
15-
feed.push({ title: options.title });
16-
17-
if (options.updated) {
18-
feed.push({ updated: options.updated.toISOString() });
19-
} else {
20-
feed.push({ updated: new Date().toISOString() });
21-
}
22-
23-
feed.push({ generator: options.generator || generator });
9+
const base: any = {
10+
_declaration: { _attributes: { version: "1.0", encoding: "utf-8" } },
11+
feed: {
12+
_attributes: { xmlns: "http://www.w3.org/2005/Atom" },
13+
id: options.id,
14+
title: options.title,
15+
updated: options.updated ? options.updated.toISOString() : new Date().toISOString(),
16+
generator: options.generator || generator
17+
}
18+
};
2419

2520
if (options.author) {
26-
feed.push({ author: formatAuthor(options.author) });
21+
base.feed.author = formatAuthor(options.author);
2722
}
2823

24+
base.feed.link = [];
25+
2926
// link (rel="alternate")
3027
if (options.link) {
31-
feed.push({ link: { _attr: { rel: "alternate", href: options.link } } });
28+
base.feed.link.push({ _attributes: { rel: "alternate", href: options.link } });
3229
}
3330

3431
// link (rel="self")
3532
const atomLink = options.feed || (options.feedLinks && options.feedLinks.atom);
3633

3734
if (atomLink) {
38-
feed.push({ link: { _attr: { rel: "self", href: atomLink } } });
35+
base.feed.link.push({ _attributes: { rel: "self", href: atomLink } });
3936
}
4037

4138
// link (rel="hub")
4239
if (options.hub) {
43-
feed.push({ link: { _attr: { rel: "hub", href: options.hub } } });
40+
base.feed.link.push({ _attributes: { rel: "hub", href: options.hub } });
4441
}
4542

4643
/**************************************************************************
4744
* "feed" node: optional elements
4845
*************************************************************************/
4946

5047
if (options.description) {
51-
feed.push({ subtitle: options.description });
48+
base.feed.subtitle = options.description;
5249
}
5350

5451
if (options.image) {
55-
feed.push({ logo: options.image });
52+
base.feed.logo = options.image;
5653
}
5754

5855
if (options.favicon) {
59-
feed.push({ icon: options.favicon });
56+
base.feed.icon = options.favicon;
6057
}
6158

6259
if (options.copyright) {
63-
feed.push({ rights: options.copyright });
60+
base.feed.rights = options.copyright;
6461
}
6562

66-
ins.categories.forEach((category: string) => {
67-
feed.push({ category: [{ _attr: { term: category } }] });
63+
base.feed.category = [];
64+
65+
ins.categories.map((category: string) => {
66+
base.feed.category.push({ _attributes: { term: category } });
6867
});
6968

70-
ins.contributors.forEach((contributor: Author) => feed.push({ contributor: formatAuthor(contributor) }));
69+
base.feed.contributor = [];
70+
71+
ins.contributors.map((contributor: Author) => {
72+
base.feed.contributor.push(formatAuthor(contributor));
73+
});
7174

7275
// icon
7376

77+
base.feed.entry = [];
78+
7479
/**************************************************************************
7580
* "entry" nodes
7681
*************************************************************************/
77-
ins.items.forEach((item: Item) => {
82+
ins.items.map((item: Item) => {
7883
//
7984
// entry: required elements
8085
//
8186

82-
let entry: any = [
83-
{ title: { _attr: { type: "html" }, _cdata: item.title } },
84-
{ id: item.id || item.link },
85-
{ link: [{ _attr: { href: item.link } }] },
86-
{ updated: item.date.toISOString() }
87-
];
87+
let entry: convert.ElementCompact = {
88+
title: { _attributes: { type: "html" }, _cdata: item.title },
89+
id: item.id || item.link,
90+
link: [{ _attributes: { href: item.link } }],
91+
updated: item.date.toISOString()
92+
};
8893

8994
//
9095
// entry: recommended elements
9196
//
9297
if (item.description) {
93-
entry.push({
94-
summary: { _attr: { type: "html" }, _cdata: item.description }
95-
});
98+
entry.summary = {
99+
_attributes: { type: "html" },
100+
_cdata: item.description
101+
};
96102
}
97103

98104
if (item.content) {
99-
entry.push({
100-
content: { _attr: { type: "html" }, _cdata: item.content }
101-
});
105+
entry.content = {
106+
_attributes: { type: "html" },
107+
_cdata: item.content
108+
};
102109
}
103110

104111
// entry author(s)
105112
if (Array.isArray(item.author)) {
106-
item.author.forEach((author: Author) => entry.push({ author: formatAuthor(author) }));
113+
entry.author = [];
114+
115+
item.author.map((author: Author) => {
116+
entry.author.push(formatAuthor(author));
117+
});
107118
}
108119

109120
// content
@@ -118,42 +129,37 @@ export default (ins: Feed) => {
118129

119130
// contributor
120131
if (item.contributor && Array.isArray(item.contributor)) {
121-
item.contributor.forEach((contributor: Author) => entry.push({ contributor: formatAuthor(contributor) }));
132+
entry.contributor = [];
133+
134+
item.contributor.map((contributor: Author) => {
135+
entry.contributor.push(formatAuthor(contributor));
136+
});
122137
}
123138

124139
// published
125140
if (item.published) {
126-
entry.push({ published: item.published.toISOString() });
141+
entry.published = item.published.toISOString();
127142
}
128143

129144
// source
130145

131146
// rights
132147
if (item.copyright) {
133-
entry.push({ rights: item.copyright });
148+
entry.rights = item.copyright;
134149
}
135150

136-
feed.push({ entry });
151+
base.feed.entry.push(entry);
137152
});
138153

139-
return DOCTYPE + xml([{ feed }], true);
154+
return convert.js2xml(base, { compact: true, ignoreComment: true, spaces: 4 });
140155
};
141156

142157
const formatAuthor = (author: Author) => {
143158
const { name, email, link } = author;
144-
let contributor = [];
145-
146-
if (name) {
147-
contributor.push({ name });
148-
}
149-
150-
if (email) {
151-
contributor.push({ email });
152-
}
153-
154-
if (link) {
155-
contributor.push({ uri: link });
156-
}
157159

158-
return contributor;
160+
return {
161+
name,
162+
email,
163+
uri: link
164+
};
159165
};

src/feed.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
/// <reference path="types/index.ts" />
2-
31
import renderAtom from "./atom1";
42
import renderJSON from "./json";
53
import renderRSS from "./rss2";
4+
import { FeedOptions, Item, Author, Extension } from "./typings";
65

76
export class Feed {
87
options: FeedOptions;

src/json.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
/// <reference path="types/index.ts" />
1+
import { Extension, Item, Author } from "./typings";
2+
import { Feed } from "./feed";
23

34
export default (ins: Feed) => {
45
const { options, items, extensions } = ins;
6+
57
let feed: any = {
68
version: "https://jsonfeed.org/version/1",
79
title: options.title
@@ -33,7 +35,7 @@ export default (ins: Feed) => {
3335
}
3436
}
3537

36-
extensions.forEach((e: Extension) => {
38+
extensions.map((e: Extension) => {
3739
feed[e.name] = e.objects;
3840
});
3941

@@ -81,7 +83,7 @@ export default (ins: Feed) => {
8183
}
8284

8385
if (item.extensions) {
84-
item.extensions.forEach((e: Extension) => {
86+
item.extensions.map((e: Extension) => {
8587
feedItem[e.name] = e.objects;
8688
});
8789
}

0 commit comments

Comments
 (0)