@docusaurus/plugin-content-blog 4.0.0-canary-6817 → 4.0.0-canary-6820

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.
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { TagsFile } from '@docusaurus/utils';
8
- import type { LoadContext } from '@docusaurus/types';
8
+ import type { LoadContext, VcsConfig } from '@docusaurus/types';
9
9
  import type { AuthorsMap, PluginOptions, BlogPost, BlogTags, BlogPaginated } from '@docusaurus/plugin-content-blog';
10
10
  import type { BlogContentPaths } from './types';
11
11
  export declare function truncate(fileString: string, truncateMarker: RegExp): string;
@@ -35,6 +35,13 @@ type ParsedBlogFileName = {
35
35
  slug: string;
36
36
  };
37
37
  export declare function parseBlogFileName(blogSourceRelative: string): ParsedBlogFileName;
38
+ export declare function parseFrontMatterDate(date: string | Date): Date;
39
+ export declare function getBlogPostDate({ frontMatterDate, filenameDate, filePath, vcs, }: {
40
+ frontMatterDate?: string | Date;
41
+ filenameDate?: Date;
42
+ filePath: string;
43
+ vcs: VcsConfig;
44
+ }): Promise<Date>;
38
45
  export declare function generateBlogPosts(contentPaths: BlogContentPaths, context: LoadContext, options: PluginOptions, tagsFile: TagsFile | null, authorsMap?: AuthorsMap): Promise<BlogPost[]>;
