1- /// <reference path="types/index.ts" />
2-
3- import * as xml from "xml" ;
41import { 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
86export 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
142157const 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} ;
0 commit comments