@docusaurus/plugin-content-blog 3.3.2 → 3.5.0

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.
Files changed (62) hide show
  1. package/assets/atom.css +75 -0
  2. package/assets/atom.xsl +92 -0
  3. package/assets/rss.css +75 -0
  4. package/assets/rss.xsl +86 -0
  5. package/lib/authors.d.ts +9 -11
  6. package/lib/authors.js +42 -64
  7. package/lib/authorsMap.d.ts +23 -0
  8. package/lib/authorsMap.js +116 -0
  9. package/lib/authorsProblems.d.ts +21 -0
  10. package/lib/authorsProblems.js +51 -0
  11. package/lib/authorsSocials.d.ts +10 -0
  12. package/lib/authorsSocials.js +48 -0
  13. package/lib/blogUtils.d.ts +7 -12
  14. package/lib/blogUtils.js +44 -34
  15. package/lib/client/contexts.d.ts +33 -0
  16. package/lib/client/contexts.js +54 -0
  17. package/lib/client/index.d.ts +3 -3
  18. package/lib/client/index.js +3 -9
  19. package/lib/client/sidebarUtils.d.ts +21 -0
  20. package/lib/client/sidebarUtils.js +49 -0
  21. package/lib/client/sidebarUtils.test.d.ts +7 -0
  22. package/lib/client/sidebarUtils.test.js +43 -0
  23. package/lib/client/structuredDataUtils.d.ts +10 -0
  24. package/lib/client/structuredDataUtils.js +122 -0
  25. package/lib/feed.d.ts +8 -3
  26. package/lib/feed.js +111 -20
  27. package/lib/frontMatter.d.ts +0 -1
  28. package/lib/frontMatter.js +3 -2
  29. package/lib/index.d.ts +0 -1
  30. package/lib/index.js +132 -105
  31. package/lib/markdownLoader.js +3 -7
  32. package/lib/options.d.ts +4 -1
  33. package/lib/options.js +107 -26
  34. package/lib/props.d.ts +9 -2
  35. package/lib/props.js +23 -3
  36. package/lib/remark/footnoteIDFixer.js +1 -1
  37. package/lib/routes.d.ts +0 -1
  38. package/lib/routes.js +82 -14
  39. package/lib/translations.d.ts +0 -1
  40. package/lib/translations.js +2 -3
  41. package/lib/types.d.ts +1 -8
  42. package/package.json +13 -10
  43. package/src/authors.ts +56 -93
  44. package/src/authorsMap.ts +171 -0
  45. package/src/authorsProblems.ts +72 -0
  46. package/src/authorsSocials.ts +64 -0
  47. package/src/blogUtils.ts +51 -46
  48. package/src/client/contexts.tsx +95 -0
  49. package/src/client/index.tsx +24 -0
  50. package/src/client/sidebarUtils.test.ts +52 -0
  51. package/src/client/sidebarUtils.tsx +85 -0
  52. package/src/client/structuredDataUtils.ts +178 -0
  53. package/src/feed.ts +197 -18
  54. package/src/frontMatter.ts +2 -0
  55. package/src/index.ts +182 -137
  56. package/src/markdownLoader.ts +3 -7
  57. package/src/options.ts +132 -32
  58. package/src/plugin-content-blog.d.ts +252 -113
  59. package/src/props.ts +41 -1
  60. package/src/routes.ts +102 -12
  61. package/src/types.ts +1 -6
  62. package/src/client/index.ts +0 -20
