@docusaurus/plugin-content-blog 2.0.0-beta.6f366f4b4 → 2.0.0-beta.7
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 +150 -0
- package/lib/blogFrontMatter.d.ts +19 -6
- package/lib/blogFrontMatter.js +31 -19
- package/lib/blogUtils.d.ts +10 -2
- package/lib/blogUtils.js +146 -104
- package/lib/index.js +76 -70
- package/lib/markdownLoader.js +3 -3
- package/lib/pluginOptionSchema.d.ts +3 -27
- package/lib/pluginOptionSchema.js +19 -7
- package/lib/translations.d.ts +10 -0
- package/lib/translations.js +53 -0
- package/lib/types.d.ts +37 -14
- package/package.json +13 -11
- 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/authors.yml +4 -0
- package/src/__tests__/__fixtures__/website/blog/mdx-blog-post.mdx +36 -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__/__snapshots__/generateBlogFeed.test.ts.snap +41 -3
- 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 +4 -0
- package/src/__tests__/index.test.ts +63 -12
- package/src/__tests__/pluginOptionSchema.test.ts +3 -3
- package/src/__tests__/translations.test.ts +92 -0
- package/src/authors.ts +202 -0
- package/src/blogFrontMatter.ts +73 -33
- package/src/blogUtils.ts +205 -132
- package/src/index.ts +92 -61
- package/{index.d.ts → src/plugin-content-blog.d.ts} +35 -31
- package/src/pluginOptionSchema.ts +22 -9
- package/src/translations.ts +63 -0
- package/src/types.ts +47 -16
package/lib/blogFrontMatter.js
CHANGED
|
@@ -7,44 +7,56 @@
|
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.validateBlogPostFrontMatter = void 0;
|
|
10
|
-
/* eslint-disable camelcase */
|
|
11
10
|
const utils_validation_1 = require("@docusaurus/utils-validation");
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
const BlogPostFrontMatterAuthorSchema = utils_validation_1.JoiFrontMatter.object({
|
|
12
|
+
key: utils_validation_1.JoiFrontMatter.string(),
|
|
13
|
+
name: utils_validation_1.JoiFrontMatter.string(),
|
|
14
|
+
title: utils_validation_1.JoiFrontMatter.string(),
|
|
15
|
+
url: utils_validation_1.URISchema,
|
|
16
|
+
imageURL: utils_validation_1.JoiFrontMatter.string(),
|
|
17
|
+
})
|
|
18
|
+
.or('key', 'name')
|
|
19
|
+
.rename('image_url', 'imageURL', { alias: true });
|
|
20
|
+
const FrontMatterAuthorErrorMessage = '{{#label}} does not look like a valid blog post author. Please use an author key or an author object (with a key and/or name).';
|
|
20
21
|
const BlogFrontMatterSchema = utils_validation_1.JoiFrontMatter.object({
|
|
21
22
|
id: utils_validation_1.JoiFrontMatter.string(),
|
|
22
23
|
title: utils_validation_1.JoiFrontMatter.string().allow(''),
|
|
23
24
|
description: utils_validation_1.JoiFrontMatter.string().allow(''),
|
|
24
|
-
tags: utils_validation_1.
|
|
25
|
+
tags: utils_validation_1.FrontMatterTagsSchema,
|
|
25
26
|
draft: utils_validation_1.JoiFrontMatter.boolean(),
|
|
26
27
|
date: utils_validation_1.JoiFrontMatter.date().raw(),
|
|
28
|
+
// New multi-authors frontmatter:
|
|
29
|
+
authors: utils_validation_1.JoiFrontMatter.alternatives()
|
|
30
|
+
.try(utils_validation_1.JoiFrontMatter.string(), BlogPostFrontMatterAuthorSchema, utils_validation_1.JoiFrontMatter.array()
|
|
31
|
+
.items(utils_validation_1.JoiFrontMatter.string(), BlogPostFrontMatterAuthorSchema)
|
|
32
|
+
.messages({
|
|
33
|
+
'array.sparse': FrontMatterAuthorErrorMessage,
|
|
34
|
+
'array.includes': FrontMatterAuthorErrorMessage,
|
|
35
|
+
}))
|
|
36
|
+
.messages({
|
|
37
|
+
'alternatives.match': FrontMatterAuthorErrorMessage,
|
|
38
|
+
}),
|
|
39
|
+
// Legacy author frontmatter
|
|
27
40
|
author: utils_validation_1.JoiFrontMatter.string(),
|
|
28
41
|
author_title: utils_validation_1.JoiFrontMatter.string(),
|
|
29
42
|
author_url: utils_validation_1.URISchema,
|
|
30
43
|
author_image_url: utils_validation_1.URISchema,
|
|
31
|
-
|
|
32
|
-
image: utils_validation_1.URISchema,
|
|
33
|
-
keywords: utils_validation_1.JoiFrontMatter.array().items(utils_validation_1.JoiFrontMatter.string().required()),
|
|
34
|
-
hide_table_of_contents: utils_validation_1.JoiFrontMatter.boolean(),
|
|
35
|
-
// TODO re-enable warnings later, our v1 blog posts use those older frontmatter fields
|
|
44
|
+
// TODO enable deprecation warnings later
|
|
36
45
|
authorURL: utils_validation_1.URISchema,
|
|
37
46
|
// .warning('deprecate.error', { alternative: '"author_url"'}),
|
|
38
47
|
authorTitle: utils_validation_1.JoiFrontMatter.string(),
|
|
39
48
|
// .warning('deprecate.error', { alternative: '"author_title"'}),
|
|
40
49
|
authorImageURL: utils_validation_1.URISchema,
|
|
41
50
|
// .warning('deprecate.error', { alternative: '"author_image_url"'}),
|
|
42
|
-
|
|
43
|
-
.
|
|
44
|
-
.
|
|
51
|
+
slug: utils_validation_1.JoiFrontMatter.string(),
|
|
52
|
+
image: utils_validation_1.URISchema,
|
|
53
|
+
keywords: utils_validation_1.JoiFrontMatter.array().items(utils_validation_1.JoiFrontMatter.string().required()),
|
|
54
|
+
hide_table_of_contents: utils_validation_1.JoiFrontMatter.boolean(),
|
|
55
|
+
...utils_validation_1.FrontMatterTOCHeadingLevels,
|
|
56
|
+
}).messages({
|
|
45
57
|
'deprecate.error': '{#label} blog frontMatter field is deprecated. Please use {#alternative} instead.',
|
|
46
58
|
});
|
|
47
59
|
function validateBlogPostFrontMatter(frontMatter) {
|
|
48
|
-
return utils_validation_1.validateFrontMatter(frontMatter, BlogFrontMatterSchema);
|
|
60
|
+
return (0, utils_validation_1.validateFrontMatter)(frontMatter, BlogFrontMatterSchema);
|
|
49
61
|
}
|
|
50
62
|
exports.validateBlogPostFrontMatter = validateBlogPostFrontMatter;
|
package/lib/blogUtils.d.ts
CHANGED
|
@@ -5,15 +5,23 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import { Feed } from 'feed';
|
|
8
|
-
import { PluginOptions, BlogPost, BlogContentPaths, BlogMarkdownLoaderOptions } from './types';
|
|
8
|
+
import { PluginOptions, BlogPost, BlogContentPaths, BlogMarkdownLoaderOptions, BlogTags } from './types';
|
|
9
9
|
import { LoadContext } from '@docusaurus/types';
|
|
10
10
|
export declare function truncate(fileString: string, truncateMarker: RegExp): string;
|
|
11
11
|
export declare function getSourceToPermalink(blogPosts: BlogPost[]): Record<string, string>;
|
|
12
|
+
export declare function getBlogTags(blogPosts: BlogPost[]): BlogTags;
|
|
13
|
+
declare type ParsedBlogFileName = {
|
|
14
|
+
date: Date | undefined;
|
|
15
|
+
text: string;
|
|
16
|
+
slug: string;
|
|
17
|
+
};
|
|
18
|
+
export declare function parseBlogFileName(blogSourceRelative: string): ParsedBlogFileName;
|
|
12
19
|
export declare function generateBlogFeed(contentPaths: BlogContentPaths, context: LoadContext, options: PluginOptions): Promise<Feed | null>;
|
|
13
|
-
export declare function generateBlogPosts(contentPaths: BlogContentPaths,
|
|
20
|
+
export declare function generateBlogPosts(contentPaths: BlogContentPaths, context: LoadContext, options: PluginOptions): Promise<BlogPost[]>;
|
|
14
21
|
export declare type LinkifyParams = {
|
|
15
22
|
filePath: string;
|
|
16
23
|
fileString: string;
|
|
17
24
|
} & Pick<BlogMarkdownLoaderOptions, 'sourceToPermalink' | 'siteDir' | 'contentPaths' | 'onBrokenMarkdownLink'>;
|
|
18
25
|
export declare function linkify({ filePath, contentPaths, fileString, siteDir, sourceToPermalink, onBrokenMarkdownLink, }: LinkifyParams): string;
|
|
19
26
|
export declare function getContentPathList(contentPaths: BlogContentPaths): string[];
|
|
27
|
+
export {};
|
package/lib/blogUtils.js
CHANGED
|
@@ -6,33 +6,55 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.getContentPathList = exports.linkify = exports.generateBlogPosts = exports.generateBlogFeed = exports.getSourceToPermalink = exports.truncate = void 0;
|
|
9
|
+
exports.getContentPathList = exports.linkify = exports.generateBlogPosts = exports.generateBlogFeed = exports.parseBlogFileName = exports.getBlogTags = exports.getSourceToPermalink = exports.truncate = void 0;
|
|
10
10
|
const tslib_1 = require("tslib");
|
|
11
|
-
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
12
|
-
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
13
|
-
const path_1 = tslib_1.__importDefault(require("path"));
|
|
14
|
-
const reading_time_1 = tslib_1.__importDefault(require("reading-time"));
|
|
11
|
+
const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
|
|
12
|
+
const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
|
|
13
|
+
const path_1 = (0, tslib_1.__importDefault)(require("path"));
|
|
14
|
+
const reading_time_1 = (0, tslib_1.__importDefault)(require("reading-time"));
|
|
15
15
|
const feed_1 = require("feed");
|
|
16
16
|
const lodash_1 = require("lodash");
|
|
17
17
|
const utils_1 = require("@docusaurus/utils");
|
|
18
18
|
const blogFrontMatter_1 = require("./blogFrontMatter");
|
|
19
|
+
const authors_1 = require("./authors");
|
|
19
20
|
function truncate(fileString, truncateMarker) {
|
|
20
21
|
return fileString.split(truncateMarker, 1).shift();
|
|
21
22
|
}
|
|
22
23
|
exports.truncate = truncate;
|
|
23
24
|
function getSourceToPermalink(blogPosts) {
|
|
24
|
-
return lodash_1.mapValues(lodash_1.keyBy(blogPosts, (item) => item.metadata.source), (v) => v.metadata.permalink);
|
|
25
|
+
return (0, lodash_1.mapValues)((0, lodash_1.keyBy)(blogPosts, (item) => item.metadata.source), (v) => v.metadata.permalink);
|
|
25
26
|
}
|
|
26
27
|
exports.getSourceToPermalink = getSourceToPermalink;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
function getBlogTags(blogPosts) {
|
|
29
|
+
const groups = (0, utils_1.groupTaggedItems)(blogPosts, (blogPost) => blogPost.metadata.tags);
|
|
30
|
+
return (0, lodash_1.mapValues)(groups, (group) => {
|
|
31
|
+
return {
|
|
32
|
+
name: group.tag.label,
|
|
33
|
+
items: group.items.map((item) => item.id),
|
|
34
|
+
permalink: group.tag.permalink,
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
exports.getBlogTags = getBlogTags;
|
|
39
|
+
const DATE_FILENAME_REGEX = /^(?<date>\d{4}[-/]\d{1,2}[-/]\d{1,2})[-/]?(?<text>.*?)(\/index)?.mdx?$/;
|
|
40
|
+
function parseBlogFileName(blogSourceRelative) {
|
|
41
|
+
const dateFilenameMatch = blogSourceRelative.match(DATE_FILENAME_REGEX);
|
|
42
|
+
if (dateFilenameMatch) {
|
|
43
|
+
const dateString = dateFilenameMatch.groups.date;
|
|
44
|
+
const text = dateFilenameMatch.groups.text;
|
|
45
|
+
// Always treat dates as UTC by adding the `Z`
|
|
46
|
+
const date = new Date(`${dateString}Z`);
|
|
47
|
+
const slugDate = dateString.replace(/-/g, '/');
|
|
48
|
+
const slug = `/${slugDate}/${text}`;
|
|
49
|
+
return { date, text, slug };
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const text = blogSourceRelative.replace(/(\/index)?\.mdx?$/, '');
|
|
53
|
+
const slug = `/${text}`;
|
|
54
|
+
return { date: undefined, text, slug };
|
|
55
|
+
}
|
|
35
56
|
}
|
|
57
|
+
exports.parseBlogFileName = parseBlogFileName;
|
|
36
58
|
function formatBlogPostDate(locale, date) {
|
|
37
59
|
try {
|
|
38
60
|
return new Intl.DateTimeFormat(locale, {
|
|
@@ -57,7 +79,7 @@ async function generateBlogFeed(contentPaths, context, options) {
|
|
|
57
79
|
}
|
|
58
80
|
const { feedOptions, routeBasePath } = options;
|
|
59
81
|
const { url: siteUrl, baseUrl, title, favicon } = siteConfig;
|
|
60
|
-
const blogBaseUrl = utils_1.normalizeUrl([siteUrl, baseUrl, routeBasePath]);
|
|
82
|
+
const blogBaseUrl = (0, utils_1.normalizeUrl)([siteUrl, baseUrl, routeBasePath]);
|
|
61
83
|
const updated = (blogPosts[0] && blogPosts[0].metadata.date) ||
|
|
62
84
|
new Date('2015-10-25T16:29:00.000-07:00');
|
|
63
85
|
const feed = new feed_1.Feed({
|
|
@@ -67,126 +89,146 @@ async function generateBlogFeed(contentPaths, context, options) {
|
|
|
67
89
|
language: feedOptions.language,
|
|
68
90
|
link: blogBaseUrl,
|
|
69
91
|
description: feedOptions.description || `${siteConfig.title} Blog`,
|
|
70
|
-
favicon: favicon ? utils_1.normalizeUrl([siteUrl, baseUrl, favicon]) : undefined,
|
|
92
|
+
favicon: favicon ? (0, utils_1.normalizeUrl)([siteUrl, baseUrl, favicon]) : undefined,
|
|
71
93
|
copyright: feedOptions.copyright,
|
|
72
94
|
});
|
|
95
|
+
function toFeedAuthor(author) {
|
|
96
|
+
// TODO ask author emails?
|
|
97
|
+
// RSS feed requires email to render authors
|
|
98
|
+
return { name: author.name, link: author.url };
|
|
99
|
+
}
|
|
73
100
|
blogPosts.forEach((post) => {
|
|
74
|
-
const { id, metadata: { title: metadataTitle, permalink, date, description }, } = post;
|
|
101
|
+
const { id, metadata: { title: metadataTitle, permalink, date, description, authors }, } = post;
|
|
75
102
|
feed.addItem({
|
|
76
103
|
title: metadataTitle,
|
|
77
104
|
id,
|
|
78
|
-
link: utils_1.normalizeUrl([siteUrl, permalink]),
|
|
105
|
+
link: (0, utils_1.normalizeUrl)([siteUrl, permalink]),
|
|
79
106
|
date,
|
|
80
107
|
description,
|
|
108
|
+
content: (0, utils_1.mdxToHtml)(post.content),
|
|
109
|
+
author: authors.map(toFeedAuthor),
|
|
81
110
|
});
|
|
82
111
|
});
|
|
83
112
|
return feed;
|
|
84
113
|
}
|
|
85
114
|
exports.generateBlogFeed = generateBlogFeed;
|
|
86
|
-
async function
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
return [];
|
|
90
|
-
}
|
|
91
|
-
const { baseUrl = '' } = siteConfig;
|
|
92
|
-
const blogSourceFiles = await utils_1.Globby(include, {
|
|
93
|
-
cwd: contentPaths.contentPath,
|
|
94
|
-
ignore: exclude,
|
|
115
|
+
async function parseBlogPostMarkdownFile(blogSourceAbsolute) {
|
|
116
|
+
const result = await (0, utils_1.parseMarkdownFile)(blogSourceAbsolute, {
|
|
117
|
+
removeContentTitle: true,
|
|
95
118
|
});
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
// Always treat dates as UTC by adding the `Z`
|
|
119
|
-
date = new Date(`${dateString}Z`);
|
|
120
|
-
linkName = name;
|
|
121
|
-
}
|
|
119
|
+
return {
|
|
120
|
+
...result,
|
|
121
|
+
frontMatter: (0, blogFrontMatter_1.validateBlogPostFrontMatter)(result.frontMatter),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
async function processBlogSourceFile(blogSourceRelative, contentPaths, context, options, authorsMap) {
|
|
125
|
+
var _a, _b, _c, _d, _e;
|
|
126
|
+
const { siteConfig: { baseUrl }, siteDir, i18n, } = context;
|
|
127
|
+
const { routeBasePath, tagsBasePath: tagsRouteBasePath, truncateMarker, showReadingTime, editUrl, } = options;
|
|
128
|
+
// Lookup in localized folder in priority
|
|
129
|
+
const blogDirPath = await (0, utils_1.getFolderContainingFile)(getContentPathList(contentPaths), blogSourceRelative);
|
|
130
|
+
const blogSourceAbsolute = path_1.default.join(blogDirPath, blogSourceRelative);
|
|
131
|
+
const { frontMatter, content, contentTitle, excerpt } = await parseBlogPostMarkdownFile(blogSourceAbsolute);
|
|
132
|
+
const aliasedSource = (0, utils_1.aliasedSitePath)(blogSourceAbsolute, siteDir);
|
|
133
|
+
if (frontMatter.draft && process.env.NODE_ENV === 'production') {
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
if (frontMatter.id) {
|
|
137
|
+
console.warn(chalk_1.default.yellow(`"id" header option is deprecated in ${blogSourceRelative} file. Please use "slug" option instead.`));
|
|
138
|
+
}
|
|
139
|
+
const parsedBlogFileName = parseBlogFileName(blogSourceRelative);
|
|
140
|
+
async function getDate() {
|
|
122
141
|
// Prefer user-defined date.
|
|
123
142
|
if (frontMatter.date) {
|
|
124
|
-
|
|
143
|
+
return new Date(frontMatter.date);
|
|
125
144
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const formattedDate = formatBlogPostDate(i18n.currentLocale, date);
|
|
129
|
-
const title = (_b = (_a = frontMatter.title) !== null && _a !== void 0 ? _a : contentTitle) !== null && _b !== void 0 ? _b : linkName;
|
|
130
|
-
const description = (_d = (_c = frontMatter.description) !== null && _c !== void 0 ? _c : excerpt) !== null && _d !== void 0 ? _d : '';
|
|
131
|
-
const slug = frontMatter.slug ||
|
|
132
|
-
(dateFilenameMatch ? toUrl({ date, link: linkName }) : linkName);
|
|
133
|
-
const permalink = utils_1.normalizeUrl([baseUrl, routeBasePath, slug]);
|
|
134
|
-
function getBlogEditUrl() {
|
|
135
|
-
const blogPathRelative = path_1.default.relative(blogDirPath, path_1.default.resolve(source));
|
|
136
|
-
if (typeof editUrl === 'function') {
|
|
137
|
-
return editUrl({
|
|
138
|
-
blogDirPath: utils_1.posixPath(path_1.default.relative(siteDir, blogDirPath)),
|
|
139
|
-
blogPath: utils_1.posixPath(blogPathRelative),
|
|
140
|
-
permalink,
|
|
141
|
-
locale: i18n.currentLocale,
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
else if (typeof editUrl === 'string') {
|
|
145
|
-
const isLocalized = blogDirPath === contentPaths.contentPathLocalized;
|
|
146
|
-
const fileContentPath = isLocalized && options.editLocalizedFiles
|
|
147
|
-
? contentPaths.contentPathLocalized
|
|
148
|
-
: contentPaths.contentPath;
|
|
149
|
-
const contentPathEditUrl = utils_1.normalizeUrl([
|
|
150
|
-
editUrl,
|
|
151
|
-
utils_1.posixPath(path_1.default.relative(siteDir, fileContentPath)),
|
|
152
|
-
]);
|
|
153
|
-
return utils_1.getEditUrl(blogPathRelative, contentPathEditUrl);
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
return undefined;
|
|
157
|
-
}
|
|
145
|
+
else if (parsedBlogFileName.date) {
|
|
146
|
+
return parsedBlogFileName.date;
|
|
158
147
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
148
|
+
// Fallback to file create time
|
|
149
|
+
return (await fs_extra_1.default.stat(blogSourceAbsolute)).birthtime;
|
|
150
|
+
}
|
|
151
|
+
const date = await getDate();
|
|
152
|
+
const formattedDate = formatBlogPostDate(i18n.currentLocale, date);
|
|
153
|
+
const title = (_b = (_a = frontMatter.title) !== null && _a !== void 0 ? _a : contentTitle) !== null && _b !== void 0 ? _b : parsedBlogFileName.text;
|
|
154
|
+
const description = (_d = (_c = frontMatter.description) !== null && _c !== void 0 ? _c : excerpt) !== null && _d !== void 0 ? _d : '';
|
|
155
|
+
const slug = frontMatter.slug || parsedBlogFileName.slug;
|
|
156
|
+
const permalink = (0, utils_1.normalizeUrl)([baseUrl, routeBasePath, slug]);
|
|
157
|
+
function getBlogEditUrl() {
|
|
158
|
+
const blogPathRelative = path_1.default.relative(blogDirPath, path_1.default.resolve(blogSourceAbsolute));
|
|
159
|
+
if (typeof editUrl === 'function') {
|
|
160
|
+
return editUrl({
|
|
161
|
+
blogDirPath: (0, utils_1.posixPath)(path_1.default.relative(siteDir, blogDirPath)),
|
|
162
|
+
blogPath: (0, utils_1.posixPath)(blogPathRelative),
|
|
162
163
|
permalink,
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
164
|
+
locale: i18n.currentLocale,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
else if (typeof editUrl === 'string') {
|
|
168
|
+
const isLocalized = blogDirPath === contentPaths.contentPathLocalized;
|
|
169
|
+
const fileContentPath = isLocalized && options.editLocalizedFiles
|
|
170
|
+
? contentPaths.contentPathLocalized
|
|
171
|
+
: contentPaths.contentPath;
|
|
172
|
+
const contentPathEditUrl = (0, utils_1.normalizeUrl)([
|
|
173
|
+
editUrl,
|
|
174
|
+
(0, utils_1.posixPath)(path_1.default.relative(siteDir, fileContentPath)),
|
|
175
|
+
]);
|
|
176
|
+
return (0, utils_1.getEditUrl)(blogPathRelative, contentPathEditUrl);
|
|
177
|
+
}
|
|
178
|
+
return undefined;
|
|
174
179
|
}
|
|
175
|
-
|
|
180
|
+
const tagsBasePath = (0, utils_1.normalizeUrl)([
|
|
181
|
+
baseUrl,
|
|
182
|
+
routeBasePath,
|
|
183
|
+
tagsRouteBasePath,
|
|
184
|
+
]);
|
|
185
|
+
const authors = (0, authors_1.getBlogPostAuthors)({ authorsMap, frontMatter });
|
|
186
|
+
return {
|
|
187
|
+
id: (_e = frontMatter.slug) !== null && _e !== void 0 ? _e : title,
|
|
188
|
+
metadata: {
|
|
189
|
+
permalink,
|
|
190
|
+
editUrl: getBlogEditUrl(),
|
|
191
|
+
source: aliasedSource,
|
|
192
|
+
title,
|
|
193
|
+
description,
|
|
194
|
+
date,
|
|
195
|
+
formattedDate,
|
|
196
|
+
tags: (0, utils_1.normalizeFrontMatterTags)(tagsBasePath, frontMatter.tags),
|
|
197
|
+
readingTime: showReadingTime ? (0, reading_time_1.default)(content).minutes : undefined,
|
|
198
|
+
truncated: (truncateMarker === null || truncateMarker === void 0 ? void 0 : truncateMarker.test(content)) || false,
|
|
199
|
+
authors,
|
|
200
|
+
},
|
|
201
|
+
content,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
async function generateBlogPosts(contentPaths, context, options) {
|
|
205
|
+
const { include, exclude } = options;
|
|
206
|
+
if (!fs_extra_1.default.existsSync(contentPaths.contentPath)) {
|
|
207
|
+
return [];
|
|
208
|
+
}
|
|
209
|
+
const blogSourceFiles = await (0, utils_1.Globby)(include, {
|
|
210
|
+
cwd: contentPaths.contentPath,
|
|
211
|
+
ignore: exclude,
|
|
212
|
+
});
|
|
213
|
+
const authorsMap = await (0, authors_1.getAuthorsMap)({
|
|
214
|
+
contentPaths,
|
|
215
|
+
authorsMapPath: options.authorsMapPath,
|
|
216
|
+
});
|
|
217
|
+
const blogPosts = (0, lodash_1.compact)(await Promise.all(blogSourceFiles.map(async (blogSourceFile) => {
|
|
176
218
|
try {
|
|
177
|
-
return await processBlogSourceFile(blogSourceFile);
|
|
219
|
+
return await processBlogSourceFile(blogSourceFile, contentPaths, context, options, authorsMap);
|
|
178
220
|
}
|
|
179
221
|
catch (e) {
|
|
180
222
|
console.error(chalk_1.default.red(`Processing of blog source file failed for path "${blogSourceFile}"`));
|
|
181
223
|
throw e;
|
|
182
224
|
}
|
|
183
|
-
}));
|
|
225
|
+
})));
|
|
184
226
|
blogPosts.sort((a, b) => b.metadata.date.getTime() - a.metadata.date.getTime());
|
|
185
227
|
return blogPosts;
|
|
186
228
|
}
|
|
187
229
|
exports.generateBlogPosts = generateBlogPosts;
|
|
188
230
|
function linkify({ filePath, contentPaths, fileString, siteDir, sourceToPermalink, onBrokenMarkdownLink, }) {
|
|
189
|
-
const { newContent, brokenMarkdownLinks } = utils_1.replaceMarkdownLinks({
|
|
231
|
+
const { newContent, brokenMarkdownLinks } = (0, utils_1.replaceMarkdownLinks)({
|
|
190
232
|
siteDir,
|
|
191
233
|
fileString,
|
|
192
234
|
filePath,
|