39
46
  export declare function applyProcessBlogPosts({ blogPosts, processBlogPosts, }: {
40
47
  blogPosts: BlogPost[];
package/lib/blogUtils.js CHANGED
@@ -12,6 +12,8 @@ exports.paginateBlogPosts = paginateBlogPosts;
12
12
  exports.shouldBeListed = shouldBeListed;
13
13
  exports.getBlogTags = getBlogTags;
14
14
  exports.parseBlogFileName = parseBlogFileName;
15
+ exports.parseFrontMatterDate = parseFrontMatterDate;
16
+ exports.getBlogPostDate = getBlogPostDate;
15
17
  exports.generateBlogPosts = generateBlogPosts;
16
18
  exports.applyProcessBlogPosts = applyProcessBlogPosts;
17
19
  const tslib_1 = require("tslib");
@@ -110,6 +112,34 @@ function parseBlogFileName(blogSourceRelative) {
110
112
  const slug = `/${text}`;
111
113
  return { date: undefined, text, slug };
112
114
  }
115
+ function parseFrontMatterDate(date) {
116
+ if (typeof date === 'string') {
117
+ const dateString = date.trim();
118
+ // Detect a timezone suffix in the time portion, not the date's day/year.
119
+ // YAML timestamps allow tabs and short offsets; also accept ISO +/-HHMM.
120
+ // https://yaml.org/type/timestamp.html
121
+ // This detects a timezone, not date validity (already checked by Joi).
122
+ const hasTimeZone = /[t \t]\d.*(?:z|[+-]\d{1,2}(?::?\d{2})?)$/i.test(dateString);
123
+ // Treat dates without an explicit timezone as UTC.
124
+ return new Date(hasTimeZone ? dateString : `${dateString}Z`);
125
+ }
126
+ // Custom front matter parsers can still return Date objects.
127
+ return date;
128
+ }
129
+ async function getBlogPostDate({ frontMatterDate, filenameDate, filePath, vcs, }) {
130
+ // Prefer front matter, then the filename, then the file creation date.
131
+ if (frontMatterDate) {
132
+ return parseFrontMatterDate(frontMatterDate);
133
+ }
134
+ else if (filenameDate) {
135
+ return filenameDate;
136
+ }
137
+ const result = await vcs.getFileCreationInfo(filePath);
138
+ if (result == null) {
139
+ return (await fs_extra_1.default.stat(filePath)).birthtime;
140
+ }
141
+ return new Date(result.timestamp);
142
+ }
113
143
  async function parseBlogPostMarkdownFile({ filePath, parseFrontMatter, }) {
114
144
  const fileContent = await fs_extra_1.default.readFile(filePath, 'utf-8');
115
145
  try {
@@ -151,26 +181,12 @@ async function processBlogSourceFile(blogSourceRelative, contentPaths, context,
151
181
  logger_1.default.warn `name=${'id'} header option is deprecated in path=${blogSourceRelative} file. Please use name=${'slug'} option instead.`;
152
182
  }
153
183
  const parsedBlogFileName = parseBlogFileName(blogSourceRelative);
154
- async function getDate() {
155
- // Prefer user-defined date.
156
- if (frontMatter.date) {
157
- if (typeof frontMatter.date === 'string') {
158
- // Always treat dates as UTC by adding the `Z`
159
- return new Date(`${frontMatter.date}Z`);
160
- }
161
- // YAML only converts YYYY-MM-DD to dates and leaves others as strings.
162
- return frontMatter.date;
163
- }
164
- else if (parsedBlogFileName.date) {
165
- return parsedBlogFileName.date;
166
- }
167
- const result = await vcs.getFileCreationInfo(blogSourceAbsolute);
168
- if (result == null) {
169
- return (await fs_extra_1.default.stat(blogSourceAbsolute)).birthtime;
170
- }
171
- return new Date(result.timestamp);
172
- }
173
- const date = await getDate();
184
+ const date = await getBlogPostDate({
185
+ frontMatterDate: frontMatter.date,
186
+ filenameDate: parsedBlogFileName.date,
187
+ filePath: blogSourceAbsolute,
188
+ vcs,
189
+ });
174
190
  const title = frontMatter.title ?? contentTitle ?? parsedBlogFileName.text;
175
191
  const description = frontMatter.description ?? excerpt ?? '';
176
192
  const slug = frontMatter.slug ?? parsedBlogFileName.slug;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docusaurus/plugin-content-blog",
3
- "version": "4.0.0-canary-6817",
3
+ "version": "4.0.0-canary-6820",
4
4
  "description": "Blog plugin for Docusaurus.",
5
5
  "main": "lib/index.js",
6
6
  "types": "src/plugin-content-blog.d.ts",
@@ -31,15 +31,15 @@
31
31
  },
32
32
  "license": "MIT",
33
33
  "dependencies": {
34
- "@docusaurus/core": "4.0.0-canary-6817",
35
- "@docusaurus/logger": "4.0.0-canary-6817",
36
- "@docusaurus/mdx-loader": "4.0.0-canary-6817",
37
- "@docusaurus/module-type-aliases": "4.0.0-canary-6817",
38
- "@docusaurus/theme-common": "4.0.0-canary-6817",
39
- "@docusaurus/types": "4.0.0-canary-6817",
40
- "@docusaurus/utils": "4.0.0-canary-6817",
41
- "@docusaurus/utils-common": "4.0.0-canary-6817",
42
- "@docusaurus/utils-validation": "4.0.0-canary-6817",
34
+ "@docusaurus/core": "4.0.0-canary-6820",
35
+ "@docusaurus/logger": "4.0.0-canary-6820",
36
+ "@docusaurus/mdx-loader": "4.0.0-canary-6820",
37
+ "@docusaurus/module-type-aliases": "4.0.0-canary-6820",
38
+ "@docusaurus/theme-common": "4.0.0-canary-6820",
39
+ "@docusaurus/types": "4.0.0-canary-6820",
40
+ "@docusaurus/utils": "4.0.0-canary-6820",
41
+ "@docusaurus/utils-common": "4.0.0-canary-6820",
42
+ "@docusaurus/utils-validation": "4.0.0-canary-6820",
43
43
  "cheerio": "^1.2.0",
44
44
  "combine-promises": "^1.2.0",
45
45
  "feed": "^5.2.1",
@@ -57,11 +57,11 @@
57
57
  "react-dom": "^19.3.0"
58
58
  },
59
59
  "engines": {
60
- "node": ">=24.14"
60
+ "node": ">=26.9"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@total-typescript/shoehorn": "^0.1.2",
64
64
  "tree-node-cli": "^3.0.0"
65
65
  },
66
- "gitHead": "38c20529ba3a20243f31ce7a56764e969bf9ba7b"
66
+ "gitHead": "548b203e01abc1df60907285520e3b000a9af3eb"
67
67
  }
package/src/blogUtils.ts CHANGED
@@ -32,7 +32,7 @@ import {getBlogPostAuthors} from './authors';
32
32
  import {reportAuthorsProblems} from './authorsProblems';
33
33
  import {calculateReadingTime} from './readingTime';
34
34
  import type {TagsFile} from '@docusaurus/utils';
35
- import type {LoadContext, ParseFrontMatter} from '@docusaurus/types';
35
+ import type {LoadContext, ParseFrontMatter, VcsConfig} from '@docusaurus/types';
36
36
  import type {
37
37
  AuthorsMap,
38
38
  PluginOptions,
@@ -184,6 +184,48 @@ export function parseBlogFileName(
184
184
  return {date: undefined, text, slug};
185
185
  }
186
186
 
187
+ export function parseFrontMatterDate(date: string | Date): Date {
188
+ if (typeof date === 'string') {
189
+ const dateString = date.trim();
190
+ // Detect a timezone suffix in the time portion, not the date's day/year.
191
+ // YAML timestamps allow tabs and short offsets; also accept ISO +/-HHMM.
192
+ // https://yaml.org/type/timestamp.html
193
+ // This detects a timezone, not date validity (already checked by Joi).
194
+ const hasTimeZone = /[t \t]\d.*(?:z|[+-]\d{1,2}(?::?\d{2})?)$/i.test(
195
+ dateString,
196
+ );
197
+ // Treat dates without an explicit timezone as UTC.
198
+ return new Date(hasTimeZone ? dateString : `${dateString}Z`);
199
+ }
200
+ // Custom front matter parsers can still return Date objects.
201
+ return date;
202
+ }
203
+
204
+ export async function getBlogPostDate({
205
+ frontMatterDate,
206
+ filenameDate,
207
+ filePath,
208
+ vcs,
209
+ }: {
210
+ frontMatterDate?: string | Date;
211
+ filenameDate?: Date;
212
+ filePath: string;
213
+ vcs: VcsConfig;
214
+ }): Promise<Date> {
215
+ // Prefer front matter, then the filename, then the file creation date.
216
+ if (frontMatterDate) {
217
+ return parseFrontMatterDate(frontMatterDate);
218
+ } else if (filenameDate) {
219
+ return filenameDate;
220
+ }
221
+
222
+ const result = await vcs.getFileCreationInfo(filePath);
223
+ if (result == null) {
224
+ return (await fs.stat(filePath)).birthtime;
225
+ }
226
+ return new Date(result.timestamp);
227
+ }
228
+
187
229
  async function parseBlogPostMarkdownFile({
188
230
  filePath,
189
231
  parseFrontMatter,
@@ -273,27 +315,12 @@ async function processBlogSourceFile(
273
315
 
274
316
  const parsedBlogFileName = parseBlogFileName(blogSourceRelative);
275
317
 
276
- async function getDate(): Promise<Date> {
277
- // Prefer user-defined date.
278
- if (frontMatter.date) {
279
- if (typeof frontMatter.date === 'string') {
280
- // Always treat dates as UTC by adding the `Z`
281
- return new Date(`${frontMatter.date}Z`);
282
- }
283
- // YAML only converts YYYY-MM-DD to dates and leaves others as strings.
284
- return frontMatter.date;
285
- } else if (parsedBlogFileName.date) {
286
- return parsedBlogFileName.date;
287
- }
288
-
289
- const result = await vcs.getFileCreationInfo(blogSourceAbsolute);
290
- if (result == null) {
291
- return (await fs.stat(blogSourceAbsolute)).birthtime;
292
- }
293
- return new Date(result.timestamp);
294
- }
295
-
296
- const date = await getDate();
318
+ const date = await getBlogPostDate({
319
+ frontMatterDate: frontMatter.date,
320
+ filenameDate: parsedBlogFileName.date,
321
+ filePath: blogSourceAbsolute,
322
+ vcs,
323
+ });
297
324
 
298
325
  const title = frontMatter.title ?? contentTitle ?? parsedBlogFileName.text;
299
326
  const description = frontMatter.description ?? excerpt ?? '';