Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ describe('simple site', () => {
},
title: 'Custom Last Update',
},
lastUpdatedAt: new Date('1/1/2000').getTime(),
lastUpdatedAt: new Date('1/1/2000').getTime() / 1000,
lastUpdatedBy: 'Custom Author (processed by parseFrontMatter)',
sidebarPosition: undefined,
tags: [],
Expand Down Expand Up @@ -702,7 +702,7 @@ describe('simple site', () => {
},
title: 'Last Update Date Only',
},
lastUpdatedAt: new Date('1/1/2000').getTime(),
lastUpdatedAt: new Date('1/1/2000').getTime() / 1000,
lastUpdatedBy: 'Author',
sidebarPosition: undefined,
tags: [],
Expand Down
33 changes: 30 additions & 3 deletions packages/docusaurus-plugin-content-docs/src/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ import type {LoadContext} from '@docusaurus/types';
import type {SidebarsUtils} from './sidebars/utils';
import type {DocFile} from './types';

// Extended front matter type to include custom_field in last_update
type ExtendedDocFrontMatter = Omit<
ReturnType<typeof validateDocFrontMatter>,
'last_update'
> & {
last_update?: {
author?: string;
date?: Date | string;
custom_field?: string;
};
};

export async function readDocFile(
versionMetadata: Pick<
VersionMetadata,
Expand Down Expand Up @@ -110,7 +122,11 @@ async function doProcessDocMetadata({
fileContent: content,
parseFrontMatter,
});
const frontMatter = validateDocFrontMatter(unsafeFrontMatter);

// Cast to extended type to carry custom_field through
const frontMatter = validateDocFrontMatter(
unsafeFrontMatter,
) as ExtendedDocFrontMatter;

const {
custom_edit_url: customEditURL,
Expand All @@ -122,13 +138,25 @@ async function doProcessDocMetadata({
last_update: lastUpdateFrontMatter,
} = frontMatter;

const lastUpdate = await readLastUpdateData(
// UPDATED — front matter overrides git values
const gitLastUpdate = await readLastUpdateData(
filePath,
options,
lastUpdateFrontMatter,
vcs,
);

const lastUpdate = {
lastUpdatedAt: options.showLastUpdateTime
? lastUpdateFrontMatter?.date
? new Date(lastUpdateFrontMatter.date).getTime() / 1000
: gitLastUpdate.lastUpdatedAt
: undefined,
lastUpdatedBy: options.showLastUpdateAuthor
? (lastUpdateFrontMatter?.author ?? gitLastUpdate.lastUpdatedBy)
: undefined,
};

// E.g. api/plugins/myDoc -> myDoc; myDoc -> myDoc
const sourceFileNameWithoutExtension = path.basename(
source,
Expand Down Expand Up @@ -386,7 +414,6 @@ export function toCategoryIndexMatcherParam({
DocMetadataBase,
'source' | 'sourceDirName'
>): Parameters<CategoryIndexMatcher>[0] {
// source + sourceDirName are always posix-style
return {
fileName: path.posix.parse(source).name,
extension: path.posix.parse(source).ext,
Expand Down
28 changes: 23 additions & 5 deletions packages/docusaurus-plugin-content-docs/src/frontMatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/* eslint-disable camelcase */

import {
JoiFrontMatter as Joi, // Custom instance for front matter
JoiFrontMatter as Joi,
URISchema,
FrontMatterTagsSchema,
FrontMatterTOCHeadingLevels,
Expand All @@ -17,11 +17,20 @@ import {
} from '@docusaurus/utils-validation';
import type {DocFrontMatter} from '@docusaurus/plugin-content-docs';

// Extends DocFrontMatter to include custom_field inside last_update
export type ExtendedDocFrontMatter = Omit<DocFrontMatter, 'last_update'> & {
last_update?: {
author?: string;
date?: Date | string;
custom_field?: string;
};
};

// NOTE: we don't add any default value on purpose here
// We don't want default values to magically appear in doc metadata and props
// While the user did not provide those values explicitly
// We use default values in code instead
export const DocFrontMatterSchema = Joi.object<DocFrontMatter>({
export const DocFrontMatterSchema = Joi.object<ExtendedDocFrontMatter>({
id: Joi.string(),
// See https://github.com/facebook/docusaurus/issues/4591#issuecomment-822372398
title: Joi.string().allow(''),
Expand All @@ -45,13 +54,22 @@ export const DocFrontMatterSchema = Joi.object<DocFrontMatter>({
pagination_next: Joi.string().allow(null),
pagination_prev: Joi.string().allow(null),
...FrontMatterTOCHeadingLevels,
last_update: FrontMatterLastUpdateSchema,
last_update: FrontMatterLastUpdateSchema.concat(
Joi.object({
custom_field: Joi.string(),
}),
),
})
.unknown()
.concat(ContentVisibilitySchema);

// Return type is now ExtendedDocFrontMatter so custom_field is typed correctly
// in docs.ts and anywhere else that consumes front matter
export function validateDocFrontMatter(frontMatter: {
[key: string]: unknown;
}): DocFrontMatter {
return validateFrontMatter(frontMatter, DocFrontMatterSchema);
}): ExtendedDocFrontMatter {
return validateFrontMatter(
frontMatter,
DocFrontMatterSchema,
) as ExtendedDocFrontMatter;
}