@docusaurus/plugin-content-blog 2.0.0-beta.12faed89d → 2.0.0-beta.13
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/lib/.tsbuildinfo +1 -1
- package/lib/authors.d.ts +23 -0
- package/lib/authors.js +147 -0
- package/lib/blogFrontMatter.d.ts +19 -6
- package/lib/blogFrontMatter.js +31 -19
- package/lib/blogUtils.d.ts +10 -4
- package/lib/blogUtils.js +141 -136
- package/lib/feed.d.ts +20 -0
- package/lib/feed.js +90 -0
- package/lib/index.js +99 -106
- package/lib/markdownLoader.d.ts +3 -6
- package/lib/markdownLoader.js +5 -5
- package/lib/pluginOptionSchema.d.ts +3 -26
- package/lib/pluginOptionSchema.js +28 -7
- package/lib/translations.d.ts +10 -0
- package/lib/translations.js +53 -0
- package/lib/types.d.ts +54 -14
- package/package.json +17 -13
- package/src/__tests__/__fixtures__/authorsMapFiles/authors.json +29 -0
- package/src/__tests__/__fixtures__/authorsMapFiles/authors.yml +27 -0
- package/src/__tests__/__fixtures__/authorsMapFiles/authorsBad1.json +5 -0
- package/src/__tests__/__fixtures__/authorsMapFiles/authorsBad1.yml +3 -0
- package/src/__tests__/__fixtures__/authorsMapFiles/authorsBad2.json +3 -0
- package/src/__tests__/__fixtures__/authorsMapFiles/authorsBad2.yml +2 -0
- package/src/__tests__/__fixtures__/authorsMapFiles/authorsBad3.json +8 -0
- package/src/__tests__/__fixtures__/authorsMapFiles/authorsBad3.yml +3 -0
- package/src/__tests__/__fixtures__/component/Typography.tsx +6 -0
- package/src/__tests__/__fixtures__/getAuthorsMapFilePath/contentPathEmpty/empty +0 -0
- package/src/__tests__/__fixtures__/getAuthorsMapFilePath/contentPathJson1/authors.json +0 -0
- package/src/__tests__/__fixtures__/getAuthorsMapFilePath/contentPathJson2/authors.json +0 -0
- package/src/__tests__/__fixtures__/getAuthorsMapFilePath/contentPathNestedYml/sub/folder/authors.yml +0 -0
- package/src/__tests__/__fixtures__/getAuthorsMapFilePath/contentPathYml1/authors.yml +0 -0
- package/src/__tests__/__fixtures__/getAuthorsMapFilePath/contentPathYml2/authors.yml +0 -0
- package/src/__tests__/__fixtures__/website/blog/2018-12-14-Happy-First-Birthday-Slash.md +3 -0
- package/src/__tests__/__fixtures__/website/blog/_partials/somePartial.md +3 -0
- package/src/__tests__/__fixtures__/website/blog/_partials/subfolder/somePartial.md +3 -0
- package/src/__tests__/__fixtures__/website/blog/_somePartial.md +3 -0
- package/src/__tests__/__fixtures__/website/blog/authors.yml +4 -0
- package/src/__tests__/__fixtures__/website/blog/mdx-blog-post.mdx +36 -0
- package/src/__tests__/__fixtures__/website/blog/mdx-require-blog-post.mdx +14 -0
- package/src/__tests__/__fixtures__/website/blog/simple-slug.md +4 -0
- package/src/__tests__/__fixtures__/website/i18n/en/docusaurus-plugin-content-blog/2018-12-14-Happy-First-Birthday-Slash.md +3 -0
- package/src/__tests__/__fixtures__/website/i18n/en/docusaurus-plugin-content-blog/authors.yml +5 -0
- package/src/__tests__/__fixtures__/website/static/img/docusaurus.png +0 -0
- package/src/__tests__/__snapshots__/feed.test.ts.snap +164 -0
- package/src/__tests__/__snapshots__/translations.test.ts.snap +64 -0
- package/src/__tests__/authors.test.ts +608 -0
- package/src/__tests__/blogFrontMatter.test.ts +93 -16
- package/src/__tests__/blogUtils.test.ts +94 -0
- package/src/__tests__/{generateBlogFeed.test.ts → feed.test.ts} +35 -9
- package/src/__tests__/index.test.ts +84 -12
- package/src/__tests__/pluginOptionSchema.test.ts +3 -3
- package/src/__tests__/translations.test.ts +92 -0
- package/src/authors.ts +198 -0
- package/src/blogFrontMatter.ts +71 -33
- package/src/blogUtils.ts +202 -179
- package/{types.d.ts → src/deps.d.ts} +0 -0
- package/src/feed.ts +129 -0
- package/src/index.ts +118 -107
- package/src/markdownLoader.ts +8 -12
- package/{index.d.ts → src/plugin-content-blog.d.ts} +35 -31
- package/src/pluginOptionSchema.ts +31 -9
- package/src/translations.ts +63 -0
- package/src/types.ts +69 -16
- package/src/__tests__/__snapshots__/generateBlogFeed.test.ts.snap +0 -76
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
} from '../blogFrontMatter';
|
|
12
12
|
import escapeStringRegexp from 'escape-string-regexp';
|
|
13
13
|
|
|
14
|
+
// TODO this abstraction reduce verbosity but it makes it harder to debug
|
|
15
|
+
// It would be preferable to just expose helper methods
|
|
14
16
|
function testField(params: {
|
|
15
17
|
fieldName: keyof BlogPostFrontMatter;
|
|
16
18
|
validFrontMatters: BlogPostFrontMatter[];
|
|
@@ -99,7 +101,30 @@ describe('validateBlogPostFrontMatter id', () => {
|
|
|
99
101
|
testField({
|
|
100
102
|
fieldName: 'id',
|
|
101
103
|
validFrontMatters: [{id: '123'}, {id: 'id'}],
|
|
102
|
-
invalidFrontMatters: [[{id: ''}, '
|
|
104
|
+
invalidFrontMatters: [[{id: ''}, 'not allowed to be empty']],
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe('validateBlogPostFrontMatter handles legacy/new author frontmatter', () => {
|
|
109
|
+
test('allow legacy author frontmatter', () => {
|
|
110
|
+
const frontMatter: BlogPostFrontMatter = {
|
|
111
|
+
author: 'Sebastien',
|
|
112
|
+
author_url: 'https://sebastienlorber.com',
|
|
113
|
+
author_title: 'maintainer',
|
|
114
|
+
author_image_url: 'https://github.com/slorber.png',
|
|
115
|
+
};
|
|
116
|
+
expect(validateBlogPostFrontMatter(frontMatter)).toEqual(frontMatter);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test('allow new authors frontmatter', () => {
|
|
120
|
+
const frontMatter: BlogPostFrontMatter = {
|
|
121
|
+
authors: [
|
|
122
|
+
'slorber',
|
|
123
|
+
{name: 'Yangshun'},
|
|
124
|
+
{key: 'JMarcey', title: 'creator', random: '42'},
|
|
125
|
+
],
|
|
126
|
+
};
|
|
127
|
+
expect(validateBlogPostFrontMatter(frontMatter)).toEqual(frontMatter);
|
|
103
128
|
});
|
|
104
129
|
});
|
|
105
130
|
|
|
@@ -107,21 +132,24 @@ describe('validateBlogPostFrontMatter author', () => {
|
|
|
107
132
|
testField({
|
|
108
133
|
fieldName: 'author',
|
|
109
134
|
validFrontMatters: [{author: '123'}, {author: 'author'}],
|
|
110
|
-
invalidFrontMatters: [[{author: ''}, '
|
|
135
|
+
invalidFrontMatters: [[{author: ''}, 'not allowed to be empty']],
|
|
111
136
|
});
|
|
112
137
|
});
|
|
113
138
|
|
|
114
139
|
describe('validateBlogPostFrontMatter author_title', () => {
|
|
115
140
|
testField({
|
|
116
141
|
fieldName: 'author_title',
|
|
117
|
-
validFrontMatters: [
|
|
118
|
-
|
|
142
|
+
validFrontMatters: [
|
|
143
|
+
{author: '123', author_title: '123'},
|
|
144
|
+
{author: '123', author_title: 'author_title'},
|
|
145
|
+
],
|
|
146
|
+
invalidFrontMatters: [[{author_title: ''}, 'not allowed to be empty']],
|
|
119
147
|
});
|
|
120
148
|
|
|
121
149
|
testField({
|
|
122
150
|
fieldName: 'authorTitle',
|
|
123
151
|
validFrontMatters: [{authorTitle: '123'}, {authorTitle: 'authorTitle'}],
|
|
124
|
-
invalidFrontMatters: [[{authorTitle: ''}, '
|
|
152
|
+
invalidFrontMatters: [[{authorTitle: ''}, 'not allowed to be empty']],
|
|
125
153
|
});
|
|
126
154
|
});
|
|
127
155
|
|
|
@@ -136,7 +164,7 @@ describe('validateBlogPostFrontMatter author_url', () => {
|
|
|
136
164
|
invalidFrontMatters: [
|
|
137
165
|
[
|
|
138
166
|
{author_url: ''},
|
|
139
|
-
'"author_url" does not
|
|
167
|
+
'"author_url" does not look like a valid url (value=\'\')',
|
|
140
168
|
],
|
|
141
169
|
],
|
|
142
170
|
});
|
|
@@ -150,7 +178,10 @@ describe('validateBlogPostFrontMatter author_url', () => {
|
|
|
150
178
|
],
|
|
151
179
|
|
|
152
180
|
invalidFrontMatters: [
|
|
153
|
-
[
|
|
181
|
+
[
|
|
182
|
+
{authorURL: ''},
|
|
183
|
+
'"authorURL" does not look like a valid url (value=\'\')',
|
|
184
|
+
],
|
|
154
185
|
],
|
|
155
186
|
});
|
|
156
187
|
});
|
|
@@ -166,7 +197,7 @@ describe('validateBlogPostFrontMatter author_image_url', () => {
|
|
|
166
197
|
invalidFrontMatters: [
|
|
167
198
|
[
|
|
168
199
|
{author_image_url: ''},
|
|
169
|
-
'"author_image_url" does not
|
|
200
|
+
'"author_image_url" does not look like a valid url (value=\'\')',
|
|
170
201
|
],
|
|
171
202
|
],
|
|
172
203
|
});
|
|
@@ -181,7 +212,55 @@ describe('validateBlogPostFrontMatter author_image_url', () => {
|
|
|
181
212
|
invalidFrontMatters: [
|
|
182
213
|
[
|
|
183
214
|
{authorImageURL: ''},
|
|
184
|
-
'"authorImageURL" does not
|
|
215
|
+
'"authorImageURL" does not look like a valid url (value=\'\')',
|
|
216
|
+
],
|
|
217
|
+
],
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
describe('validateBlogPostFrontMatter authors', () => {
|
|
222
|
+
testField({
|
|
223
|
+
fieldName: 'author',
|
|
224
|
+
validFrontMatters: [
|
|
225
|
+
{authors: []},
|
|
226
|
+
{authors: 'authorKey'},
|
|
227
|
+
{authors: ['authorKey1', 'authorKey2']},
|
|
228
|
+
{
|
|
229
|
+
authors: {
|
|
230
|
+
name: 'Author Name',
|
|
231
|
+
imageURL: '/absolute',
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
authors: {
|
|
236
|
+
key: 'authorKey',
|
|
237
|
+
title: 'Author title',
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
authors: [
|
|
242
|
+
'authorKey1',
|
|
243
|
+
{key: 'authorKey3'},
|
|
244
|
+
'authorKey3',
|
|
245
|
+
{name: 'Author Name 4'},
|
|
246
|
+
{key: 'authorKey5'},
|
|
247
|
+
],
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
|
|
251
|
+
invalidFrontMatters: [
|
|
252
|
+
[{authors: ''}, '"authors" is not allowed to be empty'],
|
|
253
|
+
[
|
|
254
|
+
{authors: [undefined]},
|
|
255
|
+
'"authors[0]" does not look like a valid blog post author. Please use an author key or an author object (with a key and/or name).',
|
|
256
|
+
],
|
|
257
|
+
[
|
|
258
|
+
{authors: [null]},
|
|
259
|
+
'"authors[0]" does not look like a valid blog post author. Please use an author key or an author object (with a key and/or name).',
|
|
260
|
+
],
|
|
261
|
+
[
|
|
262
|
+
{authors: [{}]},
|
|
263
|
+
'"authors[0]" does not look like a valid blog post author. Please use an author key or an author object (with a key and/or name).',
|
|
185
264
|
],
|
|
186
265
|
],
|
|
187
266
|
});
|
|
@@ -200,7 +279,7 @@ describe('validateBlogPostFrontMatter slug', () => {
|
|
|
200
279
|
{slug: '/api/plugins/@docusaurus/plugin-debug'},
|
|
201
280
|
{slug: '@site/api/asset/image.png'},
|
|
202
281
|
],
|
|
203
|
-
invalidFrontMatters: [[{slug: ''}, '
|
|
282
|
+
invalidFrontMatters: [[{slug: ''}, 'not allowed to be empty']],
|
|
204
283
|
});
|
|
205
284
|
});
|
|
206
285
|
|
|
@@ -219,7 +298,7 @@ describe('validateBlogPostFrontMatter image', () => {
|
|
|
219
298
|
{image: '@site/api/asset/image.png'},
|
|
220
299
|
],
|
|
221
300
|
invalidFrontMatters: [
|
|
222
|
-
[{image: ''}, '"image" does not
|
|
301
|
+
[{image: ''}, '"image" does not look like a valid url (value=\'\')'],
|
|
223
302
|
],
|
|
224
303
|
});
|
|
225
304
|
});
|
|
@@ -235,8 +314,8 @@ describe('validateBlogPostFrontMatter tags', () => {
|
|
|
235
314
|
{tags: ['hello', {label: 'tagLabel', permalink: '/tagPermalink'}]},
|
|
236
315
|
],
|
|
237
316
|
invalidFrontMatters: [
|
|
238
|
-
[{tags: ''}, '
|
|
239
|
-
[{tags: ['']}, '
|
|
317
|
+
[{tags: ''}, '"tags" does not look like a valid FrontMatter Yaml array.'],
|
|
318
|
+
[{tags: ['']}, 'not allowed to be empty'],
|
|
240
319
|
],
|
|
241
320
|
// See https://github.com/facebook/docusaurus/issues/4642
|
|
242
321
|
convertibleFrontMatter: [
|
|
@@ -260,7 +339,7 @@ describe('validateBlogPostFrontMatter keywords', () => {
|
|
|
260
339
|
],
|
|
261
340
|
invalidFrontMatters: [
|
|
262
341
|
[{keywords: ''}, 'must be an array'],
|
|
263
|
-
[{keywords: ['']}, '
|
|
342
|
+
[{keywords: ['']}, 'not allowed to be empty'],
|
|
264
343
|
[{keywords: []}, 'does not contain 1 required value(s)'],
|
|
265
344
|
],
|
|
266
345
|
});
|
|
@@ -304,9 +383,7 @@ describe('validateBlogPostFrontMatter date', () => {
|
|
|
304
383
|
fieldName: 'date',
|
|
305
384
|
validFrontMatters: [
|
|
306
385
|
{date: new Date('2020-01-01')},
|
|
307
|
-
// @ts-expect-error: string for test
|
|
308
386
|
{date: '2020-01-01'},
|
|
309
|
-
// @ts-expect-error: string for test
|
|
310
387
|
{date: '2020'},
|
|
311
388
|
],
|
|
312
389
|
invalidFrontMatters: [
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {parseBlogFileName} from '../blogUtils';
|
|
9
|
+
|
|
10
|
+
describe('parseBlogFileName', () => {
|
|
11
|
+
test('parse file', () => {
|
|
12
|
+
expect(parseBlogFileName('some-post.md')).toEqual({
|
|
13
|
+
date: undefined,
|
|
14
|
+
text: 'some-post',
|
|
15
|
+
slug: '/some-post',
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('parse folder', () => {
|
|
20
|
+
expect(parseBlogFileName('some-post/index.md')).toEqual({
|
|
21
|
+
date: undefined,
|
|
22
|
+
text: 'some-post',
|
|
23
|
+
slug: '/some-post',
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('parse nested file', () => {
|
|
28
|
+
expect(parseBlogFileName('some-post/some-file.md')).toEqual({
|
|
29
|
+
date: undefined,
|
|
30
|
+
text: 'some-post/some-file',
|
|
31
|
+
slug: '/some-post/some-file',
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('parse nested folder', () => {
|
|
36
|
+
expect(parseBlogFileName('some-post/some-subfolder/index.md')).toEqual({
|
|
37
|
+
date: undefined,
|
|
38
|
+
text: 'some-post/some-subfolder',
|
|
39
|
+
slug: '/some-post/some-subfolder',
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('parse file respecting date convention', () => {
|
|
44
|
+
expect(
|
|
45
|
+
parseBlogFileName('2021-05-12-announcing-docusaurus-two-beta.md'),
|
|
46
|
+
).toEqual({
|
|
47
|
+
date: new Date('2021-05-12Z'),
|
|
48
|
+
text: 'announcing-docusaurus-two-beta',
|
|
49
|
+
slug: '/2021/05/12/announcing-docusaurus-two-beta',
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('parse folder name respecting date convention', () => {
|
|
54
|
+
expect(
|
|
55
|
+
parseBlogFileName('2021-05-12-announcing-docusaurus-two-beta/index.md'),
|
|
56
|
+
).toEqual({
|
|
57
|
+
date: new Date('2021-05-12Z'),
|
|
58
|
+
text: 'announcing-docusaurus-two-beta',
|
|
59
|
+
slug: '/2021/05/12/announcing-docusaurus-two-beta',
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('parse folder tree respecting date convention', () => {
|
|
64
|
+
expect(
|
|
65
|
+
parseBlogFileName('2021/05/12/announcing-docusaurus-two-beta/index.md'),
|
|
66
|
+
).toEqual({
|
|
67
|
+
date: new Date('2021-05-12Z'),
|
|
68
|
+
text: 'announcing-docusaurus-two-beta',
|
|
69
|
+
slug: '/2021/05/12/announcing-docusaurus-two-beta',
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('parse folder name/tree (mixed) respecting date convention', () => {
|
|
74
|
+
expect(
|
|
75
|
+
parseBlogFileName('2021/05-12-announcing-docusaurus-two-beta/index.md'),
|
|
76
|
+
).toEqual({
|
|
77
|
+
date: new Date('2021-05-12Z'),
|
|
78
|
+
text: 'announcing-docusaurus-two-beta',
|
|
79
|
+
slug: '/2021/05/12/announcing-docusaurus-two-beta',
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('parse nested folder tree respecting date convention', () => {
|
|
84
|
+
expect(
|
|
85
|
+
parseBlogFileName(
|
|
86
|
+
'2021/05/12/announcing-docusaurus-two-beta/subfolder/subfile.md',
|
|
87
|
+
),
|
|
88
|
+
).toEqual({
|
|
89
|
+
date: new Date('2021-05-12Z'),
|
|
90
|
+
text: 'announcing-docusaurus-two-beta/subfolder/subfile',
|
|
91
|
+
slug: '/2021/05/12/announcing-docusaurus-two-beta/subfolder/subfile',
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -6,9 +6,12 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import path from 'path';
|
|
9
|
-
import {generateBlogFeed} from '../
|
|
9
|
+
import {generateBlogFeed} from '../feed';
|
|
10
10
|
import {LoadContext, I18n} from '@docusaurus/types';
|
|
11
11
|
import {PluginOptions, BlogContentPaths} from '../types';
|
|
12
|
+
import {DEFAULT_OPTIONS} from '../pluginOptionSchema';
|
|
13
|
+
import {generateBlogPosts} from '../blogUtils';
|
|
14
|
+
import {Feed} from 'feed';
|
|
12
15
|
|
|
13
16
|
const DefaultI18N: I18n = {
|
|
14
17
|
currentLocale: 'en',
|
|
@@ -29,6 +32,23 @@ function getBlogContentPaths(siteDir: string): BlogContentPaths {
|
|
|
29
32
|
};
|
|
30
33
|
}
|
|
31
34
|
|
|
35
|
+
async function testGenerateFeeds(
|
|
36
|
+
context: LoadContext,
|
|
37
|
+
options: PluginOptions,
|
|
38
|
+
): Promise<Feed | null> {
|
|
39
|
+
const blogPosts = await generateBlogPosts(
|
|
40
|
+
getBlogContentPaths(context.siteDir),
|
|
41
|
+
context,
|
|
42
|
+
options,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
return generateBlogFeed({
|
|
46
|
+
blogPosts,
|
|
47
|
+
options,
|
|
48
|
+
siteConfig: context.siteConfig,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
32
52
|
describe('blogFeed', () => {
|
|
33
53
|
(['atom', 'rss'] as const).forEach((feedType) => {
|
|
34
54
|
describe(`${feedType}`, () => {
|
|
@@ -41,8 +61,7 @@ describe('blogFeed', () => {
|
|
|
41
61
|
favicon: 'image/favicon.ico',
|
|
42
62
|
};
|
|
43
63
|
|
|
44
|
-
const feed = await
|
|
45
|
-
getBlogContentPaths(siteDir),
|
|
64
|
+
const feed = await testGenerateFeeds(
|
|
46
65
|
{
|
|
47
66
|
siteDir,
|
|
48
67
|
siteConfig,
|
|
@@ -51,16 +70,19 @@ describe('blogFeed', () => {
|
|
|
51
70
|
{
|
|
52
71
|
path: 'invalid-blog-path',
|
|
53
72
|
routeBasePath: 'blog',
|
|
73
|
+
tagsBasePath: 'tags',
|
|
74
|
+
authorsMapPath: 'authors.yml',
|
|
54
75
|
include: ['*.md', '*.mdx'],
|
|
55
76
|
feedOptions: {
|
|
56
77
|
type: [feedType],
|
|
57
78
|
copyright: 'Copyright',
|
|
58
79
|
},
|
|
80
|
+
readingTime: ({content, defaultReadingTime}) =>
|
|
81
|
+
defaultReadingTime({content}),
|
|
59
82
|
} as PluginOptions,
|
|
60
83
|
);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
expect(feedContent).toMatchSnapshot();
|
|
84
|
+
|
|
85
|
+
expect(feed).toEqual(null);
|
|
64
86
|
});
|
|
65
87
|
|
|
66
88
|
test('shows feed item for each post', async () => {
|
|
@@ -73,8 +95,7 @@ describe('blogFeed', () => {
|
|
|
73
95
|
favicon: 'image/favicon.ico',
|
|
74
96
|
};
|
|
75
97
|
|
|
76
|
-
const feed = await
|
|
77
|
-
getBlogContentPaths(siteDir),
|
|
98
|
+
const feed = await testGenerateFeeds(
|
|
78
99
|
{
|
|
79
100
|
siteDir,
|
|
80
101
|
siteConfig,
|
|
@@ -84,11 +105,16 @@ describe('blogFeed', () => {
|
|
|
84
105
|
{
|
|
85
106
|
path: 'blog',
|
|
86
107
|
routeBasePath: 'blog',
|
|
87
|
-
|
|
108
|
+
tagsBasePath: 'tags',
|
|
109
|
+
authorsMapPath: 'authors.yml',
|
|
110
|
+
include: DEFAULT_OPTIONS.include,
|
|
111
|
+
exclude: DEFAULT_OPTIONS.exclude,
|
|
88
112
|
feedOptions: {
|
|
89
113
|
type: [feedType],
|
|
90
114
|
copyright: 'Copyright',
|
|
91
115
|
},
|
|
116
|
+
readingTime: ({content, defaultReadingTime}) =>
|
|
117
|
+
defaultReadingTime({content}),
|
|
92
118
|
} as PluginOptions,
|
|
93
119
|
);
|
|
94
120
|
const feedContent =
|
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
9
|
-
|
|
10
8
|
import fs from 'fs-extra';
|
|
11
9
|
import path from 'path';
|
|
12
10
|
import pluginContentBlog from '../index';
|
|
@@ -14,6 +12,7 @@ import {DocusaurusConfig, LoadContext, I18n} from '@docusaurus/types';
|
|
|
14
12
|
import {PluginOptionSchema} from '../pluginOptionSchema';
|
|
15
13
|
import {PluginOptions, EditUrlFunction, BlogPost} from '../types';
|
|
16
14
|
import {Joi} from '@docusaurus/utils-validation';
|
|
15
|
+
import {posixPath} from '@docusaurus/utils';
|
|
17
16
|
|
|
18
17
|
function findByTitle(
|
|
19
18
|
blogPosts: BlogPost[],
|
|
@@ -60,7 +59,7 @@ describe('loadBlog', () => {
|
|
|
60
59
|
|
|
61
60
|
const BaseEditUrl = 'https://baseEditUrl.com/edit';
|
|
62
61
|
|
|
63
|
-
const
|
|
62
|
+
const getPlugin = async (
|
|
64
63
|
siteDir: string,
|
|
65
64
|
pluginOptions: Partial<PluginOptions> = {},
|
|
66
65
|
i18n: I18n = DefaultI18N,
|
|
@@ -71,7 +70,7 @@ describe('loadBlog', () => {
|
|
|
71
70
|
baseUrl: '/',
|
|
72
71
|
url: 'https://docusaurus.io',
|
|
73
72
|
} as DocusaurusConfig;
|
|
74
|
-
|
|
73
|
+
return pluginContentBlog(
|
|
75
74
|
{
|
|
76
75
|
siteDir,
|
|
77
76
|
siteConfig,
|
|
@@ -84,11 +83,32 @@ describe('loadBlog', () => {
|
|
|
84
83
|
...pluginOptions,
|
|
85
84
|
}),
|
|
86
85
|
);
|
|
87
|
-
|
|
86
|
+
};
|
|
88
87
|
|
|
88
|
+
const getBlogPosts = async (
|
|
89
|
+
siteDir: string,
|
|
90
|
+
pluginOptions: Partial<PluginOptions> = {},
|
|
91
|
+
i18n: I18n = DefaultI18N,
|
|
92
|
+
) => {
|
|
93
|
+
const plugin = await getPlugin(siteDir, pluginOptions, i18n);
|
|
94
|
+
const {blogPosts} = (await plugin.loadContent!())!;
|
|
89
95
|
return blogPosts;
|
|
90
96
|
};
|
|
91
97
|
|
|
98
|
+
test('getPathsToWatch', async () => {
|
|
99
|
+
const siteDir = path.join(__dirname, '__fixtures__', 'website');
|
|
100
|
+
const plugin = await getPlugin(siteDir);
|
|
101
|
+
const pathsToWatch = plugin.getPathsToWatch!();
|
|
102
|
+
const relativePathsToWatch = pathsToWatch.map((p) =>
|
|
103
|
+
posixPath(path.relative(siteDir, p)),
|
|
104
|
+
);
|
|
105
|
+
expect(relativePathsToWatch).toEqual([
|
|
106
|
+
'blog/authors.yml',
|
|
107
|
+
'i18n/en/docusaurus-plugin-content-blog/**/*.{md,mdx}',
|
|
108
|
+
'blog/**/*.{md,mdx}',
|
|
109
|
+
]);
|
|
110
|
+
});
|
|
111
|
+
|
|
92
112
|
test('simple website', async () => {
|
|
93
113
|
const siteDir = path.join(__dirname, '__fixtures__', 'website');
|
|
94
114
|
const blogPosts = await getBlogPosts(siteDir);
|
|
@@ -103,6 +123,7 @@ describe('loadBlog', () => {
|
|
|
103
123
|
source: path.posix.join('@site', PluginPath, 'date-matter.md'),
|
|
104
124
|
title: 'date-matter',
|
|
105
125
|
description: `date inside front matter`,
|
|
126
|
+
authors: [],
|
|
106
127
|
date: new Date('2019-01-01'),
|
|
107
128
|
formattedDate: 'January 1, 2019',
|
|
108
129
|
prevItem: undefined,
|
|
@@ -128,6 +149,16 @@ describe('loadBlog', () => {
|
|
|
128
149
|
),
|
|
129
150
|
title: 'Happy 1st Birthday Slash! (translated)',
|
|
130
151
|
description: `Happy birthday! (translated)`,
|
|
152
|
+
authors: [
|
|
153
|
+
{
|
|
154
|
+
name: 'Yangshun Tay (translated)',
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
key: 'slorber',
|
|
158
|
+
name: 'Sébastien Lorber (translated)',
|
|
159
|
+
title: 'Docusaurus maintainer (translated)',
|
|
160
|
+
},
|
|
161
|
+
],
|
|
131
162
|
date: new Date('2018-12-14'),
|
|
132
163
|
formattedDate: 'December 14, 2018',
|
|
133
164
|
tags: [],
|
|
@@ -148,6 +179,7 @@ describe('loadBlog', () => {
|
|
|
148
179
|
source: path.posix.join('@site', PluginPath, 'complex-slug.md'),
|
|
149
180
|
title: 'Complex Slug',
|
|
150
181
|
description: `complex url slug`,
|
|
182
|
+
authors: [],
|
|
151
183
|
prevItem: undefined,
|
|
152
184
|
nextItem: {
|
|
153
185
|
permalink: '/blog/simple/slug',
|
|
@@ -169,6 +201,14 @@ describe('loadBlog', () => {
|
|
|
169
201
|
source: path.posix.join('@site', PluginPath, 'simple-slug.md'),
|
|
170
202
|
title: 'Simple Slug',
|
|
171
203
|
description: `simple url slug`,
|
|
204
|
+
authors: [
|
|
205
|
+
{
|
|
206
|
+
name: 'Sébastien Lorber',
|
|
207
|
+
title: 'Docusaurus maintainer',
|
|
208
|
+
url: 'https://sebastienlorber.com',
|
|
209
|
+
imageURL: undefined,
|
|
210
|
+
},
|
|
211
|
+
],
|
|
172
212
|
prevItem: undefined,
|
|
173
213
|
nextItem: {
|
|
174
214
|
permalink: '/blog/draft',
|
|
@@ -190,6 +230,7 @@ describe('loadBlog', () => {
|
|
|
190
230
|
source: path.posix.join('@site', PluginPath, 'heading-as-title.md'),
|
|
191
231
|
title: 'some heading',
|
|
192
232
|
description: '',
|
|
233
|
+
authors: [],
|
|
193
234
|
date: new Date('2019-01-02'),
|
|
194
235
|
formattedDate: 'January 2, 2019',
|
|
195
236
|
prevItem: undefined,
|
|
@@ -205,23 +246,29 @@ describe('loadBlog', () => {
|
|
|
205
246
|
test('simple website blog dates localized', async () => {
|
|
206
247
|
const siteDir = path.join(__dirname, '__fixtures__', 'website');
|
|
207
248
|
const blogPostsFrench = await getBlogPosts(siteDir, {}, getI18n('fr'));
|
|
208
|
-
expect(blogPostsFrench).toHaveLength(
|
|
249
|
+
expect(blogPostsFrench).toHaveLength(8);
|
|
209
250
|
expect(blogPostsFrench[0].metadata.formattedDate).toMatchInlineSnapshot(
|
|
210
|
-
`"
|
|
251
|
+
`"6 mars 2021"`,
|
|
211
252
|
);
|
|
212
253
|
expect(blogPostsFrench[1].metadata.formattedDate).toMatchInlineSnapshot(
|
|
213
|
-
`"
|
|
254
|
+
`"5 mars 2021"`,
|
|
214
255
|
);
|
|
215
256
|
expect(blogPostsFrench[2].metadata.formattedDate).toMatchInlineSnapshot(
|
|
216
|
-
`"
|
|
257
|
+
`"16 août 2020"`,
|
|
217
258
|
);
|
|
218
259
|
expect(blogPostsFrench[3].metadata.formattedDate).toMatchInlineSnapshot(
|
|
219
|
-
`"
|
|
260
|
+
`"15 août 2020"`,
|
|
220
261
|
);
|
|
221
262
|
expect(blogPostsFrench[4].metadata.formattedDate).toMatchInlineSnapshot(
|
|
222
|
-
`"
|
|
263
|
+
`"27 février 2020"`,
|
|
223
264
|
);
|
|
224
265
|
expect(blogPostsFrench[5].metadata.formattedDate).toMatchInlineSnapshot(
|
|
266
|
+
`"2 janvier 2019"`,
|
|
267
|
+
);
|
|
268
|
+
expect(blogPostsFrench[6].metadata.formattedDate).toMatchInlineSnapshot(
|
|
269
|
+
`"1 janvier 2019"`,
|
|
270
|
+
);
|
|
271
|
+
expect(blogPostsFrench[7].metadata.formattedDate).toMatchInlineSnapshot(
|
|
225
272
|
`"14 décembre 2018"`,
|
|
226
273
|
);
|
|
227
274
|
});
|
|
@@ -251,7 +298,8 @@ describe('loadBlog', () => {
|
|
|
251
298
|
expect(blogPost.metadata.editUrl).toEqual(hardcodedEditUrl);
|
|
252
299
|
});
|
|
253
300
|
|
|
254
|
-
expect(editUrlFunction).toHaveBeenCalledTimes(
|
|
301
|
+
expect(editUrlFunction).toHaveBeenCalledTimes(8);
|
|
302
|
+
|
|
255
303
|
expect(editUrlFunction).toHaveBeenCalledWith({
|
|
256
304
|
blogDirPath: 'blog',
|
|
257
305
|
blogPath: 'date-matter.md',
|
|
@@ -264,6 +312,18 @@ describe('loadBlog', () => {
|
|
|
264
312
|
permalink: '/blog/draft',
|
|
265
313
|
locale: 'en',
|
|
266
314
|
});
|
|
315
|
+
expect(editUrlFunction).toHaveBeenCalledWith({
|
|
316
|
+
blogDirPath: 'blog',
|
|
317
|
+
blogPath: 'mdx-blog-post.mdx',
|
|
318
|
+
permalink: '/blog/mdx-blog-post',
|
|
319
|
+
locale: 'en',
|
|
320
|
+
});
|
|
321
|
+
expect(editUrlFunction).toHaveBeenCalledWith({
|
|
322
|
+
blogDirPath: 'blog',
|
|
323
|
+
blogPath: 'mdx-require-blog-post.mdx',
|
|
324
|
+
permalink: '/blog/mdx-require-blog-post',
|
|
325
|
+
locale: 'en',
|
|
326
|
+
});
|
|
267
327
|
expect(editUrlFunction).toHaveBeenCalledWith({
|
|
268
328
|
blogDirPath: 'blog',
|
|
269
329
|
blogPath: 'complex-slug.md',
|
|
@@ -325,6 +385,7 @@ describe('loadBlog', () => {
|
|
|
325
385
|
source: noDateSource,
|
|
326
386
|
title: 'no date',
|
|
327
387
|
description: `no date`,
|
|
388
|
+
authors: [],
|
|
328
389
|
date: noDateSourceBirthTime,
|
|
329
390
|
formattedDate,
|
|
330
391
|
tags: [],
|
|
@@ -333,4 +394,15 @@ describe('loadBlog', () => {
|
|
|
333
394
|
truncated: false,
|
|
334
395
|
});
|
|
335
396
|
});
|
|
397
|
+
|
|
398
|
+
test('test ascending sort direction of blog post', async () => {
|
|
399
|
+
const siteDir = path.join(__dirname, '__fixtures__', 'website');
|
|
400
|
+
const normalOrder = await getBlogPosts(siteDir);
|
|
401
|
+
const reversedOrder = await getBlogPosts(siteDir, {
|
|
402
|
+
sortPosts: 'ascending',
|
|
403
|
+
});
|
|
404
|
+
expect(normalOrder.reverse().map((x) => x.metadata.date)).toEqual(
|
|
405
|
+
reversedOrder.map((x) => x.metadata.date),
|
|
406
|
+
);
|
|
407
|
+
});
|
|
336
408
|
});
|
|
@@ -29,7 +29,7 @@ test('should accept correctly defined user options', () => {
|
|
|
29
29
|
const {value, error} = PluginOptionSchema.validate(userOptions);
|
|
30
30
|
expect(value).toEqual({
|
|
31
31
|
...userOptions,
|
|
32
|
-
feedOptions: {type: ['rss'], title: 'myTitle'},
|
|
32
|
+
feedOptions: {type: ['rss'], title: 'myTitle', copyright: ''},
|
|
33
33
|
});
|
|
34
34
|
expect(error).toBe(undefined);
|
|
35
35
|
});
|
|
@@ -78,7 +78,7 @@ test('should convert all feed type to array with other feed type', () => {
|
|
|
78
78
|
});
|
|
79
79
|
expect(value).toEqual({
|
|
80
80
|
...DEFAULT_OPTIONS,
|
|
81
|
-
feedOptions: {type: ['rss', 'atom']},
|
|
81
|
+
feedOptions: {type: ['rss', 'atom'], copyright: ''},
|
|
82
82
|
});
|
|
83
83
|
});
|
|
84
84
|
|
|
@@ -106,7 +106,7 @@ test('should have array with rss + atom, title for missing feed type', () => {
|
|
|
106
106
|
});
|
|
107
107
|
expect(value).toEqual({
|
|
108
108
|
...DEFAULT_OPTIONS,
|
|
109
|
-
feedOptions: {type: ['rss', 'atom'], title: 'title'},
|
|
109
|
+
feedOptions: {type: ['rss', 'atom'], title: 'title', copyright: ''},
|
|
110
110
|
});
|
|
111
111
|
});
|
|
112
112
|
|