Skip to content

Commit 0ef496c

Browse files
committed
.
0 parents  commit 0ef496c

File tree

14 files changed

+2310
-0
lines changed

14 files changed

+2310
-0
lines changed

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 2
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true

.github/workflows/main.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: main
2+
on:
3+
- pull_request
4+
- push
5+
jobs:
6+
main:
7+
name: ${{matrix.node}}
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v2
11+
- uses: dcodeIO/setup-node-nvm@master
12+
with:
13+
node-version: ${{matrix.node}}
14+
- run: npm install
15+
- run: npm test
16+
- uses: codecov/codecov-action@v1
17+
strategy:
18+
matrix:
19+
node:
20+
- lts/erbium
21+
- node

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.DS_Store
2+
*.log
3+
coverage/
4+
node_modules/
5+
yarn.lock

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false

.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
coverage/
2+
*.json
3+
*.md

example.mjs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {rss} from './index.mjs'
2+
import toXml from 'xast-util-to-xml'
3+
4+
var tree = rss(
5+
{
6+
title: 'NYT > Top Stories',
7+
url: 'https://www.nytimes.com',
8+
feedUrl: 'https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml',
9+
lang: 'en',
10+
author: 'The New York Times Company'
11+
},
12+
[
13+
{
14+
title: 'Senate Balances Impeachment Trial With an Incoming President',
15+
url:
16+
'https://www.nytimes.com/2021/01/14/us/politics/impeachment-senate-trial-trump.html',
17+
description: 'Senate leaders etc etc etc.',
18+
author: 'Nicholas Fandos and Catie Edmondson',
19+
published: 'Fri, 15 Jan 2021 01:18:49 +0000',
20+
tags: ['Senate', 'Murkowski, Lisa', 'Trump, Donald J']
21+
}
22+
]
23+
)
24+
25+
console.log(toXml(tree))

index.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export {rss} from './lib/rss.mjs'
2+
export {atom} from './lib/atom.mjs'

lib/atom.mjs

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import u from 'unist-builder'
2+
import x from 'xastscript'
3+
import bcp47 from 'bcp-47-normalize'
4+
import {toAuthor} from './util.mjs'
5+
6+
export function atom(channel, data) {
7+
var now = new Date()
8+
var meta = channel || {}
9+
var items = []
10+
var index = -1
11+
var offset
12+
var children
13+
var datum
14+
var value
15+
16+
if (meta.title == null) throw new Error('Expected `channel.title` to be set')
17+
if (meta.url == null) throw new Error('Expected `channel.url` to be set')
18+
19+
items.push(x('title', String(meta.title)))
20+
items.push(x('subtitle', String(meta.description || '')))
21+
value = new URL(meta.url).href
22+
// `rel: 'alternate'` is the default.
23+
items.push(x('link', value))
24+
items.push(x('id', value))
25+
items.push(x('updated', now.toGMTString()))
26+
27+
if (meta.feedUrl) {
28+
items.push(
29+
x('link', {
30+
href: new URL(meta.feedUrl).href,
31+
rel: 'self',
32+
type: 'application/atom+xml'
33+
})
34+
)
35+
}
36+
37+
if (meta.author) {
38+
value = toAuthor(meta.author)
39+
items.push(
40+
x('rights', '© ' + now.getUTCFullYear() + ' ' + value.name),
41+
createAuthor(value)
42+
)
43+
}
44+
45+
if (meta.tags) {
46+
offset = -1
47+
while (++offset < meta.tags.length) {
48+
items.push(x('category', {term: String(meta.tags[offset])}))
49+
}
50+
}
51+
52+
if (data) {
53+
while (++index < data.length) {
54+
datum = data[index]
55+
children = []
56+
57+
if (!datum.title && !datum.description && !datum.descriptionHtml) {
58+
throw new Error(
59+
'Expected either `title` or `description` to be set in entry `' +
60+
index +
61+
'`'
62+
)
63+
}
64+
65+
if (datum.title) children.push(x('title', String(datum.title)))
66+
67+
if (datum.author) {
68+
children.push(createAuthor(toAuthor(datum.author)))
69+
} else if (!meta.author) {
70+
throw new Error(
71+
'Expected `author` to be set in entry `' +
72+
index +
73+
'` or in the channel'
74+
)
75+
}
76+
77+
if (datum.url) {
78+
value = new URL(datum.url).href
79+
children.push(x('link', {href: value}))
80+
children.push(x('id', value))
81+
}
82+
83+
value = datum.published
84+
85+
if (value != null) {
86+
if (typeof value !== 'object') value = new Date(value)
87+
children.push(x('published', value.toISOString()))
88+
}
89+
90+
value = datum.modified
91+
92+
if (value != null) {
93+
if (typeof value !== 'object') value = new Date(value)
94+
children.push(x('updated', value.toISOString()))
95+
}
96+
97+
if (datum.tags) {
98+
offset = -1
99+
while (++offset < datum.tags.length) {
100+
items.push(x('category', {term: String(datum.tags[offset])}))
101+
}
102+
}
103+
104+
value = datum.enclosure
105+
106+
if (value) {
107+
if (!value.url) {
108+
throw new Error(
109+
'Expected either `enclosure.url` to be set in entry `' + index + '`'
110+
)
111+
}
112+
113+
if (!value.size) {
114+
throw new Error(
115+
'Expected either `enclosure.size` to be set in entry `' +
116+
index +
117+
'`'
118+
)
119+
}
120+
121+
if (!value.type) {
122+
throw new Error(
123+
'Expected either `enclosure.type` to be set in entry `' +
124+
index +
125+
'`'
126+
)
127+
}
128+
129+
// Can’t use `xastscript` because of `length`
130+
children.push({
131+
type: 'element',
132+
name: 'link',
133+
attributes: {
134+
rel: 'enclosure',
135+
href: new URL(value.url).href,
136+
length: String(value.size),
137+
type: value.type
138+
},
139+
children: []
140+
})
141+
}
142+
143+
if (datum.descriptionHtml || datum.description) {
144+
children.push(
145+
x(
146+
'content',
147+
// `type: "text"` is the default.
148+
{type: datum.descriptionHtml ? 'html' : undefined},
149+
String(datum.descriptionHtml || datum.description)
150+
)
151+
)
152+
}
153+
154+
items.push(x('entry', children))
155+
}
156+
}
157+
158+
return u('root', [
159+
u('instruction', {name: 'xml'}, 'version="1.0" encoding="utf-8"'),
160+
x(
161+
'feed',
162+
{
163+
xmlns: 'http://www.w3.org/2005/Atom',
164+
'xml:lang': meta.lang ? bcp47(meta.lang) : undefined
165+
},
166+
items
167+
)
168+
])
169+
}
170+
171+
function createAuthor(value) {
172+
return x('author', [
173+
x('name', String(value.name)),
174+
value.email ? x('email', String(value.email)) : undefined,
175+
value.url ? x('uri', new URL(value.url).href) : undefined
176+
])
177+
}

0 commit comments

Comments
 (0)