package/src/options.ts CHANGED
@@ -5,10 +5,12 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
+ import path from 'path';
8
9
  import {
9
10
  Joi,
10
11
  RemarkPluginsSchema,
11
12
  RehypePluginsSchema,
13
+ RecmaPluginsSchema,
12
14
  AdmonitionsSchema,
13
15
  RouteBasePathSchema,
14
16
  URISchema,
@@ -18,20 +20,32 @@ import type {
18
20
  PluginOptions,
19
21
  Options,
20
22
  FeedType,
23
+ FeedXSLTOptions,
21
24
  } from '@docusaurus/plugin-content-blog';
22
25
  import type {OptionValidationContext} from '@docusaurus/types';
23
26
 
24
27
  export const DEFAULT_OPTIONS: PluginOptions = {
25
- feedOptions: {type: ['rss', 'atom'], copyright: '', limit: 20},
28
+ feedOptions: {
29
+ type: ['rss', 'atom'],
30
+ copyright: '',
31
+ limit: 20,
32
+ xslt: {
33
+ rss: null,
34
+ atom: null,
35
+ },
36
+ },
26
37
  beforeDefaultRehypePlugins: [],
27
38
  beforeDefaultRemarkPlugins: [],
28
39
  admonitions: true,
29
40
  truncateMarker: /<!--\s*truncate\s*-->|\{\/\*\s*truncate\s*\*\/\}/,
30
41
  rehypePlugins: [],
31
42
  remarkPlugins: [],
43
+ recmaPlugins: [],
32
44
  showReadingTime: true,
33
45
  blogTagsPostsComponent: '@theme/BlogTagsPostsPage',
34
46
  blogTagsListComponent: '@theme/BlogTagsListPage',
47
+ blogAuthorsPostsComponent: '@theme/Blog/Pages/BlogAuthorsPostsPage',
48
+ blogAuthorsListComponent: '@theme/Blog/Pages/BlogAuthorsListPage',
35
49
  blogPostComponent: '@theme/BlogPostPage',
36
50
  blogListComponent: '@theme/BlogListPage',
37
51
  blogArchiveComponent: '@theme/BlogArchivePage',
@@ -54,8 +68,101 @@ export const DEFAULT_OPTIONS: PluginOptions = {
54
68
  showLastUpdateTime: false,
55
69
  showLastUpdateAuthor: false,
56
70
  processBlogPosts: async () => undefined,
71
+ onInlineTags: 'warn',
72
+ tags: undefined,
73
+ authorsBasePath: 'authors',
74
+ onInlineAuthors: 'warn',
75
+ onUntruncatedBlogPosts: 'warn',
57
76
  };
58
77
 
78
+ export const XSLTBuiltInPaths = {
79
+ rss: path.resolve(__dirname, '..', 'assets', 'rss.xsl'),
80
+ atom: path.resolve(__dirname, '..', 'assets', 'atom.xsl'),
81
+ };
82
+
83
+ function normalizeXsltOption(
84
+ option: string | null | boolean,
85
+ type: 'rss' | 'atom',
86
+ ): string | null {
87
+ if (typeof option === 'string') {
88
+ return option;
89
+ }
90
+ if (option === true) {
91
+ return XSLTBuiltInPaths[type];
92
+ }
93
+ return null;
94
+ }
95
+
96
+ function createXSLTFilePathSchema(type: 'atom' | 'rss') {
97
+ return Joi.alternatives()
98
+ .try(
99
+ Joi.string().required(),
100
+ Joi.boolean()
101
+ .allow(null, () => undefined)
102
+ .custom((val) => normalizeXsltOption(val, type)),
103
+ )
104
+ .optional()
105
+ .default(null);
106
+ }
107
+
108
+ const FeedXSLTOptionsSchema = Joi.alternatives()
109
+ .try(
110
+ Joi.object<FeedXSLTOptions>({
111
+ rss: createXSLTFilePathSchema('rss'),
112
+ atom: createXSLTFilePathSchema('atom'),
113
+ }).required(),
114
+ Joi.boolean()
115
+ .allow(null, () => undefined)
116
+ .custom((val) => ({
117
+ rss: normalizeXsltOption(val, 'rss'),
118
+ atom: normalizeXsltOption(val, 'atom'),
119
+ })),
120
+ )
121
+ .optional()
122
+ .custom((val) => {
123
+ if (val === null) {
124
+ return {
125
+ rss: null,
126
+ atom: null,
127
+ };
128
+ }
129
+ return val;
130
+ })
131
+ .default(DEFAULT_OPTIONS.feedOptions.xslt);
132
+
133
+ const FeedOptionsSchema = Joi.object({
134
+ type: Joi.alternatives()
135
+ .try(
136
+ Joi.array().items(Joi.string().equal('rss', 'atom', 'json')),
137
+ Joi.alternatives().conditional(
138
+ Joi.string().equal('all', 'rss', 'atom', 'json'),
139
+ {
140
+ then: Joi.custom((val: FeedType | 'all') =>
141
+ val === 'all' ? ['rss', 'atom', 'json'] : [val],
142
+ ),
143
+ },
144
+ ),
145
+ )
146
+ .allow(null)
147
+ .default(DEFAULT_OPTIONS.feedOptions.type),
148
+ xslt: FeedXSLTOptionsSchema,
149
+ title: Joi.string().allow(''),
150
+ description: Joi.string().allow(''),
151
+ // Only add default value when user actually wants a feed (type is not null)
152
+ copyright: Joi.when('type', {
153
+ is: Joi.any().valid(null),
154
+ then: Joi.string().optional(),
155
+ otherwise: Joi.string()
156
+ .allow('')
157
+ .default(DEFAULT_OPTIONS.feedOptions.copyright),
158
+ }),
159
+ language: Joi.string(),
160
+ createFeedItems: Joi.function(),
161
+ limit: Joi.alternatives()
162
+ .try(Joi.number(), Joi.valid(null), Joi.valid(false))
163
+ .default(DEFAULT_OPTIONS.feedOptions.limit),
164
+ }).default(DEFAULT_OPTIONS.feedOptions);
165
+
59
166
  const PluginOptionSchema = Joi.object<PluginOptions>({
60
167
  path: Joi.string().default(DEFAULT_OPTIONS.path),
61
168
  archiveBasePath: Joi.string()
@@ -77,6 +184,12 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
77
184
  blogTagsPostsComponent: Joi.string().default(
78
185
  DEFAULT_OPTIONS.blogTagsPostsComponent,
79
186
  ),
187
+ blogAuthorsPostsComponent: Joi.string().default(
188
+ DEFAULT_OPTIONS.blogAuthorsPostsComponent,
189
+ ),
190
+ blogAuthorsListComponent: Joi.string().default(
191
+ DEFAULT_OPTIONS.blogAuthorsListComponent,
192
+ ),
80
193
  blogArchiveComponent: Joi.string().default(
81
194
  DEFAULT_OPTIONS.blogArchiveComponent,
82
195
  ),
@@ -91,6 +204,7 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
91
204
  showReadingTime: Joi.bool().default(DEFAULT_OPTIONS.showReadingTime),
92
205
  remarkPlugins: RemarkPluginsSchema.default(DEFAULT_OPTIONS.remarkPlugins),
93
206
  rehypePlugins: RehypePluginsSchema.default(DEFAULT_OPTIONS.rehypePlugins),
207
+ recmaPlugins: RecmaPluginsSchema.default(DEFAULT_OPTIONS.recmaPlugins),
94
208
  admonitions: AdmonitionsSchema.default(DEFAULT_OPTIONS.admonitions),
95
209
  editUrl: Joi.alternatives().try(URISchema, Joi.function()),
96
210
  editLocalizedFiles: Joi.boolean().default(DEFAULT_OPTIONS.editLocalizedFiles),
@@ -101,37 +215,7 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
101
215
  beforeDefaultRehypePlugins: RehypePluginsSchema.default(
102
216
  DEFAULT_OPTIONS.beforeDefaultRehypePlugins,
103
217
  ),
104
- feedOptions: Joi.object({
105
- type: Joi.alternatives()
106
- .try(
107
- Joi.array().items(Joi.string().equal('rss', 'atom', 'json')),
108
- Joi.alternatives().conditional(
109
- Joi.string().equal('all', 'rss', 'atom', 'json'),
110
- {
111
- then: Joi.custom((val: FeedType | 'all') =>
112
- val === 'all' ? ['rss', 'atom', 'json'] : [val],
113
- ),
114
- },
115
- ),
116
- )
117
- .allow(null)
118
- .default(DEFAULT_OPTIONS.feedOptions.type),
119
- title: Joi.string().allow(''),
120
- description: Joi.string().allow(''),
121
- // Only add default value when user actually wants a feed (type is not null)
122
- copyright: Joi.when('type', {
123
- is: Joi.any().valid(null),
124
- then: Joi.string().optional(),
125
- otherwise: Joi.string()
126
- .allow('')
127
- .default(DEFAULT_OPTIONS.feedOptions.copyright),
128
- }),
129
- language: Joi.string(),
130
- createFeedItems: Joi.function(),
131
- limit: Joi.alternatives()
132
- .try(Joi.number(), Joi.valid(null), Joi.valid(false))
133
- .default(DEFAULT_OPTIONS.feedOptions.limit),
134
- }).default(DEFAULT_OPTIONS.feedOptions),
218
+ feedOptions: FeedOptionsSchema,
135
219
  authorsMapPath: Joi.string().default(DEFAULT_OPTIONS.authorsMapPath),
136
220
  readingTime: Joi.function().default(() => DEFAULT_OPTIONS.readingTime),
137
221
  sortPosts: Joi.string()
@@ -144,6 +228,22 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
144
228
  processBlogPosts: Joi.function()
145
229
  .optional()
146
230
  .default(() => DEFAULT_OPTIONS.processBlogPosts),
231
+ onInlineTags: Joi.string()
232
+ .equal('ignore', 'log', 'warn', 'throw')
233
+ .default(DEFAULT_OPTIONS.onInlineTags),
234
+ tags: Joi.string()
235
+ .disallow('')
236
+ .allow(null, false)
237
+ .default(() => DEFAULT_OPTIONS.tags),
238
+ authorsBasePath: Joi.string()
239
+ .default(DEFAULT_OPTIONS.authorsBasePath)
240
+ .disallow(''),
241
+ onInlineAuthors: Joi.string()
242
+ .equal('ignore', 'log', 'warn', 'throw')
243
+ .default(DEFAULT_OPTIONS.onInlineAuthors),
244
+ onUntruncatedBlogPosts: Joi.string()
245
+ .equal('ignore', 'log', 'warn', 'throw')
246
+ .default(DEFAULT_OPTIONS.onUntruncatedBlogPosts),
147
247
  }).default(DEFAULT_OPTIONS);
148
248
 
149
249
  export function validateOptions({