@docusaurus/plugin-content-blog 0.0.0-5982 → 0.0.0-5985

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.
@@ -0,0 +1,21 @@
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
+ import type { Author, PluginOptions } from '@docusaurus/plugin-content-blog';
8
+ export declare function reportAuthorsProblems(params: {
9
+ authors: Author[];
10
+ blogSourceRelative: string;
11
+ options: Pick<PluginOptions, 'onInlineAuthors' | 'authorsMapPath'>;
12
+ }): void;
13
+ export declare function reportInlineAuthors({ authors, blogSourceRelative, options: { onInlineAuthors, authorsMapPath }, }: {
14
+ authors: Author[];
15
+ blogSourceRelative: string;
16
+ options: Pick<PluginOptions, 'onInlineAuthors' | 'authorsMapPath'>;
17
+ }): void;
18
+ export declare function reportDuplicateAuthors({ authors, blogSourceRelative, }: {
19
+ authors: Author[];
20
+ blogSourceRelative: string;
21
+ }): void;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Facebook, Inc. and its affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.reportAuthorsProblems = reportAuthorsProblems;
10
+ exports.reportInlineAuthors = reportInlineAuthors;
11
+ exports.reportDuplicateAuthors = reportDuplicateAuthors;
12
+ const tslib_1 = require("tslib");
13
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
14
+ const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
15
+ function reportAuthorsProblems(params) {
16
+ reportInlineAuthors(params);
17
+ reportDuplicateAuthors(params);
18
+ }
19
+ function reportInlineAuthors({ authors, blogSourceRelative, options: { onInlineAuthors, authorsMapPath }, }) {
20
+ if (onInlineAuthors === 'ignore') {
21
+ return;
22
+ }
23
+ const inlineAuthors = authors.filter((author) => !author.key);
24
+ if (inlineAuthors.length > 0) {
25
+ logger_1.default.report(onInlineAuthors)(logger_1.default.interpolate `Some blog authors used in path=${blogSourceRelative} are not defined in path=${authorsMapPath}:
26
+ - ${inlineAuthors.map(authorToString).join('\n- ')}
27
+
28
+ Note that we recommend to declare authors once in a path=${authorsMapPath} file and reference them by key in blog posts front matter to avoid author info duplication.
29
+ But if you want to allow inline blog authors, you can disable this message by setting onInlineAuthors: 'ignore' in your blog plugin options.
30
+ More info at url=${'https://docusaurus.io/docs/blog'}
31
+ `);
32
+ }
33
+ }
34
+ function reportDuplicateAuthors({ authors, blogSourceRelative, }) {
35
+ const duplicateAuthors = (0, lodash_1.default)(authors)
36
+ // for now we only check for predefined authors duplicates
37
+ .filter((author) => !!author.key)
38
+ .groupBy((author) => author.key)
39
+ .pickBy((authorsByKey) => authorsByKey.length > 1)
40
+ // We only keep the "test" of all the duplicate groups
41
+ // The first author of a group is not really a duplicate...
42
+ .flatMap(([, ...rest]) => rest)
43
+ .value();
44
+ if (duplicateAuthors.length > 0) {
45
+ throw new Error(logger_1.default.interpolate `Duplicate blog post authors were found in blog post path=${blogSourceRelative} front matter:
46
+ - ${duplicateAuthors.map(authorToString).join('\n- ')}`);
47
+ }
48
+ }
49
+ function authorToString(author) {
50
+ return JSON.stringify(author);
51
+ }
package/lib/blogUtils.js CHANGED
@@ -23,6 +23,7 @@ const utils_1 = require("@docusaurus/utils");
23
23
  const utils_validation_1 = require("@docusaurus/utils-validation");
24
24
  const frontMatter_1 = require("./frontMatter");
25
25
  const authors_1 = require("./authors");
26
+ const authorsProblems_1 = require("./authorsProblems");
26
27
  function truncate(fileString, truncateMarker) {
27
28
  return fileString.split(truncateMarker, 1).shift();
28
29
  }
@@ -196,6 +197,11 @@ async function processBlogSourceFile(blogSourceRelative, contentPaths, context,
196
197
  tagsRouteBasePath,
197
198
  ]);
198
199
  const authors = (0, authors_1.getBlogPostAuthors)({ authorsMap, frontMatter, baseUrl });
