Comparing version 1.0.2 to 1.1.0
113
lib/feed.js
@@ -59,3 +59,3 @@ 'use strict'; | ||
var feed = [{ _attr: { xmlns: 'http://www.w3.org/2005/Atom' } }, { id: options.id }, { title: options.title }, { updated: options.updated ? this.ISODateString(options.updated) : this.ISODateString(new Date()) }, { generator: GENERATOR }]; | ||
var feed = [{ _attr: { xmlns: 'http://www.w3.org/2005/Atom' } }, { id: options.id }, { title: options.title }, { updated: options.updated ? this.ISODateString(options.updated) : this.ISODateString(new Date()) }, { generator: options.generator || GENERATOR }]; | ||
@@ -93,4 +93,5 @@ var root = [{ feed: feed }]; | ||
// link (rel="self") | ||
if (options.feed) { | ||
feed.push({ "link": { _attr: { rel: 'self', href: options.feed } } }); | ||
var atomLink = options.feed || options.feedLinks && options.feedLinks.atom; | ||
if (atomLink) { | ||
feed.push({ "link": { _attr: { rel: 'self', href: atomLink } } }); | ||
} | ||
@@ -115,2 +116,6 @@ | ||
if (options.favicon) { | ||
feed.push({ icon: options.favicon }); | ||
} | ||
if (options.copyright) { | ||
@@ -152,11 +157,11 @@ feed.push({ rights: options.copyright }); | ||
this.items.forEach(function (item) { | ||
// | ||
// | ||
// entry: required elements | ||
// | ||
// | ||
var entry = [{ title: { _attr: { type: 'html' }, _cdata: item.title } }, { id: item.id || item.link }, { link: [{ _attr: { href: item.link } }] }, { updated: _this.ISODateString(item.date) }]; | ||
// | ||
// | ||
// entry: recommended elements | ||
// | ||
// | ||
if (item.description) { | ||
@@ -201,3 +206,3 @@ entry.push({ summary: { _attr: { type: 'html' }, _cdata: item.description } }); | ||
// entry: optional elements | ||
// | ||
// | ||
@@ -256,3 +261,3 @@ // category | ||
var channel = [{ title: options.title }, { link: options.link }, { description: options.description }, { lastBuildDate: options.updated ? options.updated.toUTCString() : new Date().toUTCString() }, { docs: 'http://blogs.law.harvard.edu/tech/rss' }, { generator: GENERATOR }]; | ||
var channel = [{ title: options.title }, { link: options.link }, { description: options.description }, { lastBuildDate: options.updated ? options.updated.toUTCString() : new Date().toUTCString() }, { docs: 'http://blogs.law.harvard.edu/tech/rss' }, { generator: options.generator || GENERATOR }]; | ||
@@ -293,3 +298,4 @@ var rss = [{ _attr: { version: '2.0' } }, { channel: channel }]; | ||
*/ | ||
if (options.feed) { | ||
var atomLink = options.feed || options.feedLinks && options.feedLinks.atom; | ||
if (atomLink) { | ||
isAtom = true; | ||
@@ -300,3 +306,3 @@ | ||
_attr: { | ||
href: options.feed, | ||
href: atomLink, | ||
rel: 'self', | ||
@@ -391,2 +397,87 @@ type: 'application/rss+xml' | ||
}, { | ||
key: 'json1', | ||
value: function json1() { | ||
var _this2 = this; | ||
var options = this.options, | ||
items = this.items; | ||
var feed = { | ||
version: 'https://jsonfeed.org/version/1', | ||
title: options.title | ||
}; | ||
if (options.link) { | ||
feed.home_page_url = options.link; | ||
} | ||
if (options.feedLinks && options.feedLinks.json) { | ||
feed.feed_url = options.feedLinks.json; | ||
} | ||
if (options.description) { | ||
feed.description = options.description; | ||
} | ||
if (options.image) { | ||
feed.icon = options.image; | ||
} | ||
if (options.author) { | ||
feed.author = {}; | ||
if (options.author.name) { | ||
feed.author.name = options.author.name; | ||
} | ||
if (options.author.link) { | ||
feed.author.url = options.author.link; | ||
} | ||
} | ||
feed.items = items.map(function (item) { | ||
var feedItem = { | ||
id: item.id, | ||
// json_feed distinguishes between html and text content | ||
// but since we only take a single type, we'll assume HTML | ||
html_content: item.content | ||
}; | ||
if (item.link) { | ||
feedItem.url = item.link; | ||
} | ||
if (item.title) { | ||
feedItem.title = item.title; | ||
} | ||
if (item.description) { | ||
feedItem.summary = item.description; | ||
} | ||
if (item.image) { | ||
feedItem.image = item.image; | ||
} | ||
if (item.date) { | ||
feedItem.date_modified = _this2.ISODateString(item.date); | ||
} | ||
if (item.published) { | ||
feedItem.date_published = _this2.ISODateString(item.published); | ||
} | ||
if (item.author) { | ||
var author = item.author; | ||
if (author instanceof Array) { | ||
// json feed only supports 1 author per post | ||
author = author[0]; | ||
} | ||
feedItem.author = {}; | ||
if (author.name) { | ||
feedItem.author.name = author.name; | ||
} | ||
if (author.link) { | ||
feedItem.author.url = author.link; | ||
} | ||
} | ||
return feedItem; | ||
}); | ||
return JSON.stringify(feed, null, 4); | ||
} | ||
}, { | ||
key: 'ISODateString', | ||
@@ -393,0 +484,0 @@ value: function ISODateString(d) { |
{ | ||
"name": "feed", | ||
"version": "1.0.2", | ||
"version": "1.1.0", | ||
"description": "Feed is a RSS and Atom feed generator for Node.js, making content syndication simple and intuitive!", | ||
@@ -9,2 +9,6 @@ "homepage": "http://projets.jpmonette.net/en/feed", | ||
{ | ||
"name": "Ben McCormick", | ||
"email": "ben.mccormick@windsorcircle.com" | ||
}, | ||
{ | ||
"name": "Pierre Galvez", | ||
@@ -20,3 +24,3 @@ "email": "contact@pierre-galvez.fr" | ||
"test": "export NODE_ENV=test && jest", | ||
"test-travis": "export NODE_ENV=test && jest" | ||
"test-travis": "export NODE_ENV=test && jest --coverage" | ||
}, | ||
@@ -43,9 +47,10 @@ "jest": { | ||
"dependencies": { | ||
"xml": ">= 0.0.5" | ||
"xml": "^1.0.1" | ||
}, | ||
"devDependencies": { | ||
"babel-cli": "^6.24.0", | ||
"babel-preset-latest": "^6.24.0", | ||
"coveralls": "^2.13.0", | ||
"jest": "^19.0.2" | ||
"babel-cli": "^6.24.1", | ||
"babel-preset-env": "^1.5.1", | ||
"codeclimate-test-reporter": "^0.5.0", | ||
"coveralls": "^2.13.1", | ||
"jest": "^20.0.4" | ||
}, | ||
@@ -52,0 +57,0 @@ "engines": { |
# Feed for Node.js | ||
> [Feed](http://projets.jpmonette.net/en/feed) is a *RSS 2.0* and *Atom 1.0* generator for **Node.js**, making content syndication simple and intuitive! | ||
> [Feed](http://projets.jpmonette.net/en/feed) is a *RSS 2.0*, *JSON Feed 1.0*, and *Atom 1.0* generator for **Node.js**, making content syndication simple and intuitive! | ||
[![Build Status](https://travis-ci.org/jpmonette/feed.svg?branch=master)](https://travis-ci.org/jpmonette/feed) | ||
[![Build Status](https://travis-ci.org/jpmonette/feed.svg?branch=master)](https://travis-ci.org/jpmonette/feed) | ||
[![Coverage Status](https://coveralls.io/repos/github/jpmonette/feed/badge.svg?branch=master)](https://coveralls.io/github/jpmonette/feed?branch=master) | ||
@@ -33,9 +33,14 @@ | ||
title: 'Feed Title', | ||
description: 'This is my personnal feed!', | ||
description: 'This is my personal feed!', | ||
id: 'http://example.com/', | ||
link: 'http://example.com/', | ||
image: 'http://example.com/image.png', | ||
favicon: 'http://example.com/favicon.ico', | ||
copyright: 'All rights reserved 2013, John Doe', | ||
updated: new Date(2013, 06, 14), // optional, default = today | ||
generator: 'awesome', // optional, default = 'Feed for Node.js' | ||
feedLinks: { | ||
json: 'https://example.com/json', | ||
atom: 'https://example.com/atom', | ||
}, | ||
author: { | ||
@@ -58,2 +63,3 @@ name: 'John Doe', | ||
description: post.description, | ||
content: post.content, | ||
author: [{ | ||
@@ -111,2 +117,8 @@ name: 'Jane Doe', | ||
Output a JSON Feed 1.0 feed: | ||
```js | ||
feed.json1() | ||
``` | ||
Yes, it's that simple :)! | ||
@@ -113,0 +125,0 @@ |
143
src/feed.js
@@ -44,3 +44,3 @@ import xml from 'xml' | ||
{ updated: (options.updated ? this.ISODateString(options.updated) : this.ISODateString(new Date())) }, | ||
{ generator: GENERATOR }, | ||
{ generator: options.generator || GENERATOR }, | ||
] | ||
@@ -75,4 +75,5 @@ | ||
// link (rel="self") | ||
if(options.feed) { | ||
feed.push({ "link": { _attr: { rel: 'self', href: options.feed }}}); | ||
const atomLink = options.feed || (options.feedLinks && options.feedLinks.atom); | ||
if(atomLink) { | ||
feed.push({ "link": { _attr: { rel: 'self', href: atomLink }}}); | ||
} | ||
@@ -88,3 +89,3 @@ | ||
*************************************************************************/ | ||
if(options.description) { | ||
@@ -98,2 +99,6 @@ feed.push({ subtitle: options.description }); | ||
if(options.favicon) { | ||
feed.push({ icon: options.favicon }); | ||
} | ||
if(options.copyright) { | ||
@@ -106,15 +111,15 @@ feed.push({ rights: options.copyright }); | ||
}) | ||
this.contributors.forEach(item => { | ||
const { name, email, link } = item | ||
let contributor = []; | ||
if(name) { | ||
contributor.push({ name }); | ||
} | ||
if(email) { | ||
contributor.push({ email }); | ||
} | ||
if(link) { | ||
@@ -126,3 +131,3 @@ contributor.push({ uri: link }); | ||
}) | ||
// icon | ||
@@ -134,5 +139,5 @@ | ||
this.items.forEach(item => { | ||
// | ||
// | ||
// entry: required elements | ||
// | ||
// | ||
@@ -146,5 +151,5 @@ let entry = [ | ||
// | ||
// | ||
// entry: recommended elements | ||
// | ||
// | ||
if(item.description) { | ||
@@ -163,11 +168,11 @@ entry.push({ summary: { _attr: { type: 'html' }, _cdata: item.description }}); | ||
let author = []; | ||
if(name) { | ||
author.push({ name }); | ||
} | ||
if(email) { | ||
author.push({ email }); | ||
} | ||
if(link) { | ||
@@ -187,3 +192,3 @@ author.push({ uri: link }); | ||
// entry: optional elements | ||
// | ||
// | ||
@@ -197,15 +202,15 @@ // category | ||
let contributor = []; | ||
if(name) { | ||
contributor.push({ name }); | ||
} | ||
if(email) { | ||
contributor.push({ email }); | ||
} | ||
if(link) { | ||
contributor.push({ uri: link }); | ||
} | ||
entry.push({ contributor }); | ||
@@ -230,3 +235,3 @@ }) | ||
return DOCTYPE + xml(root, true); | ||
return DOCTYPE + xml(root, true); | ||
} | ||
@@ -245,3 +250,3 @@ | ||
{ docs: 'http://blogs.law.harvard.edu/tech/rss'}, | ||
{ generator: GENERATOR }, | ||
{ generator: options.generator || GENERATOR }, | ||
] | ||
@@ -277,3 +282,3 @@ | ||
} | ||
/** | ||
@@ -291,3 +296,4 @@ * Channel Categories | ||
*/ | ||
if(options.feed) { | ||
const atomLink = options.feed || (options.feedLinks && options.feedLinks.atom); | ||
if(atomLink) { | ||
isAtom = true | ||
@@ -298,3 +304,3 @@ | ||
_attr: { | ||
href: options.feed, | ||
href: atomLink, | ||
rel: 'self', | ||
@@ -306,3 +312,3 @@ type: 'application/rss+xml', | ||
} | ||
/** | ||
@@ -390,2 +396,83 @@ * Hub for PubSubHubbub | ||
json1() { | ||
const { options, items } = this | ||
let feed = { | ||
version: 'https://jsonfeed.org/version/1', | ||
title: options.title, | ||
}; | ||
if (options.link) { | ||
feed.home_page_url = options.link; | ||
} | ||
if (options.feedLinks && options.feedLinks.json) { | ||
feed.feed_url = options.feedLinks.json; | ||
} | ||
if (options.description) { | ||
feed.description = options.description; | ||
} | ||
if (options.image) { | ||
feed.icon = options.image; | ||
} | ||
if (options.author) { | ||
feed.author = {}; | ||
if (options.author.name) { | ||
feed.author.name = options.author.name; | ||
} | ||
if (options.author.link) { | ||
feed.author.url = options.author.link; | ||
} | ||
} | ||
feed.items = items.map(item => { | ||
let feedItem = { | ||
id: item.id, | ||
// json_feed distinguishes between html and text content | ||
// but since we only take a single type, we'll assume HTML | ||
html_content: item.content, | ||
} | ||
if (item.link) { | ||
feedItem.url = item.link; | ||
} | ||
if(item.title) { | ||
feedItem.title = item.title; | ||
} | ||
if (item.description) { | ||
feedItem.summary = item.description; | ||
} | ||
if (item.image) { | ||
feedItem.image = item.image | ||
} | ||
if (item.date) { | ||
feedItem.date_modified = this.ISODateString(item.date); | ||
} | ||
if (item.published) { | ||
feedItem.date_published = this.ISODateString(item.published); | ||
} | ||
if (item.author) { | ||
let author = item.author; | ||
if (author instanceof Array) { | ||
// json feed only supports 1 author per post | ||
author = author[0]; | ||
} | ||
feedItem.author = {}; | ||
if (author.name) { | ||
feedItem.author.name = author.name; | ||
} | ||
if (author.link) { | ||
feedItem.author.url = author.link; | ||
} | ||
} | ||
return feedItem; | ||
}); | ||
return JSON.stringify(feed, null, 4); | ||
} | ||
ISODateString(d) { | ||
@@ -406,2 +493,2 @@ function pad(n) { | ||
module.exports = Feed | ||
module.exports = Feed |
@@ -14,2 +14,3 @@ import Feed from './feed' | ||
updated: sampleDate, // optional, default = today | ||
generator: 'awesome', // optional, default = 'Feed for Node.js' | ||
@@ -67,3 +68,3 @@ author: { | ||
<docs>http://blogs.law.harvard.edu/tech/rss</docs> | ||
<generator>Feed for Node.js</generator> | ||
<generator>awesome</generator> | ||
<image> | ||
@@ -99,3 +100,3 @@ <title>Feed Title</title> | ||
<updated>2013-07-13T23:00:00Z</updated> | ||
<generator>Feed for Node.js</generator> | ||
<generator>awesome</generator> | ||
<author> | ||
@@ -151,2 +152,32 @@ <name>John Doe</name> | ||
expect(actual).toBe(expected) | ||
}); | ||
}); | ||
test('it should generate a JSON v1 Feed', () => { | ||
let expected = { | ||
"author": { | ||
"name": "John Doe", | ||
"url": "https://example.com/johndoe" | ||
}, | ||
"description": "This is my personnal feed!", | ||
"home_page_url": "http://example.com/", | ||
"icon": "http://example.com/image.png", | ||
"items": [{ | ||
"author": { | ||
"name": "Jane Doe", | ||
"url": "https://example.com/janedoe" | ||
}, | ||
"date_modified": "2013-07-13T23:00:00Z", | ||
"id": "https://example.com/hello-world", | ||
"image": "https://example.com/hello-world.jpg", | ||
"summary": "This is an article about Hello World.", | ||
"title": "Hello World", | ||
"url": "https://example.com/hello-world" | ||
}], | ||
"title": "Feed Title", | ||
"version": "https://jsonfeed.org/version/1" | ||
}; | ||
let actual = JSON.parse(feed.json1()); | ||
expect(actual).toEqual(expected) | ||
}); |
@@ -15,2 +15,3 @@ var assert = require("assert"), | ||
updated: new Date('Sat, 13 Jul 2013 23:00:00 GMT'), // optional, default = today | ||
generator: 'awesome', // optional, default = 'Feed for Node.js' | ||
@@ -40,3 +41,3 @@ author: { | ||
output += ' <copyright>All rights reserved 2013, John Doe</copyright>\n'; | ||
output += ' <generator>Feed for Node.js</generator>\n'; | ||
output += ' <generator>awesome</generator>\n'; | ||
output += ' </channel>\n'; | ||
@@ -50,2 +51,2 @@ output += '</rss>'; | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
76140
15
1022
139
5
Updatedxml@^1.0.1