docusaurus/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts
ozaki 32fa7e0a8d feat(blog): add LastUpdateAuthor & LastUpdateTime (#9912)
Co-authored-by: OzakIOne <OzakIOne@users.noreply.github.com>
Co-authored-by: sebastien <lorber.sebastien@gmail.com>
2024-03-15 14:54:38 +01:00

689 lines
20 KiB
TypeScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/// <reference types="@docusaurus/module-type-aliases" />
declare module '@docusaurus/plugin-content-blog' {
import type {LoadedMDXContent} from '@docusaurus/mdx-loader';
import type {MDXOptions} from '@docusaurus/mdx-loader';
import type {
FrontMatterTag,
Tag,
LastUpdateData,
FrontMatterLastUpdate,
} from '@docusaurus/utils';
import type {DocusaurusConfig, Plugin, LoadContext} from '@docusaurus/types';
import type {Item as FeedItem} from 'feed';
import type {Overwrite} from 'utility-types';
export type Assets = {
/**
* If `metadata.yarn workspace website typecheck
4
yarn workspace v1.22.19yarn workspace website typecheck
4
yarn workspace v1.22.19yarn workspace website typecheck
4
yarn workspace v1.22.19image` is a collocated image path, this entry will be the
* bundler-generated image path. Otherwise, it's empty, and the image URL
* should be accessed through `frontMatter.image`.
*/
image?: string;
/**
* Array where each item is 1-1 correlated with the `metadata.authors` array
* so that client can render the correct author images. If the author's
* image is a local file path, the slot will be filled with the bundler-
* generated image path; otherwise, it's empty, and the author's image URL
* should be accessed through `authors.imageURL`.
*/
authorsImageUrls: (string | undefined)[];
};
export type Author = {
/**
* If `name` doesn't exist, an `imageURL` is expected.
*/
name?: string;
/**
* The image path could be collocated, in which case
* `metadata.assets.authorsImageUrls` should be used instead. If `imageURL`
* doesn't exist, a `name` is expected.
*/
imageURL?: string;
/**
* Used to generate the author's link.
*/
url?: string;
/**
* Used as a subtitle for the author, e.g. "maintainer of Docusaurus"
*/
title?: string;
/**
* Mainly used for RSS feeds; if `url` doesn't exist, `email` can be used
* to generate a fallback `mailto:` URL.
*/
email?: string;
/**
* Unknown keys are allowed, so that we can pass custom fields to authors,
* e.g., `twitter`.
*/
[key: string]: unknown;
};
/**
* Everything is partial/unnormalized, because front matter is always
* preserved as-is. Default values will be applied when generating metadata
*/
export type BlogPostFrontMatter = {
/**
* @deprecated Use `slug` instead.
*/
id?: string;
/**
* Will override the default title collected from h1 heading.
* @see {@link BlogPostMetadata.title}
*/
title?: string;
/**
* Will override the default excerpt.
* @see {@link BlogPostMetadata.description}
*/
description?: string;
/**
* Front matter tags, unnormalized.
* @see {@link BlogPostMetadata.tags}
*/
tags?: FrontMatterTag[];
/** Custom slug appended after `/<baseUrl>/<routeBasePath>/` */
slug?: string;
/**
* Marks the post as draft and excludes it from the production build.
*/
draft?: boolean;
/**
* Marks the post as unlisted and visibly hides it unless directly accessed.
*/
unlisted?: boolean;
/**
* Will override the default publish date inferred from git/filename. Yaml
* only converts standard yyyy-MM-dd format to dates, so this may stay as a
* plain string.
* @see {@link BlogPostMetadata.date}
*/
date?: Date | string;
/**
* Authors, unnormalized.
* @see {@link BlogPostMetadata.authors}
*/
authors?: BlogPostFrontMatterAuthors;
/**
* To be deprecated
* @see {@link BlogPostFrontMatterAuthor.name}
*/
author?: string;
/**
* To be deprecated
* @see {@link BlogPostFrontMatterAuthor.title}
*/
author_title?: string;
/**
* To be deprecated
* @see {@link BlogPostFrontMatterAuthor.url}
*/
author_url?: string;
/**
* To be deprecated
* @see {@link BlogPostFrontMatterAuthor.imageURL}
*/
author_image_url?: string;
/** @deprecated v1 legacy */
authorTitle?: string;
/** @deprecated v1 legacy */
authorURL?: string;
/** @deprecated v1 legacy */
authorImageURL?: string;
/** Used in the head meta. Should use `assets.image` in priority. */
image?: string;
/** Used in the head meta. */
keywords?: string[];
/** Hide the right TOC. */
hide_table_of_contents?: boolean;
/**
* Minimum TOC heading level. Must be between 2 and 6 and lower or equal to
* the max value.
*/
toc_min_heading_level?: number;
/** Maximum TOC heading level. Must be between 2 and 6. */
toc_max_heading_level?: number;
/** Allows overriding the last updated author and/or date. */
last_update?: FrontMatterLastUpdate;
};
export type BlogPostFrontMatterAuthor = Author & {
/**
* Will be normalized into the `imageURL` prop.
*/
image_url?: string;
/**
* References an existing author in the authors map.
*/
key?: string;
};
/**
* Blog post authors can be declared in front matter as a string key
* (referencing an author in authors map), an object (partially overriding the
* data in authors map, or a completely new author), or an array of a mix of
* both.
*/
export type BlogPostFrontMatterAuthors =
| string
| BlogPostFrontMatterAuthor
| (string | BlogPostFrontMatterAuthor)[];
export type BlogPostMetadata = LastUpdateData & {
/** Path to the Markdown source, with `@site` alias. */
readonly source: string;
/**
* Used to generate the page h1 heading, tab title, and pagination title.
*/
readonly title: string;
/**
* The publish date of the post. On client side, this will be serialized
* into a string.
*/
readonly date: Date;
/** Full link including base URL. */
readonly permalink: string;
/**
* Description used in the meta. Could be an empty string (empty content)
*/
readonly description: string;
/**
* Absolute URL to the editing page of the post. Undefined if the post
* shouldn't be edited.
*/
readonly editUrl?: string;
/**
* Reading time in minutes calculated based on word count.
*/
readonly readingTime?: number;
/**
* Whether the truncate marker exists in the post's content.
*/
readonly hasTruncateMarker: boolean;
/**
* Used in pagination. Generated after the other metadata, so not readonly.
* Content is just a subset of another post's metadata.
*/
nextItem?: {readonly title: string; readonly permalink: string};
/**
* Used in pagination. Generated after the other metadata, so not readonly.
* Content is just a subset of another post's metadata.
*/
prevItem?: {readonly title: string; readonly permalink: string};
/**
* Author metadata, normalized. Should be used in joint with
* `assets.authorsImageUrls` on client side.
*/
readonly authors: Author[];
/** Front matter, as-is. */
readonly frontMatter: BlogPostFrontMatter & {[key: string]: unknown};
/** Tags, normalized. */
readonly tags: Tag[];
/**
* Marks the post as unlisted and visibly hides it unless directly accessed.
*/
readonly unlisted: boolean;
};
/**
* @returns The edit URL that's directly plugged into metadata.
*/
export type EditUrlFunction = (editUrlParams: {
/**
* The root content directory containing this post file, relative to the
* site path. Usually the same as `options.path` but can be localized
*/
blogDirPath: string;
/** Path to this post file, relative to `blogDirPath`. */
blogPath: string;
/** @see {@link BlogPostMetadata.permalink} */
permalink: string;
/** Locale name. */
locale: string;
}) => string | undefined;
export type FeedType = 'rss' | 'atom' | 'json';
/**
* Normalized feed options used within code.
*/
export type FeedOptions = {
/** If `null`, no feed is generated. */
type?: FeedType[] | null;
/** Title of generated feed. */
title?: string;
/** Description of generated feed. */
description?: string;
/** Copyright notice. Required because the feed library marked it that. */
copyright: string;
/** Language of the feed. */
language?: string;
/** Allow control over the construction of BlogFeedItems */
createFeedItems?: CreateFeedItemsFn;
/** Limits the feed to the specified number of posts, false|null for all */
limit?: number | false | null;
};
type DefaultCreateFeedItemsParams = {
blogPosts: BlogPost[];
siteConfig: DocusaurusConfig;
outDir: string;
};
type CreateFeedItemsFn = (
params: CreateFeedItemsParams,
) => Promise<BlogFeedItem[]>;
type CreateFeedItemsParams = DefaultCreateFeedItemsParams & {
defaultCreateFeedItems: (
params: DefaultCreateFeedItemsParams,
) => Promise<BlogFeedItem[]>;
};
/**
* Duplicate from ngryman/reading-time to keep stability of API.
*/
type ReadingTimeOptions = {
wordsPerMinute?: number;
/**
* @param char The character to be matched.
* @returns `true` if this character is a word bound.
*/
wordBound?: (char: string) => boolean;
};
/**
* Represents the default reading time implementation.
* @returns The reading time directly plugged into metadata.
*/
export type ReadingTimeFunction = (params: {
/** Markdown content. */
content: string;
/** Front matter. */
frontMatter?: BlogPostFrontMatter & {[key: string]: unknown};
/** Options accepted by ngryman/reading-time. */
options?: ReadingTimeOptions;
}) => number;
/**
* @returns The reading time directly plugged into metadata. `undefined` to
* hide reading time for a specific post.
*/
export type ReadingTimeFunctionOption = (
/**
* The `options` is not provided by the caller; the user can inject their
* own option values into `defaultReadingTime`
*/
params: Required<Omit<Parameters<ReadingTimeFunction>[0], 'options'>> & {
/**
* The default reading time implementation from ngryman/reading-time.
*/
defaultReadingTime: ReadingTimeFunction;
},
) => number | undefined;
export type ProcessBlogPostsFn = (params: {
blogPosts: BlogPost[];
}) => Promise<void | BlogPost[]>;
/**
* Plugin options after normalization.
*/
export type PluginOptions = MDXOptions & {
/** Plugin ID. */
id?: string;
/**
* Path to the blog content directory on the file system, relative to site
* directory.
*/
path: string;
/**
* URL route for the blog section of your site. **DO NOT** include a
* trailing slash. Use `/` to put the blog at root path.
*/
routeBasePath: string;
/**
* URL route for the tags section of your blog. Will be appended to
* `routeBasePath`.
*/
tagsBasePath: string;
/**
* URL route for the pages section of your blog. Will be appended to
* `routeBasePath`.
*/
pageBasePath: string;
/**
* URL route for the archive section of your blog. Will be appended to
* `routeBasePath`. **DO NOT** include a trailing slash. Use `null` to
* disable generation of archive.
*/
archiveBasePath: string | null;
/**
* Array of glob patterns matching Markdown files to be built, relative to
* the content path.
*/
include: string[];
/**
* Array of glob patterns matching Markdown files to be excluded. Serves as
* refinement based on the `include` option.
*/
exclude: string[];
/**
* Number of posts to show per page in the listing page. Use `'ALL'` to
* display all posts on one listing page.
*/
postsPerPage: number | 'ALL';
/** Root component of the blog listing page. */
blogListComponent: string;
/** Root component of each blog post page. */
blogPostComponent: string;
/** Root component of the tags list page. */
blogTagsListComponent: string;
/** Root component of the "posts containing tag" page. */
blogTagsPostsComponent: string;
/** Root component of the blog archive page. */
blogArchiveComponent: string;
/** Blog page title for better SEO. */
blogTitle: string;
/** Blog page meta description for better SEO. */
blogDescription: string;
/**
* Number of blog post elements to show in the blog sidebar. `'ALL'` to show
* all blog posts; `0` to disable.
*/
blogSidebarCount: number | 'ALL';
/** Title of the blog sidebar. */
blogSidebarTitle: string;
/** Truncate marker marking where the summary ends. */
truncateMarker: RegExp;
/** Show estimated reading time for the blog post. */
showReadingTime: boolean;
/** Blog feed. */
feedOptions: FeedOptions;
/**
* Base URL to edit your site. The final URL is computed by `editUrl +
* relativePostPath`. Using a function allows more nuanced control for each
* file. Omitting this variable entirely will disable edit links.
*/
editUrl?: string | EditUrlFunction;
/**
* The edit URL will target the localized file, instead of the original
* unlocalized file. Ignored when `editUrl` is a function.
*/
editLocalizedFiles?: boolean;
/** Path to the authors map file, relative to the blog content directory. */
authorsMapPath: string;
/** A callback to customize the reading time number displayed. */
readingTime: ReadingTimeFunctionOption;
/** Governs the direction of blog post sorting. */
sortPosts: 'ascending' | 'descending';
/** Whether to display the last date the doc was updated. */
showLastUpdateTime: boolean;
/** Whether to display the author who last updated the doc. */
showLastUpdateAuthor: boolean;
/** An optional function which can be used to transform blog posts
* (filter, modify, delete, etc...).
*/
processBlogPosts: ProcessBlogPostsFn;
};
/**
* Feed options, as provided by user config. `type` accepts `all` as shortcut
*/
export type UserFeedOptions = Overwrite<
Partial<FeedOptions>,
{
/** Type of feed to be generated. Use `null` to disable generation. */
type?: FeedOptions['type'] | 'all' | FeedType;
}
>;
/**
* Options as provided in the user config (before normalization)
*/
export type Options = Overwrite<
Partial<PluginOptions>,
{
/** Blog feed. */
feedOptions?: UserFeedOptions;
}
>;
export type BlogSidebarItem = {
title: string;
permalink: string;
unlisted: boolean;
};
export type BlogSidebar = {
title: string;
items: BlogSidebarItem[];
};
export type BlogContent = {
blogSidebarTitle: string;
blogPosts: BlogPost[];
blogListPaginated: BlogPaginated[];
blogTags: BlogTags;
blogTagsListPath: string;
};
export type BlogMetadata = {
/** the path to the base of the blog */
blogBasePath: string;
/** title of the overall blog */
blogTitle: string;
};
export type BlogTags = {
[permalink: string]: BlogTag;
};
export type BlogTag = Tag & {
/** Blog post permalinks. */
items: string[];
pages: BlogPaginated[];
unlisted: boolean;
};
export type BlogPost = {
id: string;
metadata: BlogPostMetadata;
content: string;
};
export type BlogFeedItem = FeedItem;
export type BlogPaginatedMetadata = {
/** Title of the entire blog. */
readonly blogTitle: string;
/** Blog description. */
readonly blogDescription: string;
/** Permalink to the next list page. */
readonly nextPage?: string;
/** Permalink of the current page. */
readonly permalink: string;
/** Permalink to the previous list page. */
readonly previousPage?: string;
/** Index of the current page, 1-based. */
readonly page: number;
/** Posts displayed on each list page. */
readonly postsPerPage: number;
/** Total number of posts in the entire blog. */
readonly totalCount: number;
/** Total number of list pages. */
readonly totalPages: number;
};
export type BlogPaginated = {
metadata: BlogPaginatedMetadata;
/** Blog post permalinks. */
items: string[];
};
type PropBlogPostMetadata = Overwrite<
BlogPostMetadata,
{
/** The publish date of the post. Serialized from the `Date` object. */
date: string;
}
>;
export type PropBlogPostContent = LoadedMDXContent<
BlogPostFrontMatter,
PropBlogPostMetadata,
Assets
>;
export default function pluginContentBlog(
context: LoadContext,
options: PluginOptions,
): Promise<Plugin<BlogContent>>;
}
declare module '@theme/BlogPostPage' {
import type {
BlogPostFrontMatter,
BlogSidebar,
PropBlogPostContent,
BlogMetadata,
} from '@docusaurus/plugin-content-blog';
export type FrontMatter = BlogPostFrontMatter;
export type Content = PropBlogPostContent;
export interface Props {
/** Blog sidebar. */
readonly sidebar: BlogSidebar;
/** Content of this post as an MDX component, with useful metadata. */
readonly content: Content;
/** Metadata about the blog. */
readonly blogMetadata: BlogMetadata;
}
export default function BlogPostPage(props: Props): JSX.Element;
}
declare module '@theme/BlogPostPage/Metadata' {
export default function BlogPostPageMetadata(): JSX.Element;
}
declare module '@theme/BlogPostPage/StructuredData' {
export default function BlogPostStructuredData(): JSX.Element;
}
declare module '@theme/BlogListPage' {
import type {Content} from '@theme/BlogPostPage';
import type {
BlogSidebar,
BlogPaginatedMetadata,
} from '@docusaurus/plugin-content-blog';
export interface Props {
/** Blog sidebar. */
readonly sidebar: BlogSidebar;
/** Metadata of the current listing page. */
readonly metadata: BlogPaginatedMetadata;
/**
* Array of blog posts included on this page. Every post's metadata is also
* available.
*/
readonly items: readonly {readonly content: Content}[];
}
export default function BlogListPage(props: Props): JSX.Element;
}
declare module '@theme/BlogListPage/StructuredData' {
import type {Content} from '@theme/BlogPostPage';
import type {
BlogSidebar,
BlogPaginatedMetadata,
} from '@docusaurus/plugin-content-blog';
export interface Props {
/** Blog sidebar. */
readonly sidebar: BlogSidebar;
/** Metadata of the current listing page. */
readonly metadata: BlogPaginatedMetadata;
/**
* Array of blog posts included on this page. Every post's metadata is also
* available.
*/
readonly items: readonly {readonly content: Content}[];
}
export default function BlogListPageStructuredData(props: Props): JSX.Element;
}
declare module '@theme/BlogTagsListPage' {
import type {BlogSidebar} from '@docusaurus/plugin-content-blog';
import type {TagsListItem} from '@docusaurus/utils';
export interface Props {
/** Blog sidebar. */
readonly sidebar: BlogSidebar;
/** All tags declared in this blog. */
readonly tags: TagsListItem[];
}
export default function BlogTagsListPage(props: Props): JSX.Element;
}
declare module '@theme/BlogTagsPostsPage' {
import type {Content} from '@theme/BlogPostPage';
import type {
BlogSidebar,
BlogPaginatedMetadata,
} from '@docusaurus/plugin-content-blog';
import type {TagModule} from '@docusaurus/utils';
export interface Props {
/** Blog sidebar. */
readonly sidebar: BlogSidebar;
/** Metadata of this tag. */
readonly tag: TagModule;
/** Looks exactly the same as the posts list page */
readonly listMetadata: BlogPaginatedMetadata;
/**
* Array of blog posts included on this page. Every post's metadata is also
* available.
*/
readonly items: readonly {readonly content: Content}[];
}
export default function BlogTagsPostsPage(props: Props): JSX.Element;
}
declare module '@theme/BlogArchivePage' {
import type {Content} from '@theme/BlogPostPage';
/** We may add extra metadata or prune some metadata from here */
export type ArchiveBlogPost = Content;
export interface Props {
/** The entirety of the blog's data. */
readonly archive: {
/** All posts. Can select any useful data/metadata to render. */
readonly blogPosts: readonly ArchiveBlogPost[];
};
}
export default function BlogArchivePage(props: Props): JSX.Element;
}