200
+ (0, authorsProblems_1.reportAuthorsProblems)({
201
+ authors,
202
+ blogSourceRelative,
203
+ options,
204
+ });
199
205
  const tags = (0, utils_1.normalizeTags)({
200
206
  options,
201
207
  source: blogSourceRelative,
package/lib/index.js CHANGED
@@ -162,13 +162,14 @@ async function pluginContentBlog(context, options) {
162
162
  return (0, translations_1.translateContent)(content, translationFiles);
163
163
  },
164
164
  configureWebpack() {
165
- const { admonitions, rehypePlugins, remarkPlugins, truncateMarker, beforeDefaultRemarkPlugins, beforeDefaultRehypePlugins, } = options;
165
+ const { admonitions, rehypePlugins, remarkPlugins, recmaPlugins, truncateMarker, beforeDefaultRemarkPlugins, beforeDefaultRehypePlugins, } = options;
166
166
  const contentDirs = (0, utils_1.getContentPathList)(contentPaths);
167
167
  function createMDXLoader() {
168
168
  const loaderOptions = {
169
169
  admonitions,
170
170
  remarkPlugins,
171
171
  rehypePlugins,
172
+ recmaPlugins,
172
173
  beforeDefaultRemarkPlugins: [
173
174
  footnoteIDFixer_1.default,
174
175
  ...beforeDefaultRemarkPlugins,
package/lib/options.js CHANGED
@@ -18,6 +18,7 @@ exports.DEFAULT_OPTIONS = {
18
18
  truncateMarker: /<!--\s*truncate\s*-->|\{\/\*\s*truncate\s*\*\/\}/,
19
19
  rehypePlugins: [],
20
20
  remarkPlugins: [],
21
+ recmaPlugins: [],
21
22
  showReadingTime: true,
22
23
  blogTagsPostsComponent: '@theme/BlogTagsPostsPage',
23
24
  blogTagsListComponent: '@theme/BlogTagsListPage',
@@ -45,6 +46,7 @@ exports.DEFAULT_OPTIONS = {
45
46
  processBlogPosts: async () => undefined,
46
47
  onInlineTags: 'warn',
47
48
  tags: undefined,
49
+ onInlineAuthors: 'warn',
48
50
  };
49
51
  const PluginOptionSchema = utils_validation_1.Joi.object({
50
52
  path: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.path),
@@ -75,6 +77,7 @@ const PluginOptionSchema = utils_validation_1.Joi.object({
75
77
  showReadingTime: utils_validation_1.Joi.bool().default(exports.DEFAULT_OPTIONS.showReadingTime),
76
78
  remarkPlugins: utils_validation_1.RemarkPluginsSchema.default(exports.DEFAULT_OPTIONS.remarkPlugins),
77
79
  rehypePlugins: utils_validation_1.RehypePluginsSchema.default(exports.DEFAULT_OPTIONS.rehypePlugins),
80
+ recmaPlugins: utils_validation_1.RecmaPluginsSchema.default(exports.DEFAULT_OPTIONS.recmaPlugins),
78
81
  admonitions: utils_validation_1.AdmonitionsSchema.default(exports.DEFAULT_OPTIONS.admonitions),
79
82
  editUrl: utils_validation_1.Joi.alternatives().try(utils_validation_1.URISchema, utils_validation_1.Joi.function()),
80
83
  editLocalizedFiles: utils_validation_1.Joi.boolean().default(exports.DEFAULT_OPTIONS.editLocalizedFiles),
@@ -121,6 +124,9 @@ const PluginOptionSchema = utils_validation_1.Joi.object({
121
124
  .disallow('')
122
125
  .allow(null, false)
123
126
  .default(() => exports.DEFAULT_OPTIONS.tags),
127
+ onInlineAuthors: utils_validation_1.Joi.string()
128
+ .equal('ignore', 'log', 'warn', 'throw')
129
+ .default(exports.DEFAULT_OPTIONS.onInlineAuthors),
124
130
  }).default(exports.DEFAULT_OPTIONS);
125
131
  function validateOptions({ validate, options, }) {
126
132
  const validatedOptions = validate(PluginOptionSchema, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docusaurus/plugin-content-blog",
3
- "version": "0.0.0-5982",
3
+ "version": "0.0.0-5985",
4
4
  "description": "Blog plugin for Docusaurus.",
5
5
  "main": "lib/index.js",
6
6
  "types": "src/plugin-content-blog.d.ts",
@@ -31,13 +31,13 @@
31
31
  },
32
32
  "license": "MIT",
33
33
  "dependencies": {
34
- "@docusaurus/core": "0.0.0-5982",
35
- "@docusaurus/logger": "0.0.0-5982",
36
- "@docusaurus/mdx-loader": "0.0.0-5982",
37
- "@docusaurus/types": "0.0.0-5982",
38
- "@docusaurus/utils": "0.0.0-5982",
39
- "@docusaurus/utils-common": "0.0.0-5982",
40
- "@docusaurus/utils-validation": "0.0.0-5982",
34
+ "@docusaurus/core": "0.0.0-5985",
35
+ "@docusaurus/logger": "0.0.0-5985",
36
+ "@docusaurus/mdx-loader": "0.0.0-5985",
37
+ "@docusaurus/types": "0.0.0-5985",
38
+ "@docusaurus/utils": "0.0.0-5985",
39
+ "@docusaurus/utils-common": "0.0.0-5985",
40
+ "@docusaurus/utils-validation": "0.0.0-5985",
41
41
  "cheerio": "^1.0.0-rc.12",
42
42
  "feed": "^4.2.2",
43
43
  "fs-extra": "^11.1.1",
@@ -59,5 +59,5 @@
59
59
  "devDependencies": {
60
60
  "@total-typescript/shoehorn": "^0.1.2"
61
61
  },
62
- "gitHead": "8b6a944282857a6fc8e184e8b56109238ce50924"
62
+ "gitHead": "01e2896b49cfb78bed86b3c8854728377792a90a"
63
63
  }
@@ -0,0 +1,72 @@
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 _ from 'lodash';
9
+ import logger from '@docusaurus/logger';
10
+ import type {Author, PluginOptions} from '@docusaurus/plugin-content-blog';
11
+
12
+ export function reportAuthorsProblems(params: {
13
+ authors: Author[];
14
+ blogSourceRelative: string;
15
+ options: Pick<PluginOptions, 'onInlineAuthors' | 'authorsMapPath'>;
16
+ }): void {
17
+ reportInlineAuthors(params);
18
+ reportDuplicateAuthors(params);
19
+ }
20
+
21
+ export function reportInlineAuthors({
22
+ authors,
23
+ blogSourceRelative,
24
+ options: {onInlineAuthors, authorsMapPath},
25
+ }: {
26
+ authors: Author[];
27
+ blogSourceRelative: string;
28
+ options: Pick<PluginOptions, 'onInlineAuthors' | 'authorsMapPath'>;
29
+ }): void {
30
+ if (onInlineAuthors === 'ignore') {
31
+ return;
32
+ }
33
+ const inlineAuthors = authors.filter((author) => !author.key);
34
+ if (inlineAuthors.length > 0) {
35
+ logger.report(onInlineAuthors)(
36
+ logger.interpolate`Some blog authors used in path=${blogSourceRelative} are not defined in path=${authorsMapPath}:
37
+ - ${inlineAuthors.map(authorToString).join('\n- ')}
38
+
39
+ Note that we recommend to declare authors once in a path=${authorsMapPath} file and reference them by key in blog posts front matter to avoid author info duplication.
40
+ But if you want to allow inline blog authors, you can disable this message by setting onInlineAuthors: 'ignore' in your blog plugin options.
41
+ More info at url=${'https://docusaurus.io/docs/blog'}
42
+ `,
43
+ );
44
+ }
45
+ }
46
+
47
+ export function reportDuplicateAuthors({
48
+ authors,
49
+ blogSourceRelative,
50
+ }: {
51
+ authors: Author[];
52
+ blogSourceRelative: string;
53
+ }): void {
54
+ const duplicateAuthors = _(authors)
55
+ // for now we only check for predefined authors duplicates
56
+ .filter((author) => !!author.key)
57
+ .groupBy((author) => author.key)
58
+ .pickBy((authorsByKey) => authorsByKey.length > 1)
59
+ // We only keep the "test" of all the duplicate groups
60
+ // The first author of a group is not really a duplicate...
61
+ .flatMap(([, ...rest]) => rest)
62
+ .value();
63
+
64
+ if (duplicateAuthors.length > 0) {
65
+ throw new Error(logger.interpolate`Duplicate blog post authors were found in blog post path=${blogSourceRelative} front matter:
66
+ - ${duplicateAuthors.map(authorToString).join('\n- ')}`);
67
+ }
68
+ }
69
+
70
+ function authorToString(author: Author) {
71
+ return JSON.stringify(author);
72
+ }
package/src/blogUtils.ts CHANGED
@@ -30,6 +30,7 @@ import {
30
30
  import {getTagsFile} from '@docusaurus/utils-validation';
31
31
  import {validateBlogPostFrontMatter} from './frontMatter';
32
32
  import {type AuthorsMap, getAuthorsMap, getBlogPostAuthors} from './authors';
33
+ import {reportAuthorsProblems} from './authorsProblems';
33
34
  import type {TagsFile} from '@docusaurus/utils';
34
35
  import type {LoadContext, ParseFrontMatter} from '@docusaurus/types';
35
36
  import type {
@@ -317,7 +318,13 @@ async function processBlogSourceFile(
317
318
  routeBasePath,
318
319
  tagsRouteBasePath,
319
320
  ]);
321
+
320
322
  const authors = getBlogPostAuthors({authorsMap, frontMatter, baseUrl});
323
+ reportAuthorsProblems({
324
+ authors,
325
+ blogSourceRelative,
326
+ options,
327
+ });
321
328
 
322
329
  const tags = normalizeTags({
323
330
  options,
package/src/index.ts CHANGED
@@ -250,6 +250,7 @@ export default async function pluginContentBlog(
250
250
  admonitions,
251
251
  rehypePlugins,
252
252
  remarkPlugins,
253
+ recmaPlugins,
253
254
  truncateMarker,
254
255
  beforeDefaultRemarkPlugins,
255
256
  beforeDefaultRehypePlugins,
@@ -262,6 +263,7 @@ export default async function pluginContentBlog(
262
263
  admonitions,
263
264
  remarkPlugins,
264
265
  rehypePlugins,
266
+ recmaPlugins,
265
267
  beforeDefaultRemarkPlugins: [
266
268
  footnoteIDFixer,
267
269
  ...beforeDefaultRemarkPlugins,
package/src/options.ts CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  Joi,
10
10
  RemarkPluginsSchema,
11
11
  RehypePluginsSchema,
12
+ RecmaPluginsSchema,
12
13
  AdmonitionsSchema,
13
14
  RouteBasePathSchema,
14
15
  URISchema,
@@ -29,6 +30,7 @@ export const DEFAULT_OPTIONS: PluginOptions = {
29
30
  truncateMarker: /<!--\s*truncate\s*-->|\{\/\*\s*truncate\s*\*\/\}/,
30
31
  rehypePlugins: [],
31
32
  remarkPlugins: [],
33
+ recmaPlugins: [],
32
34
  showReadingTime: true,
33
35
  blogTagsPostsComponent: '@theme/BlogTagsPostsPage',
34
36
  blogTagsListComponent: '@theme/BlogTagsListPage',
@@ -56,6 +58,7 @@ export const DEFAULT_OPTIONS: PluginOptions = {
56
58
  processBlogPosts: async () => undefined,
57
59
  onInlineTags: 'warn',
58
60
  tags: undefined,
61
+ onInlineAuthors: 'warn',
59
62
  };
60
63
 
61
64
  const PluginOptionSchema = Joi.object<PluginOptions>({
@@ -93,6 +96,7 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
93
96
  showReadingTime: Joi.bool().default(DEFAULT_OPTIONS.showReadingTime),
94
97
  remarkPlugins: RemarkPluginsSchema.default(DEFAULT_OPTIONS.remarkPlugins),
95
98
  rehypePlugins: RehypePluginsSchema.default(DEFAULT_OPTIONS.rehypePlugins),
99
+ recmaPlugins: RecmaPluginsSchema.default(DEFAULT_OPTIONS.recmaPlugins),
96
100
  admonitions: AdmonitionsSchema.default(DEFAULT_OPTIONS.admonitions),
97
101
  editUrl: Joi.alternatives().try(URISchema, Joi.function()),
98
102
  editLocalizedFiles: Joi.boolean().default(DEFAULT_OPTIONS.editLocalizedFiles),
@@ -153,6 +157,9 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
153
157
  .disallow('')
154
158
  .allow(null, false)
155
159
  .default(() => DEFAULT_OPTIONS.tags),
160
+ onInlineAuthors: Joi.string()
161
+ .equal('ignore', 'log', 'warn', 'throw')
162
+ .default(DEFAULT_OPTIONS.onInlineAuthors),
156
163
  }).default(DEFAULT_OPTIONS);
157
164
 
158
165
  export function validateOptions({
@@ -44,6 +44,8 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
44
44
  };
45
45
 
46
46
  export type Author = {
47
+ key?: string; // TODO temporary, need refactor
48
+
47
49
  /**
48
50
  * If `name` doesn't exist, an `imageURL` is expected.
49
51
  */
@@ -442,6 +444,8 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
442
444
  * (filter, modify, delete, etc...).
443
445
  */
444
446
  processBlogPosts: ProcessBlogPostsFn;
447
+ /** The behavior of Docusaurus when it finds inline authors. */
448
+ onInlineAuthors: 'ignore' | 'log' | 'warn' | 'throw';
445
449
  };
446
450
 
447
451
  /**