@rspress/plugin-rss 1.41.0 → 1.41.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +265 -289
- package/dist/index.d.ts +156 -141
- package/dist/index.mjs +212 -247
- package/package.json +8 -9
- package/dist/index.cjs.map +0 -1
- package/dist/index.mjs.map +0 -1
package/dist/index.mjs
CHANGED
@@ -1,277 +1,242 @@
|
|
1
|
-
|
2
|
-
import
|
3
|
-
import
|
4
|
-
import
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
var PluginComponents = {
|
9
|
-
FeedsAnnotations: "@rspress/plugin-rss/FeedsAnnotations"
|
1
|
+
import * as __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__ from "node:path";
|
2
|
+
import * as __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__ from "node:url";
|
3
|
+
import * as __WEBPACK_EXTERNAL_MODULE_feed__ from "feed";
|
4
|
+
import * as __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__ from "node:fs";
|
5
|
+
const PluginName = '@rspress/plugin-rss';
|
6
|
+
const PluginComponents = {
|
7
|
+
FeedsAnnotations: '@rspress/plugin-rss/FeedsAnnotations'
|
10
8
|
};
|
11
|
-
|
12
|
-
// src/feed.ts
|
13
|
-
import { resolve as resolveUrl } from "url";
|
14
|
-
|
15
|
-
// src/internals/lang.ts
|
16
9
|
function notNullish(n) {
|
17
|
-
|
10
|
+
return null != n;
|
18
11
|
}
|
19
12
|
function concatArray(...arrList) {
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
);
|
13
|
+
return arrList.reduce((arr, item)=>arr.concat((Array.isArray(item) ? item : [
|
14
|
+
item
|
15
|
+
]).filter(notNullish)), []);
|
24
16
|
}
|
25
17
|
function selectNonNullishProperty(...list) {
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
return `${item}`;
|
33
|
-
if (typeof item === "string")
|
34
|
-
return item;
|
35
|
-
}
|
18
|
+
for (const item of list){
|
19
|
+
if ('' === item) return '';
|
20
|
+
if (0 === item) return '0';
|
21
|
+
if ('number' == typeof item) return `${item}`;
|
22
|
+
if ('string' == typeof item) return item;
|
23
|
+
}
|
36
24
|
}
|
37
25
|
function toDate(s) {
|
38
|
-
|
39
|
-
|
26
|
+
const d = new Date(s);
|
27
|
+
return Number.isNaN(d.getDate()) ? null : d;
|
40
28
|
}
|
41
29
|
function sortByDate(l, r) {
|
42
|
-
|
30
|
+
return (r ? r.getTime() : 0) - (l ? l.getTime() : 0);
|
43
31
|
}
|
44
|
-
|
45
|
-
// src/internals/node.ts
|
46
|
-
import { promises } from "fs";
|
47
|
-
import * as NodePath from "path";
|
48
32
|
async function writeFile(path, content) {
|
49
|
-
|
50
|
-
|
51
|
-
|
33
|
+
const dir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.dirname(path);
|
34
|
+
await __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.promises.mkdir(dir, {
|
35
|
+
mode: 493,
|
36
|
+
recursive: true
|
37
|
+
});
|
38
|
+
return __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.promises.writeFile(path, content);
|
52
39
|
}
|
53
|
-
|
54
|
-
// src/feed.ts
|
55
40
|
function generateFeedItem(page, siteUrl) {
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
(cat) => ({ name: cat })
|
70
|
-
)
|
71
|
-
};
|
41
|
+
const { frontmatter: fm } = page;
|
42
|
+
return {
|
43
|
+
id: selectNonNullishProperty(fm.slug, fm.id, page.id) || '',
|
44
|
+
title: selectNonNullishProperty(fm.title, page.title) || '',
|
45
|
+
author: toAuthors(fm.author),
|
46
|
+
link: (0, __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__.resolve)(siteUrl, selectNonNullishProperty(fm.permalink, page.routePath) || ''),
|
47
|
+
description: selectNonNullishProperty(fm.description) || '',
|
48
|
+
content: selectNonNullishProperty(fm.summary, page._html) || '',
|
49
|
+
date: toDate(fm.date || fm.published_at),
|
50
|
+
category: concatArray(fm.categories, fm.category).map((cat)=>({
|
51
|
+
name: cat
|
52
|
+
}))
|
53
|
+
};
|
72
54
|
}
|
73
55
|
function createFeed(options, config) {
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
56
|
+
var _config_themeConfig_footer, _config_themeConfig;
|
57
|
+
const { output, item, id, title, ..._options } = options;
|
58
|
+
return {
|
59
|
+
id,
|
60
|
+
copyright: (null === (_config_themeConfig = config.themeConfig) || void 0 === _config_themeConfig ? void 0 : null === (_config_themeConfig_footer = _config_themeConfig.footer) || void 0 === _config_themeConfig_footer ? void 0 : _config_themeConfig_footer.message) || '',
|
61
|
+
description: config.description || '',
|
62
|
+
link: output.url,
|
63
|
+
..._options,
|
64
|
+
title: title || config.title || ''
|
65
|
+
};
|
83
66
|
}
|
84
67
|
function toAuthors(author) {
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
68
|
+
const authors = (Array.isArray(author) ? author : [
|
69
|
+
author
|
70
|
+
]).filter(Boolean).map((author)=>({
|
71
|
+
...'string' == typeof author ? {
|
72
|
+
name: author
|
73
|
+
} : author
|
74
|
+
}));
|
75
|
+
return authors.length ? authors : void 0;
|
90
76
|
}
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
}
|
106
|
-
if (test instanceof RegExp) {
|
107
|
-
return [routePath, pureRoutePath].some((path) => test.test(path));
|
108
|
-
}
|
109
|
-
throw new Error(
|
110
|
-
"test must be of `RegExp` or `string` or `(page: PageIndexInfo, base: string) => boolean`"
|
111
|
-
);
|
77
|
+
function testPage(test, page, base = '/') {
|
78
|
+
if (Array.isArray(test)) return test.some((item)=>testPage(item, page, base));
|
79
|
+
if ('function' == typeof test) return test(page, base);
|
80
|
+
const routePath = page.routePath;
|
81
|
+
const pureRoutePath = `/${routePath.startsWith(base) ? routePath.slice(base.length) : routePath}`.replace(/^\/+/, '/');
|
82
|
+
if ('string' == typeof test) return [
|
83
|
+
routePath,
|
84
|
+
pureRoutePath
|
85
|
+
].some((path)=>path.startsWith(test));
|
86
|
+
if (test instanceof RegExp) return [
|
87
|
+
routePath,
|
88
|
+
pureRoutePath
|
89
|
+
].some((path)=>test.test(path));
|
90
|
+
throw new Error('test must be of `RegExp` or `string` or `(page: PageIndexInfo, base: string) => boolean`');
|
112
91
|
}
|
113
92
|
function getDefaultFeedOption() {
|
114
|
-
|
93
|
+
return {
|
94
|
+
id: 'blog',
|
95
|
+
test: '/blog/'
|
96
|
+
};
|
115
97
|
}
|
116
98
|
function getFeedFileType(type) {
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
99
|
+
switch(type){
|
100
|
+
case 'rss':
|
101
|
+
return {
|
102
|
+
extension: 'rss',
|
103
|
+
mime: 'application/rss+xml',
|
104
|
+
getContent: (feed)=>feed.rss2()
|
105
|
+
};
|
106
|
+
case 'json':
|
107
|
+
return {
|
108
|
+
extension: 'json',
|
109
|
+
mime: 'application/json',
|
110
|
+
getContent: (feed)=>feed.json1()
|
111
|
+
};
|
112
|
+
case 'atom':
|
113
|
+
default:
|
114
|
+
return {
|
115
|
+
extension: 'xml',
|
116
|
+
mime: 'application/atom+xml',
|
117
|
+
getContent: (feed)=>feed.atom1()
|
118
|
+
};
|
119
|
+
}
|
138
120
|
}
|
139
|
-
function getOutputInfo({ id, output }, {
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
(u, part)
|
150
|
-
|
151
|
-
|
152
|
-
|
121
|
+
function getOutputInfo({ id, output }, { siteUrl, output: globalOutput }) {
|
122
|
+
const type = (null == output ? void 0 : output.type) || (null == globalOutput ? void 0 : globalOutput.type) || 'atom';
|
123
|
+
const { extension, mime, getContent } = getFeedFileType(type);
|
124
|
+
const filename = (null == output ? void 0 : output.filename) || `${id}.${extension}`;
|
125
|
+
const dir = (null == output ? void 0 : output.dir) || (null == globalOutput ? void 0 : globalOutput.dir) || 'rss';
|
126
|
+
const publicPath = (null == output ? void 0 : output.publicPath) || (null == globalOutput ? void 0 : globalOutput.publicPath) || siteUrl;
|
127
|
+
const url = [
|
128
|
+
publicPath,
|
129
|
+
`${dir}/`,
|
130
|
+
filename
|
131
|
+
].reduce((u, part)=>u ? (0, __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__.resolve)(u, part) : part);
|
132
|
+
const sorting = (null == output ? void 0 : output.sorting) || (null == globalOutput ? void 0 : globalOutput.sorting) || ((l, r)=>sortByDate(l.date, r.date));
|
133
|
+
return {
|
134
|
+
type,
|
135
|
+
mime,
|
136
|
+
filename,
|
137
|
+
getContent,
|
138
|
+
dir,
|
139
|
+
publicPath,
|
140
|
+
url,
|
141
|
+
sorting
|
142
|
+
};
|
153
143
|
}
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
144
|
+
class FeedsSet {
|
145
|
+
set({ feed, output, siteUrl }, config) {
|
146
|
+
this.feeds = (Array.isArray(feed) ? feed : [
|
147
|
+
{
|
148
|
+
...getDefaultFeedOption(),
|
149
|
+
...feed
|
150
|
+
}
|
151
|
+
]).map((options)=>{
|
152
|
+
var _config_themeConfig_footer, _config_themeConfig;
|
153
|
+
return {
|
154
|
+
title: config.title || '',
|
155
|
+
description: config.description || '',
|
156
|
+
favicon: config.icon && (0, __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__.resolve)(siteUrl, config.icon),
|
157
|
+
copyright: (null === (_config_themeConfig = config.themeConfig) || void 0 === _config_themeConfig ? void 0 : null === (_config_themeConfig_footer = _config_themeConfig.footer) || void 0 === _config_themeConfig_footer ? void 0 : _config_themeConfig_footer.message) || '',
|
158
|
+
link: siteUrl,
|
159
|
+
docs: '',
|
160
|
+
...options,
|
161
|
+
output: getOutputInfo(options, {
|
162
|
+
siteUrl,
|
163
|
+
output
|
164
|
+
})
|
165
|
+
};
|
166
|
+
});
|
167
|
+
this.feedsMapById = this.feeds.reduce((m, f)=>({
|
168
|
+
...m,
|
169
|
+
[f.id]: f
|
170
|
+
}), Object.create(null));
|
171
|
+
}
|
172
|
+
get(id) {
|
173
|
+
if (id) return this.feedsMapById[id] || null;
|
174
|
+
return this.feeds.slice(0);
|
175
|
+
}
|
176
|
+
constructor(){
|
177
|
+
this.feeds = [];
|
178
|
+
this.feedsMapById = Object.create(null);
|
180
179
|
}
|
181
|
-
return this.feeds.slice(0);
|
182
|
-
}
|
183
|
-
};
|
184
|
-
function getRssItems(feeds, page, config, siteUrl) {
|
185
|
-
return Promise.all(
|
186
|
-
feeds.filter((options) => testPage(options.test, page, config.base)).map(async (options) => {
|
187
|
-
const after = options.item || ((feed) => feed);
|
188
|
-
const item = await after(
|
189
|
-
generateFeedItem(page, siteUrl),
|
190
|
-
page,
|
191
|
-
siteUrl
|
192
|
-
);
|
193
|
-
return { ...item, channel: options.id };
|
194
|
-
})
|
195
|
-
);
|
196
180
|
}
|
197
|
-
function
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
return {
|
202
|
-
name: PluginName,
|
203
|
-
globalUIComponents: Object.values(PluginComponents),
|
204
|
-
beforeBuild(config, isProd) {
|
205
|
-
if (!isProd) {
|
206
|
-
_rssWorkaround = null;
|
207
|
-
return;
|
208
|
-
}
|
209
|
-
_rssWorkaround = {};
|
210
|
-
_config = config;
|
211
|
-
feedsSet.set(pluginRssOptions, config);
|
212
|
-
},
|
213
|
-
async extendPageData(_pageData) {
|
214
|
-
if (!_rssWorkaround)
|
215
|
-
return;
|
216
|
-
const pageData = _pageData;
|
217
|
-
_rssWorkaround[pageData.id] = _rssWorkaround[pageData.id] || getRssItems(
|
218
|
-
feedsSet.get(),
|
219
|
-
pageData,
|
220
|
-
_config,
|
221
|
-
pluginRssOptions.siteUrl
|
222
|
-
);
|
223
|
-
const feeds = await _rssWorkaround[pageData.id];
|
224
|
-
const showRssList = new Set(
|
225
|
-
concatArray(pageData.frontmatter["link-rss"])
|
226
|
-
);
|
227
|
-
for (const feed of feeds) {
|
228
|
-
showRssList.add(feed.channel);
|
229
|
-
}
|
230
|
-
pageData.feeds = Array.from(showRssList, (id) => {
|
231
|
-
const { output, language } = feedsSet.get(id);
|
181
|
+
function getRssItems(feeds, page, config, siteUrl) {
|
182
|
+
return Promise.all(feeds.filter((options)=>testPage(options.test, page, config.base)).map(async (options)=>{
|
183
|
+
const after = options.item || ((feed)=>feed);
|
184
|
+
const item = await after(generateFeedItem(page, siteUrl), page, siteUrl);
|
232
185
|
return {
|
233
|
-
|
234
|
-
|
235
|
-
language: language || pageData.lang
|
186
|
+
...item,
|
187
|
+
channel: options.id
|
236
188
|
};
|
237
|
-
|
238
|
-
},
|
239
|
-
async afterBuild(config) {
|
240
|
-
if (!_rssWorkaround)
|
241
|
-
return;
|
242
|
-
const items = concatArray(
|
243
|
-
...await Promise.all(Object.values(_rssWorkaround))
|
244
|
-
);
|
245
|
-
const feeds = /* @__PURE__ */ Object.create(null);
|
246
|
-
for (const { channel, ...item } of items) {
|
247
|
-
feeds[channel] = feeds[channel] || new Feed(createFeed(feedsSet.get(channel), config));
|
248
|
-
feeds[channel].addItem(item);
|
249
|
-
}
|
250
|
-
for (const [channel, feed] of Object.entries(feeds)) {
|
251
|
-
const { output } = feedsSet.get(channel);
|
252
|
-
feed.items.sort(output.sorting);
|
253
|
-
const path = NodePath2.resolve(
|
254
|
-
config.outDir || "doc_build",
|
255
|
-
output.dir,
|
256
|
-
output.filename
|
257
|
-
);
|
258
|
-
await writeFile(path, output.getContent(feed));
|
259
|
-
}
|
260
|
-
_rssWorkaround = null;
|
261
|
-
_config = null;
|
262
|
-
}
|
263
|
-
};
|
189
|
+
}));
|
264
190
|
}
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
191
|
+
function pluginRss(pluginRssOptions) {
|
192
|
+
const feedsSet = new FeedsSet();
|
193
|
+
let _rssWorkaround = null;
|
194
|
+
let _config;
|
195
|
+
return {
|
196
|
+
name: PluginName,
|
197
|
+
globalUIComponents: Object.values(PluginComponents),
|
198
|
+
beforeBuild (config, isProd) {
|
199
|
+
if (!isProd) {
|
200
|
+
_rssWorkaround = null;
|
201
|
+
return;
|
202
|
+
}
|
203
|
+
_rssWorkaround = {};
|
204
|
+
_config = config;
|
205
|
+
feedsSet.set(pluginRssOptions, config);
|
206
|
+
},
|
207
|
+
async extendPageData (_pageData) {
|
208
|
+
if (!_rssWorkaround) return;
|
209
|
+
const pageData = _pageData;
|
210
|
+
_rssWorkaround[pageData.id] = _rssWorkaround[pageData.id] || getRssItems(feedsSet.get(), pageData, _config, pluginRssOptions.siteUrl);
|
211
|
+
const feeds = await _rssWorkaround[pageData.id];
|
212
|
+
const showRssList = new Set(concatArray(pageData.frontmatter['link-rss']));
|
213
|
+
for (const feed of feeds)showRssList.add(feed.channel);
|
214
|
+
pageData.feeds = Array.from(showRssList, (id)=>{
|
215
|
+
const { output, language } = feedsSet.get(id);
|
216
|
+
return {
|
217
|
+
url: output.url,
|
218
|
+
mime: output.mime,
|
219
|
+
language: language || pageData.lang
|
220
|
+
};
|
221
|
+
});
|
222
|
+
},
|
223
|
+
async afterBuild (config) {
|
224
|
+
if (!_rssWorkaround) return;
|
225
|
+
const items = concatArray(...await Promise.all(Object.values(_rssWorkaround)));
|
226
|
+
const feeds = Object.create(null);
|
227
|
+
for (const { channel, ...item } of items){
|
228
|
+
feeds[channel] = feeds[channel] || new __WEBPACK_EXTERNAL_MODULE_feed__.Feed(createFeed(feedsSet.get(channel), config));
|
229
|
+
feeds[channel].addItem(item);
|
230
|
+
}
|
231
|
+
for (const [channel, feed] of Object.entries(feeds)){
|
232
|
+
const { output } = feedsSet.get(channel);
|
233
|
+
feed.items.sort(output.sorting);
|
234
|
+
const path = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].resolve(config.outDir || 'doc_build', output.dir, output.filename);
|
235
|
+
await writeFile(path, output.getContent(feed));
|
236
|
+
}
|
237
|
+
_rssWorkaround = null;
|
238
|
+
_config = null;
|
239
|
+
}
|
240
|
+
};
|
241
|
+
}
|
242
|
+
export { PluginComponents, PluginName, createFeed, generateFeedItem, getDefaultFeedOption, getFeedFileType, getOutputInfo, pluginRss, testPage };
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@rspress/plugin-rss",
|
3
|
-
"version": "1.41.
|
3
|
+
"version": "1.41.2",
|
4
4
|
"description": "A plugin for rss generation for rspress",
|
5
5
|
"bugs": "https://github.com/web-infra-dev/rspress/issues",
|
6
6
|
"repository": {
|
@@ -26,19 +26,19 @@
|
|
26
26
|
],
|
27
27
|
"dependencies": {
|
28
28
|
"feed": "^4.2.2",
|
29
|
-
"@rspress/shared": "1.41.
|
29
|
+
"@rspress/shared": "1.41.2"
|
30
30
|
},
|
31
31
|
"devDependencies": {
|
32
|
+
"@rslib/core": "0.4.1",
|
32
33
|
"@types/node": "^18.11.17",
|
33
34
|
"@types/react": "^18.3.18",
|
34
35
|
"react": "^18.3.1",
|
35
36
|
"typescript": "^5.5.3",
|
36
|
-
"
|
37
|
-
"@rspress/runtime": "1.41.0"
|
37
|
+
"@rspress/runtime": "1.41.2"
|
38
38
|
},
|
39
39
|
"peerDependencies": {
|
40
40
|
"react": ">=17.0.0",
|
41
|
-
"rspress": "^1.41.
|
41
|
+
"rspress": "^1.41.2"
|
42
42
|
},
|
43
43
|
"engines": {
|
44
44
|
"node": ">=14.17.6"
|
@@ -50,9 +50,8 @@
|
|
50
50
|
},
|
51
51
|
"jsnext:source": "./src/index.ts",
|
52
52
|
"scripts": {
|
53
|
-
"build": "
|
54
|
-
"dev": "
|
55
|
-
"reset": "rimraf ./**/node_modules"
|
56
|
-
"test": "vitest run --passWithNoTests"
|
53
|
+
"build": "rslib build",
|
54
|
+
"dev": "rslib build -w",
|
55
|
+
"reset": "rimraf ./**/node_modules"
|
57
56
|
}
|
58
57
|
}
|
package/dist/index.cjs.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,uBAAqB;AACrB,IAAAA,mBAAsC;AAEtC,kBAAqB;;;ACHd,IAAM,aAAa;AAEnB,IAAM,mBAAmB;AAAA,EAC9B,kBAAkB;AACpB;;;ACJA,sBAAsC;;;ACK/B,SAAS,WAAc,GAAiC;AAC7D,SAAO,MAAM,UAAa,MAAM;AAClC;AACO,SAAS,eAAkB,SAAkC;AAClE,SAAO,QAAQ;AAAA,IACb,CAAC,KAAK,SACJ,IAAI,QAAQ,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI,GAAG,OAAO,UAAU,CAAC;AAAA,IACrE,CAAC;AAAA,EACH;AACF;AAEO,SAAS,4BAA4B,MAAiB;AAC3D,aAAW,QAAQ,MAAM;AACvB,QAAI,SAAS;AAAI,aAAO;AACxB,QAAI,SAAS;AAAG,aAAO;AACvB,QAAI,OAAO,SAAS;AAAU,aAAO,GAAG,IAAI;AAC5C,QAAI,OAAO,SAAS;AAAU,aAAO;AAAA,EACvC;AACF;AAEO,SAAS,OAAO,GAA+B;AACpD,QAAM,IAAI,IAAI,KAAK,CAAC;AACpB,SAAO,OAAO,MAAM,EAAE,QAAQ,CAAC,IAAI,OAAO;AAC5C;AAEO,SAAS,WAAW,GAAgB,GAAwB;AACjE,UAAQ,IAAI,EAAE,QAAQ,IAAI,MAAM,IAAI,EAAE,QAAQ,IAAI;AACpD;;;AChCA,qBAAyB;AACzB,eAA0B;AAE1B,eAAsB,UACpB,MACA,SACA;AACA,QAAM,MAAe,iBAAQ,IAAI;AACjC,QAAM,wBAAS,MAAM,KAAK,EAAE,MAAM,KAAO,WAAW,KAAK,CAAC;AAC1D,SAAO,wBAAS,UAAU,MAAM,OAAO;AACzC;;;AFMO,SAAS,iBAAiB,MAAqB,SAAiB;AACrE,QAAM,EAAE,aAAa,GAAG,IAAI;AAC5B,SAAO;AAAA,IACL,IAAI,yBAAyB,GAAG,MAAM,GAAG,IAAI,KAAK,EAAE,KAAK;AAAA,IACzD,OAAO,yBAAyB,GAAG,OAAO,KAAK,KAAK,KAAK;AAAA,IACzD,QAAQ,UAAU,GAAG,MAAM;AAAA,IAC3B,UAAM,gBAAAC;AAAA,MACJ;AAAA,MACA,yBAAyB,GAAG,WAAW,KAAK,SAAS,KAAK;AAAA,IAC5D;AAAA,IACA,aAAa,yBAAyB,GAAG,WAAW,KAAK;AAAA,IACzD,SAAS,yBAAyB,GAAG,SAAS,KAAK,KAAK,KAAK;AAAA,IAC7D,MAAM,OAAQ,GAAG,QAAoB,GAAG,YAAuB;AAAA,IAC/D,UAAU,YAAY,GAAG,YAAwB,GAAG,QAAkB,EAAE;AAAA,MACtE,UAAQ,EAAE,MAAM,IAAI;AAAA,IACtB;AAAA,EACF;AACF;AAEO,SAAS,WACd,SAKA,QACa;AACb,QAAM,EAAE,QAAQ,MAAM,IAAI,OAAO,GAAG,SAAS,IAAI;AACjD,SAAO;AAAA,IACL;AAAA,IACA,WAAW,OAAO,aAAa,QAAQ,WAAW;AAAA,IAClD,aAAa,OAAO,eAAe;AAAA,IACnC,MAAM,OAAO;AAAA,IACb,GAAG;AAAA,IACH,OAAO,SAAS,OAAO,SAAS;AAAA,EAClC;AACF;AAEA,SAAS,UAAU,QAAuC;AACxD,QAAM,WAAW,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM,GACtD,OAAO,OAAO,EACd,IAAI,CAAAC,aAAW;AAAA;AAAA,IAEd,GAAI,OAAOA,YAAW,WAAW,EAAE,MAAMA,QAAO,IAAIA;AAAA,EACtD,EAAE;AACJ,SAAO,QAAQ,SAAS,UAAU;AACpC;;;AG9DA,IAAAF,mBAAsC;AAM/B,SAAS,SACd,MACA,MACA,OAAO,KACE;AACT,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO,KAAK,KAAK,UAAQ,SAAS,MAAM,MAAM,IAAI,CAAC;AAAA,EACrD;AACA,MAAI,OAAO,SAAS,YAAY;AAC9B,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AACA,QAAM,YAAY,KAAK;AACvB,QAAM,gBAAgB,IACpB,UAAU,WAAW,IAAI,IAAI,UAAU,MAAM,KAAK,MAAM,IAAI,SAC9D,GAAG,QAAQ,QAAQ,GAAG;AACtB,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,CAAC,WAAW,aAAa,EAAE,KAAK,UAAQ,KAAK,WAAW,IAAI,CAAC;AAAA,EACtE;AACA,MAAI,gBAAgB,QAAQ;AAC1B,WAAO,CAAC,WAAW,aAAa,EAAE,KAAK,UAAQ,KAAK,KAAK,IAAI,CAAC;AAAA,EAChE;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAEO,SAAS,uBAAuB;AACrC,SAAO,EAAE,IAAI,QAAQ,MAAM,SAAS;AACtC;AAEO,SAAS,gBAAgB,MAAsB;AACpD,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,QACL,WAAW;AAAA,QACX,MAAM;AAAA,QACN,YAAY,CAAC,SAAe,KAAK,KAAK;AAAA,MACxC;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,WAAW;AAAA,QACX,MAAM;AAAA,QACN,YAAY,CAAC,SAAe,KAAK,MAAM;AAAA,MACzC;AAAA,IACF,KAAK;AAAA,IACL;AACE,aAAO;AAAA,QACL,WAAW;AAAA,QACX,MAAM;AAAA,QACN,YAAY,CAAC,SAAe,KAAK,MAAM;AAAA,MACzC;AAAA,EACJ;AACF;AACO,SAAS,cACd,EAAE,IAAI,OAAO,GACb;AAAA,EACE;AAAA,EACA,QAAQ;AACV,GACgB;AAChB,QAAM,OAAO,QAAQ,QAAQ,cAAc,QAAQ;AACnD,QAAM,EAAE,WAAW,MAAM,WAAW,IAAI,gBAAgB,IAAI;AAC5D,QAAM,WAAW,QAAQ,YAAY,GAAG,EAAE,IAAI,SAAS;AACvD,QAAM,MAAM,QAAQ,OAAO,cAAc,OAAO;AAChD,QAAM,aAAa,QAAQ,cAAc,cAAc,cAAc;AACrE,QAAM,MAAM,CAAC,YAAY,GAAG,GAAG,KAAK,QAAQ,EAAE;AAAA,IAAO,CAAC,GAAG,SACvD,QAAI,iBAAAC,SAAW,GAAG,IAAI,IAAI;AAAA,EAC5B;AACA,QAAM,UACJ,QAAQ,WACR,cAAc,YACb,CAAC,GAAG,MAAM,WAAW,EAAE,MAAM,EAAE,IAAI;AACtC,SAAO,EAAE,MAAM,MAAM,UAAU,YAAY,KAAK,YAAY,KAAK,QAAQ;AAC3E;;;AL7DA,IAAM,WAAN,MAAe;AAAA,EAAf;AACE,iBAAkC,CAAC;AACnC,wBAAuD,uBAAO,OAAO,IAAI;AAAA;AAAA,EACzE,IAAI,EAAE,MAAM,QAAQ,QAAQ,GAAqB,QAAoB;AACnE,SAAK,SACH,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,EAAE,GAAG,qBAAqB,GAAG,GAAG,KAAK,CAAC,GACpE,IAAI,cAAY;AAAA,MAChB,OAAO,OAAO,SAAS;AAAA,MACvB,aAAa,OAAO,eAAe;AAAA,MACnC,SAAS,OAAO,YAAQ,iBAAAA,SAAW,SAAS,OAAO,IAAI;AAAA,MACvD,WAAW,OAAO,aAAa,QAAQ,WAAW;AAAA,MAClD,MAAM;AAAA,MACN,MAAM;AAAA,MACN,GAAG;AAAA,MACH,QAAQ,cAAc,SAAS,EAAE,SAAS,OAAO,CAAC;AAAA,IACpD,EAAE;AAEF,SAAK,eAAe,KAAK,MAAM;AAAA,MAC7B,CAAC,GAAG,OAAO,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE;AAAA,MAC7B,uBAAO,OAAO,IAAI;AAAA,IACpB;AAAA,EACF;AAAA,EAGA,IAAI,IAAuE;AACzE,QAAI,IAAI;AACN,aAAO,KAAK,aAAa,EAAE,KAAK;AAAA,IAClC;AACA,WAAO,KAAK,MAAM,MAAM,CAAC;AAAA,EAC3B;AACF;AAEA,SAAS,YACP,OACA,MACA,QACA,SACgC;AAChC,SAAO,QAAQ;AAAA,IACb,MACG,OAAO,aAAW,SAAS,QAAQ,MAAM,MAAM,OAAO,IAAI,CAAC,EAC3D,IAAI,OAAM,YAAW;AACpB,YAAM,QAAQ,QAAQ,SAAS,CAAC,SAAmB;AACnD,YAAM,OAAO,MAAM;AAAA,QACjB,iBAAiB,MAAM,OAAO;AAAA,QAC9B;AAAA,QACA;AAAA,MACF;AACA,aAAO,EAAE,GAAG,MAAM,SAAS,QAAQ,GAAG;AAAA,IACxC,CAAC;AAAA,EACL;AACF;AAEO,SAAS,UAAU,kBAAmD;AAC3E,QAAM,WAAW,IAAI,SAAS;AAM9B,MAAI,iBAGA;AACJ,MAAI;AAEJ,SAAO;AAAA,IACL,MAAM;AAAA,IACN,oBAAoB,OAAO,OAAO,gBAAgB;AAAA,IAClD,YAAY,QAAQ,QAAQ;AAC1B,UAAI,CAAC,QAAQ;AACX,yBAAiB;AACjB;AAAA,MACF;AACA,uBAAiB,CAAC;AAClB,gBAAU;AACV,eAAS,IAAI,kBAAkB,MAAM;AAAA,IACvC;AAAA,IACA,MAAM,eAAe,WAAW;AAC9B,UAAI,CAAC;AAAgB;AAErB,YAAM,WAAW;AAIjB,qBAAe,SAAS,EAAE,IACxB,eAAe,SAAS,EAAE,KAC1B;AAAA,QACE,SAAS,IAAI;AAAA,QACb;AAAA,QACA;AAAA,QACA,iBAAiB;AAAA,MACnB;AAEF,YAAM,QAAQ,MAAM,eAAe,SAAS,EAAE;AAC9C,YAAM,cAAc,IAAI;AAAA,QACtB,YAAY,SAAS,YAAY,UAAU,CAAsB;AAAA,MACnE;AACA,iBAAW,QAAQ,OAAO;AACxB,oBAAY,IAAI,KAAK,OAAO;AAAA,MAC9B;AAEA,eAAS,QAAQ,MAAM,KAAK,aAAa,QAAM;AAC7C,cAAM,EAAE,QAAQ,SAAS,IAAI,SAAS,IAAI,EAAE;AAC5C,eAAO;AAAA,UACL,KAAK,OAAO;AAAA,UACZ,MAAM,OAAO;AAAA,UACb,UAAU,YAAY,SAAS;AAAA,QACjC;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,MAAM,WAAW,QAAQ;AACvB,UAAI,CAAC;AAAgB;AAErB,YAAM,QAAQ;AAAA,QACZ,GAAI,MAAM,QAAQ,IAAI,OAAO,OAAO,cAAc,CAAC;AAAA,MACrD;AACA,YAAM,QAA8B,uBAAO,OAAO,IAAI;AAEtD,iBAAW,EAAE,SAAS,GAAG,KAAK,KAAK,OAAO;AACxC,cAAM,OAAO,IACX,MAAM,OAAO,KACb,IAAI,iBAAK,WAAW,SAAS,IAAI,OAAO,GAAI,MAAM,CAAC;AACrD,cAAM,OAAO,EAAE,QAAQ,IAAI;AAAA,MAC7B;AAEA,iBAAW,CAAC,SAAS,IAAI,KAAK,OAAO,QAAQ,KAAK,GAAG;AACnD,cAAM,EAAE,OAAO,IAAI,SAAS,IAAI,OAAO;AACvC,aAAK,MAAM,KAAK,OAAO,OAAO;AAC9B,cAAM,OAAO,iBAAAE,QAAS;AAAA,UACpB,OAAO,UAAU;AAAA,UACjB,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AACA,cAAM,UAAU,MAAM,OAAO,WAAW,IAAI,CAAC;AAAA,MAC/C;AACA,uBAAiB;AACjB,gBAAU;AAAA,IACZ;AAAA,EACF;AACF","names":["import_node_url","resolveUrl","author","NodePath"],"ignoreList":[],"sources":["../src/index.ts","../src/plugin-rss.ts","../src/exports.ts","../src/feed.ts","../src/internals/lang.ts","../src/internals/node.ts","../src/options.ts"],"sourcesContent":["export * from './plugin-rss';\nexport * from './type';\nexport * from './exports';\nexport * from './options';\nexport * from './feed';\n","import NodePath from 'node:path';\nimport { resolve as resolveUrl } from 'node:url';\nimport type { PageIndexInfo, RspressPlugin, UserConfig } from '@rspress/shared';\nimport { Feed } from 'feed';\nimport { PluginComponents, PluginName } from './exports';\nimport { createFeed, generateFeedItem } from './feed';\n\nimport {\n type PageWithFeeds,\n type ResolvedOutput,\n concatArray,\n writeFile,\n} from './internals';\nimport { getDefaultFeedOption, getOutputInfo, testPage } from './options';\nimport type { FeedChannel, FeedItem, PluginRssOptions } from './type';\n\ntype FeedItemWithChannel = FeedItem & { channel: string };\ntype TransformedFeedChannel = FeedChannel & { output: ResolvedOutput };\n\nclass FeedsSet {\n feeds: TransformedFeedChannel[] = [];\n feedsMapById: Record<string, TransformedFeedChannel> = Object.create(null);\n set({ feed, output, siteUrl }: PluginRssOptions, config: UserConfig) {\n this.feeds = (\n Array.isArray(feed) ? feed : [{ ...getDefaultFeedOption(), ...feed }]\n ).map(options => ({\n title: config.title || '',\n description: config.description || '',\n favicon: config.icon && resolveUrl(siteUrl, config.icon),\n copyright: config.themeConfig?.footer?.message || '',\n link: siteUrl,\n docs: '',\n ...options,\n output: getOutputInfo(options, { siteUrl, output }),\n }));\n\n this.feedsMapById = this.feeds.reduce(\n (m, f) => ({ ...m, [f.id]: f }),\n Object.create(null),\n );\n }\n get(): TransformedFeedChannel[];\n get(id: string): TransformedFeedChannel | null;\n get(id?: string): TransformedFeedChannel[] | TransformedFeedChannel | null {\n if (id) {\n return this.feedsMapById[id] || null;\n }\n return this.feeds.slice(0);\n }\n}\n\nfunction getRssItems(\n feeds: TransformedFeedChannel[],\n page: PageIndexInfo,\n config: UserConfig,\n siteUrl: string,\n): Promise<FeedItemWithChannel[]> {\n return Promise.all(\n feeds\n .filter(options => testPage(options.test, page, config.base))\n .map(async options => {\n const after = options.item || ((feed: FeedItem) => feed);\n const item = await after(\n generateFeedItem(page, siteUrl),\n page,\n siteUrl,\n );\n return { ...item, channel: options.id };\n }),\n );\n}\n\nexport function pluginRss(pluginRssOptions: PluginRssOptions): RspressPlugin {\n const feedsSet = new FeedsSet();\n\n /**\n * workaround for retrieving data of pages in `afterBuild`\n * TODO: get pageData list directly in `afterBuild`\n **/\n let _rssWorkaround: null | Record<\n string,\n PromiseLike<FeedItemWithChannel[]>\n > = null;\n let _config: null | UserConfig;\n\n return {\n name: PluginName,\n globalUIComponents: Object.values(PluginComponents),\n beforeBuild(config, isProd) {\n if (!isProd) {\n _rssWorkaround = null;\n return;\n }\n _rssWorkaround = {};\n _config = config;\n feedsSet.set(pluginRssOptions, config);\n },\n async extendPageData(_pageData) {\n if (!_rssWorkaround) return;\n\n const pageData = _pageData as PageWithFeeds;\n\n // rspress run `extendPageData` for each page\n // - let's cache rss items within a complete rspress build\n _rssWorkaround[pageData.id] =\n _rssWorkaround[pageData.id] ||\n getRssItems(\n feedsSet.get(),\n pageData,\n _config!,\n pluginRssOptions.siteUrl,\n );\n\n const feeds = await _rssWorkaround[pageData.id];\n const showRssList = new Set(\n concatArray(pageData.frontmatter['link-rss'] as string[] | string),\n );\n for (const feed of feeds) {\n showRssList.add(feed.channel);\n }\n\n pageData.feeds = Array.from(showRssList, id => {\n const { output, language } = feedsSet.get(id)!;\n return {\n url: output.url,\n mime: output.mime,\n language: language || pageData.lang,\n };\n });\n },\n async afterBuild(config) {\n if (!_rssWorkaround) return;\n\n const items = concatArray(\n ...(await Promise.all(Object.values(_rssWorkaround))),\n );\n const feeds: Record<string, Feed> = Object.create(null);\n\n for (const { channel, ...item } of items) {\n feeds[channel] =\n feeds[channel] ||\n new Feed(createFeed(feedsSet.get(channel)!, config));\n feeds[channel].addItem(item);\n }\n\n for (const [channel, feed] of Object.entries(feeds)) {\n const { output } = feedsSet.get(channel)!;\n feed.items.sort(output.sorting);\n const path = NodePath.resolve(\n config.outDir || 'doc_build',\n output.dir,\n output.filename,\n );\n await writeFile(path, output.getContent(feed));\n }\n _rssWorkaround = null;\n _config = null;\n },\n };\n}\n","export const PluginName = '@rspress/plugin-rss';\n\nexport const PluginComponents = {\n FeedsAnnotations: '@rspress/plugin-rss/FeedsAnnotations',\n} as const;\n","import { resolve as resolveUrl } from 'node:url';\nimport type { PageIndexInfo, UserConfig } from '@rspress/shared';\nimport type { Author, FeedOptions } from 'feed';\nimport {\n type ResolvedOutput,\n concatArray,\n selectNonNullishProperty,\n toDate,\n} from './internals';\nimport type { FeedChannel, FeedItem } from './type';\n\n/**\n * @public\n * @param page Rspress Page Data\n * @param siteUrl\n */\nexport function generateFeedItem(page: PageIndexInfo, siteUrl: string) {\n const { frontmatter: fm } = page;\n return {\n id: selectNonNullishProperty(fm.slug, fm.id, page.id) || '',\n title: selectNonNullishProperty(fm.title, page.title) || '',\n author: toAuthors(fm.author),\n link: resolveUrl(\n siteUrl,\n selectNonNullishProperty(fm.permalink, page.routePath) || '',\n ),\n description: selectNonNullishProperty(fm.description) || '',\n content: selectNonNullishProperty(fm.summary, page._html) || '',\n date: toDate((fm.date as string) || (fm.published_at as string))!,\n category: concatArray(fm.categories as string[], fm.category as string).map(\n cat => ({ name: cat }),\n ),\n } satisfies FeedItem;\n}\n\nexport function createFeed(\n options: Omit<FeedChannel, 'test' | 'item' | 'output'> & {\n item?: any;\n test?: any;\n output: ResolvedOutput;\n },\n config: UserConfig,\n): FeedOptions {\n const { output, item, id, title, ..._options } = options;\n return {\n id,\n copyright: config.themeConfig?.footer?.message || '',\n description: config.description || '',\n link: output.url,\n ..._options,\n title: title || config.title || '',\n };\n}\n\nfunction toAuthors(author: unknown): Author[] | undefined {\n const authors = (Array.isArray(author) ? author : [author])\n .filter(Boolean)\n .map(author => ({\n // email is mandatory for RSS 2.0.\n ...(typeof author === 'string' ? { name: author } : author),\n }));\n return authors.length ? authors : undefined;\n}\n","export type PartialPartial<T, K extends keyof T> = Partial<Pick<T, K>> &\n Omit<T, K>;\n\nexport type ItemOf<T> = T extends Array<infer K> ? K : never;\n\nexport function notNullish<T>(n: T | undefined | null): n is T {\n return n !== undefined && n !== null;\n}\nexport function concatArray<T>(...arrList: (T[] | T | undefined)[]) {\n return arrList.reduce<T[]>(\n (arr, item) =>\n arr.concat((Array.isArray(item) ? item : [item]).filter(notNullish)),\n [] as T[],\n );\n}\n\nexport function selectNonNullishProperty(...list: unknown[]) {\n for (const item of list) {\n if (item === '') return '';\n if (item === 0) return '0';\n if (typeof item === 'number') return `${item}`;\n if (typeof item === 'string') return item;\n }\n}\n\nexport function toDate(s: string | Date): null | Date {\n const d = new Date(s);\n return Number.isNaN(d.getDate()) ? null : d;\n}\n\nexport function sortByDate(l: null | Date, r: null | Date): number {\n return (r ? r.getTime() : 0) - (l ? l.getTime() : 0);\n}\n","import { promises } from 'node:fs';\nimport * as NodePath from 'node:path';\n\nexport async function writeFile(\n path: string,\n content: Parameters<typeof promises.writeFile>[1],\n) {\n const dir = NodePath.dirname(path);\n await promises.mkdir(dir, { mode: 0o755, recursive: true });\n return promises.writeFile(path, content);\n}\n","import { resolve as resolveUrl } from 'node:url';\nimport type { PageIndexInfo } from '@rspress/shared';\nimport type { Feed } from 'feed';\nimport { type ResolvedOutput, sortByDate } from './internals';\nimport type { FeedChannel, FeedOutputType, PluginRssOptions } from './type';\n\nexport function testPage(\n test: FeedChannel['test'],\n page: PageIndexInfo,\n base = '/',\n): boolean {\n if (Array.isArray(test)) {\n return test.some(item => testPage(item, page, base));\n }\n if (typeof test === 'function') {\n return test(page, base);\n }\n const routePath = page.routePath;\n const pureRoutePath = `/${\n routePath.startsWith(base) ? routePath.slice(base.length) : routePath\n }`.replace(/^\\/+/, '/');\n if (typeof test === 'string') {\n return [routePath, pureRoutePath].some(path => path.startsWith(test));\n }\n if (test instanceof RegExp) {\n return [routePath, pureRoutePath].some(path => test.test(path));\n }\n\n throw new Error(\n 'test must be of `RegExp` or `string` or `(page: PageIndexInfo, base: string) => boolean`',\n );\n}\n\nexport function getDefaultFeedOption() {\n return { id: 'blog', test: '/blog/' } satisfies FeedChannel;\n}\n\nexport function getFeedFileType(type: FeedOutputType) {\n switch (type) {\n case 'rss':\n return {\n extension: 'rss',\n mime: 'application/rss+xml',\n getContent: (feed: Feed) => feed.rss2(),\n };\n case 'json':\n return {\n extension: 'json',\n mime: 'application/json',\n getContent: (feed: Feed) => feed.json1(),\n };\n case 'atom':\n default:\n return {\n extension: 'xml',\n mime: 'application/atom+xml',\n getContent: (feed: Feed) => feed.atom1(),\n };\n }\n}\nexport function getOutputInfo(\n { id, output }: Pick<FeedChannel, 'id' | 'output'>,\n {\n siteUrl,\n output: globalOutput,\n }: Pick<PluginRssOptions, 'output' | 'siteUrl'>,\n): ResolvedOutput {\n const type = output?.type || globalOutput?.type || 'atom';\n const { extension, mime, getContent } = getFeedFileType(type);\n const filename = output?.filename || `${id}.${extension}`;\n const dir = output?.dir || globalOutput?.dir || 'rss';\n const publicPath = output?.publicPath || globalOutput?.publicPath || siteUrl;\n const url = [publicPath, `${dir}/`, filename].reduce((u, part) =>\n u ? resolveUrl(u, part) : part,\n );\n const sorting =\n output?.sorting ||\n globalOutput?.sorting ||\n ((l, r) => sortByDate(l.date, r.date));\n return { type, mime, filename, getContent, dir, publicPath, url, sorting };\n}\n"]}
|
package/dist/index.mjs.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"mappings":"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","names":["NodePath","resolveUrl","author"],"ignoreList":[],"sources":["../src/plugin-rss.ts","../src/exports.ts","../src/feed.ts","../src/internals/lang.ts","../src/internals/node.ts","../src/options.ts"],"sourcesContent":["import NodePath from 'node:path';\nimport { resolve as resolveUrl } from 'node:url';\nimport type { PageIndexInfo, RspressPlugin, UserConfig } from '@rspress/shared';\nimport { Feed } from 'feed';\nimport { PluginComponents, PluginName } from './exports';\nimport { createFeed, generateFeedItem } from './feed';\n\nimport {\n type PageWithFeeds,\n type ResolvedOutput,\n concatArray,\n writeFile,\n} from './internals';\nimport { getDefaultFeedOption, getOutputInfo, testPage } from './options';\nimport type { FeedChannel, FeedItem, PluginRssOptions } from './type';\n\ntype FeedItemWithChannel = FeedItem & { channel: string };\ntype TransformedFeedChannel = FeedChannel & { output: ResolvedOutput };\n\nclass FeedsSet {\n feeds: TransformedFeedChannel[] = [];\n feedsMapById: Record<string, TransformedFeedChannel> = Object.create(null);\n set({ feed, output, siteUrl }: PluginRssOptions, config: UserConfig) {\n this.feeds = (\n Array.isArray(feed) ? feed : [{ ...getDefaultFeedOption(), ...feed }]\n ).map(options => ({\n title: config.title || '',\n description: config.description || '',\n favicon: config.icon && resolveUrl(siteUrl, config.icon),\n copyright: config.themeConfig?.footer?.message || '',\n link: siteUrl,\n docs: '',\n ...options,\n output: getOutputInfo(options, { siteUrl, output }),\n }));\n\n this.feedsMapById = this.feeds.reduce(\n (m, f) => ({ ...m, [f.id]: f }),\n Object.create(null),\n );\n }\n get(): TransformedFeedChannel[];\n get(id: string): TransformedFeedChannel | null;\n get(id?: string): TransformedFeedChannel[] | TransformedFeedChannel | null {\n if (id) {\n return this.feedsMapById[id] || null;\n }\n return this.feeds.slice(0);\n }\n}\n\nfunction getRssItems(\n feeds: TransformedFeedChannel[],\n page: PageIndexInfo,\n config: UserConfig,\n siteUrl: string,\n): Promise<FeedItemWithChannel[]> {\n return Promise.all(\n feeds\n .filter(options => testPage(options.test, page, config.base))\n .map(async options => {\n const after = options.item || ((feed: FeedItem) => feed);\n const item = await after(\n generateFeedItem(page, siteUrl),\n page,\n siteUrl,\n );\n return { ...item, channel: options.id };\n }),\n );\n}\n\nexport function pluginRss(pluginRssOptions: PluginRssOptions): RspressPlugin {\n const feedsSet = new FeedsSet();\n\n /**\n * workaround for retrieving data of pages in `afterBuild`\n * TODO: get pageData list directly in `afterBuild`\n **/\n let _rssWorkaround: null | Record<\n string,\n PromiseLike<FeedItemWithChannel[]>\n > = null;\n let _config: null | UserConfig;\n\n return {\n name: PluginName,\n globalUIComponents: Object.values(PluginComponents),\n beforeBuild(config, isProd) {\n if (!isProd) {\n _rssWorkaround = null;\n return;\n }\n _rssWorkaround = {};\n _config = config;\n feedsSet.set(pluginRssOptions, config);\n },\n async extendPageData(_pageData) {\n if (!_rssWorkaround) return;\n\n const pageData = _pageData as PageWithFeeds;\n\n // rspress run `extendPageData` for each page\n // - let's cache rss items within a complete rspress build\n _rssWorkaround[pageData.id] =\n _rssWorkaround[pageData.id] ||\n getRssItems(\n feedsSet.get(),\n pageData,\n _config!,\n pluginRssOptions.siteUrl,\n );\n\n const feeds = await _rssWorkaround[pageData.id];\n const showRssList = new Set(\n concatArray(pageData.frontmatter['link-rss'] as string[] | string),\n );\n for (const feed of feeds) {\n showRssList.add(feed.channel);\n }\n\n pageData.feeds = Array.from(showRssList, id => {\n const { output, language } = feedsSet.get(id)!;\n return {\n url: output.url,\n mime: output.mime,\n language: language || pageData.lang,\n };\n });\n },\n async afterBuild(config) {\n if (!_rssWorkaround) return;\n\n const items = concatArray(\n ...(await Promise.all(Object.values(_rssWorkaround))),\n );\n const feeds: Record<string, Feed> = Object.create(null);\n\n for (const { channel, ...item } of items) {\n feeds[channel] =\n feeds[channel] ||\n new Feed(createFeed(feedsSet.get(channel)!, config));\n feeds[channel].addItem(item);\n }\n\n for (const [channel, feed] of Object.entries(feeds)) {\n const { output } = feedsSet.get(channel)!;\n feed.items.sort(output.sorting);\n const path = NodePath.resolve(\n config.outDir || 'doc_build',\n output.dir,\n output.filename,\n );\n await writeFile(path, output.getContent(feed));\n }\n _rssWorkaround = null;\n _config = null;\n },\n };\n}\n","export const PluginName = '@rspress/plugin-rss';\n\nexport const PluginComponents = {\n FeedsAnnotations: '@rspress/plugin-rss/FeedsAnnotations',\n} as const;\n","import { resolve as resolveUrl } from 'node:url';\nimport type { PageIndexInfo, UserConfig } from '@rspress/shared';\nimport type { Author, FeedOptions } from 'feed';\nimport {\n type ResolvedOutput,\n concatArray,\n selectNonNullishProperty,\n toDate,\n} from './internals';\nimport type { FeedChannel, FeedItem } from './type';\n\n/**\n * @public\n * @param page Rspress Page Data\n * @param siteUrl\n */\nexport function generateFeedItem(page: PageIndexInfo, siteUrl: string) {\n const { frontmatter: fm } = page;\n return {\n id: selectNonNullishProperty(fm.slug, fm.id, page.id) || '',\n title: selectNonNullishProperty(fm.title, page.title) || '',\n author: toAuthors(fm.author),\n link: resolveUrl(\n siteUrl,\n selectNonNullishProperty(fm.permalink, page.routePath) || '',\n ),\n description: selectNonNullishProperty(fm.description) || '',\n content: selectNonNullishProperty(fm.summary, page._html) || '',\n date: toDate((fm.date as string) || (fm.published_at as string))!,\n category: concatArray(fm.categories as string[], fm.category as string).map(\n cat => ({ name: cat }),\n ),\n } satisfies FeedItem;\n}\n\nexport function createFeed(\n options: Omit<FeedChannel, 'test' | 'item' | 'output'> & {\n item?: any;\n test?: any;\n output: ResolvedOutput;\n },\n config: UserConfig,\n): FeedOptions {\n const { output, item, id, title, ..._options } = options;\n return {\n id,\n copyright: config.themeConfig?.footer?.message || '',\n description: config.description || '',\n link: output.url,\n ..._options,\n title: title || config.title || '',\n };\n}\n\nfunction toAuthors(author: unknown): Author[] | undefined {\n const authors = (Array.isArray(author) ? author : [author])\n .filter(Boolean)\n .map(author => ({\n // email is mandatory for RSS 2.0.\n ...(typeof author === 'string' ? { name: author } : author),\n }));\n return authors.length ? authors : undefined;\n}\n","export type PartialPartial<T, K extends keyof T> = Partial<Pick<T, K>> &\n Omit<T, K>;\n\nexport type ItemOf<T> = T extends Array<infer K> ? K : never;\n\nexport function notNullish<T>(n: T | undefined | null): n is T {\n return n !== undefined && n !== null;\n}\nexport function concatArray<T>(...arrList: (T[] | T | undefined)[]) {\n return arrList.reduce<T[]>(\n (arr, item) =>\n arr.concat((Array.isArray(item) ? item : [item]).filter(notNullish)),\n [] as T[],\n );\n}\n\nexport function selectNonNullishProperty(...list: unknown[]) {\n for (const item of list) {\n if (item === '') return '';\n if (item === 0) return '0';\n if (typeof item === 'number') return `${item}`;\n if (typeof item === 'string') return item;\n }\n}\n\nexport function toDate(s: string | Date): null | Date {\n const d = new Date(s);\n return Number.isNaN(d.getDate()) ? null : d;\n}\n\nexport function sortByDate(l: null | Date, r: null | Date): number {\n return (r ? r.getTime() : 0) - (l ? l.getTime() : 0);\n}\n","import { promises } from 'node:fs';\nimport * as NodePath from 'node:path';\n\nexport async function writeFile(\n path: string,\n content: Parameters<typeof promises.writeFile>[1],\n) {\n const dir = NodePath.dirname(path);\n await promises.mkdir(dir, { mode: 0o755, recursive: true });\n return promises.writeFile(path, content);\n}\n","import { resolve as resolveUrl } from 'node:url';\nimport type { PageIndexInfo } from '@rspress/shared';\nimport type { Feed } from 'feed';\nimport { type ResolvedOutput, sortByDate } from './internals';\nimport type { FeedChannel, FeedOutputType, PluginRssOptions } from './type';\n\nexport function testPage(\n test: FeedChannel['test'],\n page: PageIndexInfo,\n base = '/',\n): boolean {\n if (Array.isArray(test)) {\n return test.some(item => testPage(item, page, base));\n }\n if (typeof test === 'function') {\n return test(page, base);\n }\n const routePath = page.routePath;\n const pureRoutePath = `/${\n routePath.startsWith(base) ? routePath.slice(base.length) : routePath\n }`.replace(/^\\/+/, '/');\n if (typeof test === 'string') {\n return [routePath, pureRoutePath].some(path => path.startsWith(test));\n }\n if (test instanceof RegExp) {\n return [routePath, pureRoutePath].some(path => test.test(path));\n }\n\n throw new Error(\n 'test must be of `RegExp` or `string` or `(page: PageIndexInfo, base: string) => boolean`',\n );\n}\n\nexport function getDefaultFeedOption() {\n return { id: 'blog', test: '/blog/' } satisfies FeedChannel;\n}\n\nexport function getFeedFileType(type: FeedOutputType) {\n switch (type) {\n case 'rss':\n return {\n extension: 'rss',\n mime: 'application/rss+xml',\n getContent: (feed: Feed) => feed.rss2(),\n };\n case 'json':\n return {\n extension: 'json',\n mime: 'application/json',\n getContent: (feed: Feed) => feed.json1(),\n };\n case 'atom':\n default:\n return {\n extension: 'xml',\n mime: 'application/atom+xml',\n getContent: (feed: Feed) => feed.atom1(),\n };\n }\n}\nexport function getOutputInfo(\n { id, output }: Pick<FeedChannel, 'id' | 'output'>,\n {\n siteUrl,\n output: globalOutput,\n }: Pick<PluginRssOptions, 'output' | 'siteUrl'>,\n): ResolvedOutput {\n const type = output?.type || globalOutput?.type || 'atom';\n const { extension, mime, getContent } = getFeedFileType(type);\n const filename = output?.filename || `${id}.${extension}`;\n const dir = output?.dir || globalOutput?.dir || 'rss';\n const publicPath = output?.publicPath || globalOutput?.publicPath || siteUrl;\n const url = [publicPath, `${dir}/`, filename].reduce((u, part) =>\n u ? resolveUrl(u, part) : part,\n );\n const sorting =\n output?.sorting ||\n globalOutput?.sorting ||\n ((l, r) => sortByDate(l.date, r.date));\n return { type, mime, filename, getContent, dir, publicPath, url, sorting };\n}\n"]}
|