mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-10 15:47:23 +02:00
refactor: replace non-prop interface with type; allow plugin lifecycles to have sync type (#7080)
* refactor: replace non-prop interface with type; allow plugin lifecycles to have sync type * fix
This commit is contained in:
parent
ce2b631455
commit
24c205a835
38 changed files with 145 additions and 138 deletions
4
packages/docusaurus-mdx-loader/src/deps.d.ts
vendored
4
packages/docusaurus-mdx-loader/src/deps.d.ts
vendored
|
@ -10,13 +10,13 @@ declare module '@mdx-js/mdx' {
|
||||||
import type {Processor} from 'unified';
|
import type {Processor} from 'unified';
|
||||||
import type {RemarkOrRehypePlugin} from '@docusaurus/mdx-loader';
|
import type {RemarkOrRehypePlugin} from '@docusaurus/mdx-loader';
|
||||||
|
|
||||||
export interface Options {
|
export type Options = {
|
||||||
filepath?: string;
|
filepath?: string;
|
||||||
skipExport?: boolean;
|
skipExport?: boolean;
|
||||||
wrapExport?: string;
|
wrapExport?: string;
|
||||||
remarkPlugins?: RemarkOrRehypePlugin[];
|
remarkPlugins?: RemarkOrRehypePlugin[];
|
||||||
rehypePlugins?: RemarkOrRehypePlugin[];
|
rehypePlugins?: RemarkOrRehypePlugin[];
|
||||||
}
|
};
|
||||||
|
|
||||||
export function sync(content: string, options?: Options): string;
|
export function sync(content: string, options?: Options): string;
|
||||||
export function createMdxAstCompiler(options?: Options): Processor;
|
export function createMdxAstCompiler(options?: Options): Processor;
|
||||||
|
|
|
@ -182,9 +182,9 @@ export default async function mdxLoader(
|
||||||
// Partial are not expected to have associated metadata files or front matter
|
// Partial are not expected to have associated metadata files or front matter
|
||||||
const isMDXPartial = options.isMDXPartial?.(filePath);
|
const isMDXPartial = options.isMDXPartial?.(filePath);
|
||||||
if (isMDXPartial && hasFrontMatter) {
|
if (isMDXPartial && hasFrontMatter) {
|
||||||
const errorMessage = `Docusaurus MDX partial files should not contain FrontMatter.
|
const errorMessage = `Docusaurus MDX partial files should not contain front matter.
|
||||||
Those partial files use the _ prefix as a convention by default, but this is configurable.
|
Those partial files use the _ prefix as a convention by default, but this is configurable.
|
||||||
File at ${filePath} contains FrontMatter that will be ignored:
|
File at ${filePath} contains front matter that will be ignored:
|
||||||
${JSON.stringify(frontMatter, null, 2)}`;
|
${JSON.stringify(frontMatter, null, 2)}`;
|
||||||
|
|
||||||
if (!options.isMDXPartialFrontMatterWarningDisabled) {
|
if (!options.isMDXPartialFrontMatterWarningDisabled) {
|
||||||
|
|
|
@ -9,9 +9,8 @@
|
||||||
|
|
||||||
import {parseMarkdownHeadingId, createSlugger} from '@docusaurus/utils';
|
import {parseMarkdownHeadingId, createSlugger} from '@docusaurus/utils';
|
||||||
import visit from 'unist-util-visit';
|
import visit from 'unist-util-visit';
|
||||||
import toString from 'mdast-util-to-string';
|
import mdastToString from 'mdast-util-to-string';
|
||||||
import type {Transformer} from 'unified';
|
import type {Transformer} from 'unified';
|
||||||
import type {Parent} from 'unist';
|
|
||||||
import type {Heading, Text} from 'mdast';
|
import type {Heading, Text} from 'mdast';
|
||||||
|
|
||||||
export default function plugin(): Transformer {
|
export default function plugin(): Transformer {
|
||||||
|
@ -30,10 +29,8 @@ export default function plugin(): Transformer {
|
||||||
const headingTextNodes = headingNode.children.filter(
|
const headingTextNodes = headingNode.children.filter(
|
||||||
({type}) => !['html', 'jsx'].includes(type),
|
({type}) => !['html', 'jsx'].includes(type),
|
||||||
);
|
);
|
||||||
const heading = toString(
|
const heading = mdastToString(
|
||||||
headingTextNodes.length > 0
|
headingTextNodes.length > 0 ? headingTextNodes : headingNode,
|
||||||
? ({children: headingTextNodes} as Parent)
|
|
||||||
: headingNode,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Support explicit heading IDs
|
// Support explicit heading IDs
|
||||||
|
|
|
@ -27,9 +27,9 @@ const isImport = (child: Node): child is Literal => child.type === 'import';
|
||||||
const hasImports = (index: number) => index > -1;
|
const hasImports = (index: number) => index > -1;
|
||||||
const isExport = (child: Node): child is Literal => child.type === 'export';
|
const isExport = (child: Node): child is Literal => child.type === 'export';
|
||||||
|
|
||||||
interface PluginOptions {
|
type PluginOptions = {
|
||||||
name?: string;
|
name?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
const isTarget = (child: Literal, name: string) => {
|
const isTarget = (child: Literal, name: string) => {
|
||||||
let found = false;
|
let found = false;
|
||||||
|
|
|
@ -37,7 +37,7 @@ export type SidebarEntries = {
|
||||||
| Array<{[key: string]: unknown} | string>;
|
| Array<{[key: string]: unknown} | string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface VersionTwoConfig {
|
export type VersionTwoConfig = {
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
favicon: string;
|
favicon: string;
|
||||||
tagline?: string;
|
tagline?: string;
|
||||||
|
@ -93,7 +93,7 @@ export interface VersionTwoConfig {
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
}
|
}
|
||||||
)[];
|
)[];
|
||||||
}
|
};
|
||||||
|
|
||||||
export type VersionOneConfig = {
|
export type VersionOneConfig = {
|
||||||
title?: string;
|
title?: string;
|
||||||
|
|
|
@ -140,8 +140,9 @@ declare module '@docusaurus/Head' {
|
||||||
|
|
||||||
declare module '@docusaurus/Link' {
|
declare module '@docusaurus/Link' {
|
||||||
import type {CSSProperties, ComponentProps} from 'react';
|
import type {CSSProperties, ComponentProps} from 'react';
|
||||||
|
import type {NavLinkProps as RRNavLinkProps} from 'react-router-dom';
|
||||||
|
|
||||||
type NavLinkProps = Partial<import('react-router-dom').NavLinkProps>;
|
type NavLinkProps = Partial<RRNavLinkProps>;
|
||||||
export type Props = NavLinkProps &
|
export type Props = NavLinkProps &
|
||||||
ComponentProps<'a'> & {
|
ComponentProps<'a'> & {
|
||||||
readonly className?: string;
|
readonly className?: string;
|
||||||
|
|
|
@ -314,7 +314,10 @@ describe('validateBlogPostFrontMatter tags', () => {
|
||||||
{tags: ['hello', {label: 'tagLabel', permalink: '/tagPermalink'}]},
|
{tags: ['hello', {label: 'tagLabel', permalink: '/tagPermalink'}]},
|
||||||
],
|
],
|
||||||
invalidFrontMatters: [
|
invalidFrontMatters: [
|
||||||
[{tags: ''}, '"tags" does not look like a valid FrontMatter Yaml array.'],
|
[
|
||||||
|
{tags: ''},
|
||||||
|
'"tags" does not look like a valid front matter Yaml array.',
|
||||||
|
],
|
||||||
[{tags: ['']}, 'not allowed to be empty'],
|
[{tags: ['']}, 'not allowed to be empty'],
|
||||||
],
|
],
|
||||||
// See https://github.com/facebook/docusaurus/issues/4642
|
// See https://github.com/facebook/docusaurus/issues/4642
|
||||||
|
|
|
@ -102,7 +102,7 @@ export default async function pluginContentBlog(
|
||||||
) as string[];
|
) as string[];
|
||||||
},
|
},
|
||||||
|
|
||||||
async getTranslationFiles() {
|
getTranslationFiles() {
|
||||||
return getTranslationFiles(options);
|
return getTranslationFiles(options);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ declare module '@docusaurus/plugin-content-blog' {
|
||||||
import type {FrontMatterTag, Tag} from '@docusaurus/utils';
|
import type {FrontMatterTag, Tag} from '@docusaurus/utils';
|
||||||
import type {Overwrite} from 'utility-types';
|
import type {Overwrite} from 'utility-types';
|
||||||
|
|
||||||
export interface Assets {
|
export type Assets = {
|
||||||
/**
|
/**
|
||||||
* If `metadata.image` is a collocated image path, this entry will be the
|
* If `metadata.image` is a collocated image path, this entry will be the
|
||||||
* bundler-generated image path. Otherwise, it's empty, and the image URL
|
* bundler-generated image path. Otherwise, it's empty, and the image URL
|
||||||
|
@ -25,13 +25,9 @@ declare module '@docusaurus/plugin-content-blog' {
|
||||||
* should be accessed through `authors.imageURL`.
|
* should be accessed through `authors.imageURL`.
|
||||||
*/
|
*/
|
||||||
authorsImageUrls: (string | undefined)[];
|
authorsImageUrls: (string | undefined)[];
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
export type Author = {
|
||||||
* Unknown keys are allowed, so that we can pass custom fields to authors,
|
|
||||||
* e.g., `twitter`.
|
|
||||||
*/
|
|
||||||
export interface Author extends Record<string, unknown> {
|
|
||||||
/**
|
/**
|
||||||
* If `name` doesn't exist, an `imageURL` is expected.
|
* If `name` doesn't exist, an `imageURL` is expected.
|
||||||
*/
|
*/
|
||||||
|
@ -55,7 +51,12 @@ declare module '@docusaurus/plugin-content-blog' {
|
||||||
* to generate a fallback `mailto:` URL.
|
* to generate a fallback `mailto:` URL.
|
||||||
*/
|
*/
|
||||||
email?: string;
|
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
|
* Everything is partial/unnormalized, because front matter is always
|
||||||
|
@ -443,8 +444,6 @@ declare module '@theme/BlogPostPage' {
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export type Content = {
|
export type Content = {
|
||||||
// TODO remove this. `metadata.frontMatter` is preferred because it can be
|
|
||||||
// accessed in enhanced plugins
|
|
||||||
/** Same as `metadata.frontMatter` */
|
/** Same as `metadata.frontMatter` */
|
||||||
readonly frontMatter: FrontMatter;
|
readonly frontMatter: FrontMatter;
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -11,39 +11,41 @@ import type {Metadata as BlogPaginatedMetadata} from '@theme/BlogListPage';
|
||||||
|
|
||||||
export type BlogContentPaths = ContentPaths;
|
export type BlogContentPaths = ContentPaths;
|
||||||
|
|
||||||
export interface BlogContent {
|
export type BlogContent = {
|
||||||
blogSidebarTitle: string;
|
blogSidebarTitle: string;
|
||||||
blogPosts: BlogPost[];
|
blogPosts: BlogPost[];
|
||||||
blogListPaginated: BlogPaginated[];
|
blogListPaginated: BlogPaginated[];
|
||||||
blogTags: BlogTags;
|
blogTags: BlogTags;
|
||||||
blogTagsListPath: string | null;
|
blogTagsListPath: string | null;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface BlogTags {
|
export type BlogTags = {
|
||||||
// TODO, the key is the tag slug/permalink
|
// TODO, the key is the tag slug/permalink
|
||||||
// This is due to legacy frontmatter: tags:
|
// This is due to legacy frontmatter: tags:
|
||||||
// [{label: "xyz", permalink: "/1"}, {label: "xyz", permalink: "/2"}]
|
// [{label: "xyz", permalink: "/1"}, {label: "xyz", permalink: "/2"}]
|
||||||
// Soon we should forbid declaring permalink through frontmatter
|
// Soon we should forbid declaring permalink through frontmatter
|
||||||
[tagKey: string]: BlogTag;
|
[tagKey: string]: BlogTag;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface BlogTag {
|
export type BlogTag = {
|
||||||
name: string;
|
name: string;
|
||||||
items: string[]; // blog post permalinks
|
/** Blog post permalinks. */
|
||||||
|
items: string[];
|
||||||
permalink: string;
|
permalink: string;
|
||||||
pages: BlogPaginated[];
|
pages: BlogPaginated[];
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface BlogPost {
|
export type BlogPost = {
|
||||||
id: string;
|
id: string;
|
||||||
metadata: BlogPostMetadata;
|
metadata: BlogPostMetadata;
|
||||||
content: string;
|
content: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface BlogPaginated {
|
export type BlogPaginated = {
|
||||||
metadata: BlogPaginatedMetadata;
|
metadata: BlogPaginatedMetadata;
|
||||||
items: string[]; // blog post permalinks
|
/** Blog post permalinks. */
|
||||||
}
|
items: string[];
|
||||||
|
};
|
||||||
|
|
||||||
export type BlogBrokenMarkdownLink = BrokenMarkdownLink<BlogContentPaths>;
|
export type BlogBrokenMarkdownLink = BrokenMarkdownLink<BlogContentPaths>;
|
||||||
export type BlogMarkdownLoaderOptions = {
|
export type BlogMarkdownLoaderOptions = {
|
||||||
|
|
|
@ -265,10 +265,13 @@ describe('validateDocFrontMatter tags', () => {
|
||||||
validFrontMatters: [{}, {tags: undefined}, {tags: ['tag1', 'tag2']}],
|
validFrontMatters: [{}, {tags: undefined}, {tags: ['tag1', 'tag2']}],
|
||||||
convertibleFrontMatter: [[{tags: ['tag1', 42]}, {tags: ['tag1', '42']}]],
|
convertibleFrontMatter: [[{tags: ['tag1', 42]}, {tags: ['tag1', '42']}]],
|
||||||
invalidFrontMatters: [
|
invalidFrontMatters: [
|
||||||
[{tags: 42}, '"tags" does not look like a valid FrontMatter Yaml array.'],
|
[
|
||||||
|
{tags: 42},
|
||||||
|
'"tags" does not look like a valid front matter Yaml array.',
|
||||||
|
],
|
||||||
[
|
[
|
||||||
{tags: 'tag1, tag2'},
|
{tags: 'tag1, tag2'},
|
||||||
'"tags" does not look like a valid FrontMatter Yaml array.',
|
'"tags" does not look like a valid front matter Yaml array.',
|
||||||
],
|
],
|
||||||
[{tags: [{}]}, '"tags[0]" does not look like a valid tag'],
|
[{tags: [{}]}, '"tags[0]" does not look like a valid tag'],
|
||||||
[{tags: [true]}, '"tags[0]" does not look like a valid tag'],
|
[{tags: [true]}, '"tags[0]" does not look like a valid tag'],
|
||||||
|
|
|
@ -106,7 +106,7 @@ export default async function pluginContentDocs(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async getTranslationFiles({content}) {
|
getTranslationFiles({content}) {
|
||||||
return getLoadedContentTranslationFiles(content);
|
return getLoadedContentTranslationFiles(content);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,9 @@ declare module '@docusaurus/plugin-content-docs' {
|
||||||
import type {ContentPaths, Tag, FrontMatterTag} from '@docusaurus/utils';
|
import type {ContentPaths, Tag, FrontMatterTag} from '@docusaurus/utils';
|
||||||
import type {Required} from 'utility-types';
|
import type {Required} from 'utility-types';
|
||||||
|
|
||||||
export interface Assets {
|
export type Assets = {
|
||||||
image?: string;
|
image?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom callback for parsing number prefixes from file/folder names.
|
* Custom callback for parsing number prefixes from file/folder names.
|
||||||
|
|
|
@ -254,18 +254,15 @@ export type SidebarItemsGenerator = (
|
||||||
generatorArgs: SidebarItemsGeneratorArgs,
|
generatorArgs: SidebarItemsGeneratorArgs,
|
||||||
) => Promise<NormalizedSidebar>;
|
) => Promise<NormalizedSidebar>;
|
||||||
|
|
||||||
// Also inject the default generator to conveniently wrap/enhance/sort the
|
export type SidebarItemsGeneratorOption = (
|
||||||
// default sidebar gen logic
|
generatorArgs: {
|
||||||
// see https://github.com/facebook/docusaurus/issues/4640#issuecomment-822292320
|
|
||||||
export type SidebarItemsGeneratorOptionArgs = {
|
|
||||||
/**
|
/**
|
||||||
* Useful to re-use/enhance the default sidebar generation logic from
|
* Useful to re-use/enhance the default sidebar generation logic from
|
||||||
* Docusaurus.
|
* Docusaurus.
|
||||||
|
* @see https://github.com/facebook/docusaurus/issues/4640#issuecomment-822292320
|
||||||
*/
|
*/
|
||||||
defaultSidebarItemsGenerator: SidebarItemsGenerator;
|
defaultSidebarItemsGenerator: SidebarItemsGenerator;
|
||||||
} & SidebarItemsGeneratorArgs;
|
} & SidebarItemsGeneratorArgs,
|
||||||
export type SidebarItemsGeneratorOption = (
|
|
||||||
generatorArgs: SidebarItemsGeneratorOptionArgs,
|
|
||||||
) => Promise<NormalizedSidebarItem[]>;
|
) => Promise<NormalizedSidebarItem[]>;
|
||||||
|
|
||||||
export type SidebarProcessorParams = {
|
export type SidebarProcessorParams = {
|
||||||
|
|
|
@ -33,12 +33,12 @@ declare module '@endiliey/react-ideal-image' {
|
||||||
| 'noicon'
|
| 'noicon'
|
||||||
| 'offline';
|
| 'offline';
|
||||||
|
|
||||||
export interface SrcType {
|
export type SrcType = {
|
||||||
width: number;
|
width: number;
|
||||||
src?: string;
|
src?: string;
|
||||||
size?: number;
|
size?: number;
|
||||||
format?: 'webp' | 'jpeg' | 'png' | 'gif';
|
format?: 'webp' | 'jpeg' | 'png' | 'gif';
|
||||||
}
|
};
|
||||||
|
|
||||||
type ThemeKey = 'placeholder' | 'img' | 'icon' | 'noscript';
|
type ThemeKey = 'placeholder' | 'img' | 'icon' | 'noscript';
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,9 @@ import type {Node, Parent} from 'unist';
|
||||||
import visit from 'unist-util-visit';
|
import visit from 'unist-util-visit';
|
||||||
import npmToYarn from 'npm-to-yarn';
|
import npmToYarn from 'npm-to-yarn';
|
||||||
|
|
||||||
interface PluginOptions {
|
type PluginOptions = {
|
||||||
sync?: boolean;
|
sync?: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
// E.g. global install: 'npm i' -> 'yarn'
|
// E.g. global install: 'npm i' -> 'yarn'
|
||||||
const convertNpmToYarn = (npmCode: string) => npmToYarn(npmCode, 'yarn');
|
const convertNpmToYarn = (npmCode: string) => npmToYarn(npmCode, 'yarn');
|
||||||
|
|
|
@ -118,7 +118,7 @@ export default function docusaurusThemeClassic(
|
||||||
return '../src/theme';
|
return '../src/theme';
|
||||||
},
|
},
|
||||||
|
|
||||||
getTranslationFiles: async () => getTranslationFiles({themeConfig}),
|
getTranslationFiles: () => getTranslationFiles({themeConfig}),
|
||||||
|
|
||||||
translateThemeConfig: (params) =>
|
translateThemeConfig: (params) =>
|
||||||
translateThemeConfig({
|
translateThemeConfig({
|
||||||
|
|
|
@ -13,11 +13,11 @@ import {ReactContextError} from '../utils/reactUtils';
|
||||||
// Inspired by https://github.com/jamiebuilds/unstated-next/blob/master/src/unstated-next.tsx
|
// Inspired by https://github.com/jamiebuilds/unstated-next/blob/master/src/unstated-next.tsx
|
||||||
const EmptyContext: unique symbol = Symbol('EmptyContext');
|
const EmptyContext: unique symbol = Symbol('EmptyContext');
|
||||||
|
|
||||||
type SidebarContextValue = {name: string; items: PropSidebar};
|
type ContextValue = {name: string; items: PropSidebar};
|
||||||
|
|
||||||
const Context = React.createContext<
|
const Context = React.createContext<ContextValue | null | typeof EmptyContext>(
|
||||||
SidebarContextValue | null | typeof EmptyContext
|
EmptyContext,
|
||||||
>(EmptyContext);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide the current sidebar to your children.
|
* Provide the current sidebar to your children.
|
||||||
|
@ -31,7 +31,7 @@ export function DocsSidebarProvider({
|
||||||
name: string | undefined;
|
name: string | undefined;
|
||||||
items: PropSidebar | undefined;
|
items: PropSidebar | undefined;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const stableValue: SidebarContextValue | null = useMemo(
|
const stableValue: ContextValue | null = useMemo(
|
||||||
() =>
|
() =>
|
||||||
name && items
|
name && items
|
||||||
? {
|
? {
|
||||||
|
@ -45,9 +45,9 @@ export function DocsSidebarProvider({
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the sidebar data that's currently displayed, or `null` if there isn't one
|
* Gets the sidebar that's currently displayed, or `null` if there isn't one
|
||||||
*/
|
*/
|
||||||
export function useDocsSidebar(): SidebarContextValue | null {
|
export function useDocsSidebar(): ContextValue | null {
|
||||||
const value = useContext(Context);
|
const value = useContext(Context);
|
||||||
if (value === EmptyContext) {
|
if (value === EmptyContext) {
|
||||||
throw new ReactContextError('DocsSidebarProvider');
|
throw new ReactContextError('DocsSidebarProvider');
|
||||||
|
|
|
@ -220,8 +220,9 @@ export function useDocsVersionCandidates(
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The layout components, like navbar items, must be able to work on all pages,
|
* The layout components, like navbar items, must be able to work on all pages,
|
||||||
* even on non-doc ones. This hook would always return a sidebar to be linked
|
* even on non-doc ones where there's no version context, so a sidebar ID could
|
||||||
* to. See also {@link useDocsVersionCandidates} for how this selection is done.
|
* be ambiguous. This hook would always return a sidebar to be linked to. See
|
||||||
|
* also {@link useDocsVersionCandidates} for how this selection is done.
|
||||||
*
|
*
|
||||||
* @throws This hook throws if a sidebar with said ID is not found.
|
* @throws This hook throws if a sidebar with said ID is not found.
|
||||||
*/
|
*/
|
||||||
|
@ -252,8 +253,9 @@ export function useLayoutDocsSidebar(
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The layout components, like navbar items, must be able to work on all pages,
|
* The layout components, like navbar items, must be able to work on all pages,
|
||||||
* even on non-doc ones. This hook would always return a doc to be linked
|
* even on non-doc ones where there's no version context, so a doc ID could be
|
||||||
* to. See also {@link useDocsVersionCandidates} for how this selection is done.
|
* ambiguous. This hook would always return a doc to be linked to. See also
|
||||||
|
* {@link useDocsVersionCandidates} for how this selection is done.
|
||||||
*
|
*
|
||||||
* @throws This hook throws if a doc with said ID is not found.
|
* @throws This hook throws if a doc with said ID is not found.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -12,13 +12,13 @@ import useRouteContext from '@docusaurus/useRouteContext';
|
||||||
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
|
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
|
||||||
import {useTitleFormatter} from './generalUtils';
|
import {useTitleFormatter} from './generalUtils';
|
||||||
|
|
||||||
interface PageMetadataProps {
|
type PageMetadataProps = {
|
||||||
readonly title?: string;
|
readonly title?: string;
|
||||||
readonly description?: string;
|
readonly description?: string;
|
||||||
readonly keywords?: readonly string[] | string;
|
readonly keywords?: readonly string[] | string;
|
||||||
readonly image?: string;
|
readonly image?: string;
|
||||||
readonly children?: ReactNode;
|
readonly children?: ReactNode;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper component to manipulate page metadata and override site defaults.
|
* Helper component to manipulate page metadata and override site defaults.
|
||||||
|
|
|
@ -54,11 +54,11 @@ Possible reasons: running Docusaurus in an iframe, in an incognito browser sessi
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenient storage interface for a single storage key
|
// Convenient storage interface for a single storage key
|
||||||
export interface StorageSlot {
|
export type StorageSlot = {
|
||||||
get: () => string | null;
|
get: () => string | null;
|
||||||
set: (value: string) => void;
|
set: (value: string) => void;
|
||||||
del: () => void;
|
del: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
const NoopStorageSlot: StorageSlot = {
|
const NoopStorageSlot: StorageSlot = {
|
||||||
get: () => null,
|
get: () => null,
|
||||||
|
|
|
@ -101,7 +101,7 @@ function filterTOC({
|
||||||
* to ensure that weird TOC structures preserve their semantics. For example, an
|
* to ensure that weird TOC structures preserve their semantics. For example, an
|
||||||
* h3-h2-h4 sequence should not be treeified as an "h3 > h4" hierarchy with
|
* h3-h2-h4 sequence should not be treeified as an "h3 > h4" hierarchy with
|
||||||
* min=3, max=4, but should rather be "[h3, h4]" (since the h2 heading has split
|
* min=3, max=4, but should rather be "[h3, h4]" (since the h2 heading has split
|
||||||
* the two headings and they are not parents)
|
* the two headings and they are not parent-children)
|
||||||
*/
|
*/
|
||||||
export function useFilteredAndTreeifiedTOC({
|
export function useFilteredAndTreeifiedTOC({
|
||||||
toc,
|
toc,
|
||||||
|
|
|
@ -10,10 +10,10 @@ declare module '@philpl/buble' {
|
||||||
// eslint-disable-next-line import/no-extraneous-dependencies, no-restricted-syntax
|
// eslint-disable-next-line import/no-extraneous-dependencies, no-restricted-syntax
|
||||||
export * from 'buble';
|
export * from 'buble';
|
||||||
export const features: string[];
|
export const features: string[];
|
||||||
export interface TransformOptions extends OriginalTransformOptions {
|
export type TransformOptions = OriginalTransformOptions & {
|
||||||
transforms?: OriginalTransformOptions['transforms'] & {
|
transforms?: OriginalTransformOptions['transforms'] & {
|
||||||
asyncAwait?: boolean;
|
asyncAwait?: boolean;
|
||||||
getterSetter?: boolean;
|
getterSetter?: boolean;
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,9 @@ declare module '@theme/Playground' {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module '@theme/ReactLiveScope' {
|
declare module '@theme/ReactLiveScope' {
|
||||||
interface Scope {
|
type Scope = {
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
}
|
};
|
||||||
|
|
||||||
const ReactLiveScope: Scope;
|
const ReactLiveScope: Scope;
|
||||||
export default ReactLiveScope;
|
export default ReactLiveScope;
|
||||||
|
|
16
packages/docusaurus-types/src/index.d.ts
vendored
16
packages/docusaurus-types/src/index.d.ts
vendored
|
@ -86,7 +86,7 @@ export type DocusaurusConfig = {
|
||||||
| string
|
| string
|
||||||
| {
|
| {
|
||||||
src: string;
|
src: string;
|
||||||
[key: string]: unknown;
|
[key: string]: string | boolean | undefined;
|
||||||
}
|
}
|
||||||
)[];
|
)[];
|
||||||
clientModules: string[];
|
clientModules: string[];
|
||||||
|
@ -96,7 +96,7 @@ export type DocusaurusConfig = {
|
||||||
| string
|
| string
|
||||||
| {
|
| {
|
||||||
href: string;
|
href: string;
|
||||||
[key: string]: unknown;
|
[key: string]: string | boolean | undefined;
|
||||||
}
|
}
|
||||||
)[];
|
)[];
|
||||||
titleDelimiter?: string;
|
titleDelimiter?: string;
|
||||||
|
@ -304,16 +304,16 @@ export type ThemeConfigValidationContext<T> = {
|
||||||
|
|
||||||
export type Plugin<Content = unknown> = {
|
export type Plugin<Content = unknown> = {
|
||||||
name: string;
|
name: string;
|
||||||
loadContent?: () => Promise<Content>;
|
loadContent?: () => Promise<Content> | Content;
|
||||||
contentLoaded?: (args: {
|
contentLoaded?: (args: {
|
||||||
/** the content loaded by this plugin instance */
|
/** the content loaded by this plugin instance */
|
||||||
content: Content; //
|
content: Content; //
|
||||||
/** content loaded by ALL the plugins */
|
/** content loaded by ALL the plugins */
|
||||||
allContent: AllContent;
|
allContent: AllContent;
|
||||||
actions: PluginContentLoadedActions;
|
actions: PluginContentLoadedActions;
|
||||||
}) => Promise<void>;
|
}) => Promise<void> | void;
|
||||||
routesLoaded?: (routes: RouteConfig[]) => void; // TODO remove soon, deprecated (alpha-60)
|
routesLoaded?: (routes: RouteConfig[]) => void; // TODO remove soon, deprecated (alpha-60)
|
||||||
postBuild?: (props: Props & {content: Content}) => Promise<void>;
|
postBuild?: (props: Props & {content: Content}) => Promise<void> | void;
|
||||||
// TODO refactor the configureWebpack API surface: use an object instead of
|
// TODO refactor the configureWebpack API surface: use an object instead of
|
||||||
// multiple params (requires breaking change)
|
// multiple params (requires breaking change)
|
||||||
configureWebpack?: (
|
configureWebpack?: (
|
||||||
|
@ -342,8 +342,10 @@ export type Plugin<Content = unknown> = {
|
||||||
// translations
|
// translations
|
||||||
getTranslationFiles?: (args: {
|
getTranslationFiles?: (args: {
|
||||||
content: Content;
|
content: Content;
|
||||||
}) => Promise<TranslationFile[]>;
|
}) => Promise<TranslationFile[]> | TranslationFile[];
|
||||||
getDefaultCodeTranslationMessages?: () => Promise<{[id: string]: string}>;
|
getDefaultCodeTranslationMessages?: () =>
|
||||||
|
| Promise<{[id: string]: string}>
|
||||||
|
| {[id: string]: string};
|
||||||
translateContent?: (args: {
|
translateContent?: (args: {
|
||||||
/** The content loaded by this plugin instance. */
|
/** The content loaded by this plugin instance. */
|
||||||
content: Content;
|
content: Content;
|
||||||
|
|
|
@ -83,7 +83,7 @@ export const FrontMatterTagsSchema = JoiFrontMatter.array()
|
||||||
.items(FrontMatterTagSchema)
|
.items(FrontMatterTagSchema)
|
||||||
.messages({
|
.messages({
|
||||||
'array.base':
|
'array.base':
|
||||||
'{{#label}} does not look like a valid FrontMatter Yaml array.',
|
'{{#label}} does not look like a valid front matter Yaml array.',
|
||||||
});
|
});
|
||||||
|
|
||||||
export const FrontMatterTOCHeadingLevels = {
|
export const FrontMatterTOCHeadingLevels = {
|
||||||
|
|
|
@ -19,18 +19,18 @@ import './nprogress.css';
|
||||||
|
|
||||||
nprogress.configure({showSpinner: false});
|
nprogress.configure({showSpinner: false});
|
||||||
|
|
||||||
interface Props extends RouteComponentProps {
|
type Props = RouteComponentProps & {
|
||||||
readonly routes: RouteConfig[];
|
readonly routes: RouteConfig[];
|
||||||
readonly delay: number;
|
readonly delay: number;
|
||||||
readonly location: Location;
|
readonly location: Location;
|
||||||
}
|
};
|
||||||
interface State {
|
type State = {
|
||||||
nextRouteHasLoaded: boolean;
|
nextRouteHasLoaded: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
class PendingNavigation extends React.Component<Props, State> {
|
class PendingNavigation extends React.Component<Props, State> {
|
||||||
previousLocation: Location | null;
|
private previousLocation: Location | null;
|
||||||
progressBarTimeout: NodeJS.Timeout | null;
|
private progressBarTimeout: NodeJS.Timeout | null;
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -11,9 +11,9 @@ import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
||||||
import type {Props} from '@docusaurus/ErrorBoundary';
|
import type {Props} from '@docusaurus/ErrorBoundary';
|
||||||
import DefaultFallback from '@theme/Error';
|
import DefaultFallback from '@theme/Error';
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
error: Error | null;
|
error: Error | null;
|
||||||
}
|
};
|
||||||
|
|
||||||
export default class ErrorBoundary extends React.Component<Props, State> {
|
export default class ErrorBoundary extends React.Component<Props, State> {
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
|
|
8
packages/docusaurus/src/deps.d.ts
vendored
8
packages/docusaurus/src/deps.d.ts
vendored
|
@ -26,9 +26,9 @@ declare module 'react-loadable-ssr-addon-v5-slorber' {
|
||||||
modulesToBeLoaded: string[],
|
modulesToBeLoaded: string[],
|
||||||
): {js: Asset[]; css: Asset[]};
|
): {js: Asset[]; css: Asset[]};
|
||||||
|
|
||||||
interface ReactLoadableSSRAddon {
|
type ReactLoadableSSRAddon = {
|
||||||
new (props: {filename: string});
|
new (props: {filename: string});
|
||||||
}
|
};
|
||||||
|
|
||||||
const plugin: ReactLoadableSSRAddon;
|
const plugin: ReactLoadableSSRAddon;
|
||||||
export default plugin;
|
export default plugin;
|
||||||
|
@ -47,7 +47,7 @@ declare module '@slorber/static-site-generator-webpack-plugin' {
|
||||||
noIndex: boolean;
|
noIndex: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface StaticSiteGeneratorPlugin {
|
type StaticSiteGeneratorPlugin = {
|
||||||
new (props: {
|
new (props: {
|
||||||
entry: string;
|
entry: string;
|
||||||
locals: Locals;
|
locals: Locals;
|
||||||
|
@ -55,7 +55,7 @@ declare module '@slorber/static-site-generator-webpack-plugin' {
|
||||||
preferFoldersOutput?: boolean;
|
preferFoldersOutput?: boolean;
|
||||||
globals: {[key: string]: unknown};
|
globals: {[key: string]: unknown};
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
const plugin: StaticSiteGeneratorPlugin;
|
const plugin: StaticSiteGeneratorPlugin;
|
||||||
export default plugin;
|
export default plugin;
|
||||||
|
|
|
@ -36,26 +36,27 @@ export function createBootstrapPlugin({
|
||||||
return siteConfigClientModules;
|
return siteConfigClientModules;
|
||||||
},
|
},
|
||||||
injectHtmlTags: () => {
|
injectHtmlTags: () => {
|
||||||
const stylesheetsTags = stylesheets.map((source) =>
|
const stylesheetsTags = stylesheets.map(
|
||||||
|
(source): string | HtmlTagObject =>
|
||||||
typeof source === 'string'
|
typeof source === 'string'
|
||||||
? `<link rel="stylesheet" href="${source}">`
|
? `<link rel="stylesheet" href="${source}">`
|
||||||
: ({
|
: {
|
||||||
tagName: 'link',
|
tagName: 'link',
|
||||||
attributes: {
|
attributes: {
|
||||||
rel: 'stylesheet',
|
rel: 'stylesheet',
|
||||||
...source,
|
...source,
|
||||||
},
|
},
|
||||||
} as HtmlTagObject),
|
},
|
||||||
);
|
);
|
||||||
const scriptsTags = scripts.map((source) =>
|
const scriptsTags = scripts.map((source): string | HtmlTagObject =>
|
||||||
typeof source === 'string'
|
typeof source === 'string'
|
||||||
? `<script src="${source}"></script>`
|
? `<script src="${source}"></script>`
|
||||||
: ({
|
: {
|
||||||
tagName: 'script',
|
tagName: 'script',
|
||||||
attributes: {
|
attributes: {
|
||||||
...source,
|
...source,
|
||||||
},
|
},
|
||||||
} as HtmlTagObject),
|
},
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
headTags: [...stylesheetsTags, ...scriptsTags],
|
headTags: [...stylesheetsTags, ...scriptsTags],
|
||||||
|
|
|
@ -33,7 +33,7 @@ import type {Compiler, Stats} from 'webpack';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {sync as delSync} from 'del';
|
import {sync as delSync} from 'del';
|
||||||
|
|
||||||
export interface Options {
|
export type Options = {
|
||||||
/**
|
/**
|
||||||
* Write Logs to Console
|
* Write Logs to Console
|
||||||
* (Always enabled when dry is true)
|
* (Always enabled when dry is true)
|
||||||
|
@ -65,7 +65,7 @@ export interface Options {
|
||||||
* default: ['**\/*']
|
* default: ['**\/*']
|
||||||
*/
|
*/
|
||||||
cleanOnceBeforeBuildPatterns?: string[];
|
cleanOnceBeforeBuildPatterns?: string[];
|
||||||
}
|
};
|
||||||
|
|
||||||
export default class CleanWebpackPlugin {
|
export default class CleanWebpackPlugin {
|
||||||
private readonly verbose: boolean;
|
private readonly verbose: boolean;
|
||||||
|
|
|
@ -10,9 +10,9 @@ import fs from 'fs-extra';
|
||||||
import waitOn from 'wait-on';
|
import waitOn from 'wait-on';
|
||||||
import type {Compiler} from 'webpack';
|
import type {Compiler} from 'webpack';
|
||||||
|
|
||||||
interface WaitPluginOptions {
|
type WaitPluginOptions = {
|
||||||
filepath: string;
|
filepath: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export default class WaitPlugin {
|
export default class WaitPlugin {
|
||||||
filepath: string;
|
filepath: string;
|
||||||
|
|
|
@ -24,13 +24,13 @@ The plugin module's default export is a constructor function with the signature
|
||||||
`context` is plugin-agnostic, and the same object will be passed into all plugins used for a Docusaurus website. The `context` object contains the following fields:
|
`context` is plugin-agnostic, and the same object will be passed into all plugins used for a Docusaurus website. The `context` object contains the following fields:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
interface LoadContext {
|
type LoadContext = {
|
||||||
siteDir: string;
|
siteDir: string;
|
||||||
generatedFilesDir: string;
|
generatedFilesDir: string;
|
||||||
siteConfig: DocusaurusConfig;
|
siteConfig: DocusaurusConfig;
|
||||||
outDir: string;
|
outDir: string;
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
}
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
### `options` {#options}
|
### `options` {#options}
|
||||||
|
|
|
@ -43,17 +43,17 @@ The data that was loaded in `loadContent` will be consumed in `contentLoaded`. I
|
||||||
Create a route to add to the website.
|
Create a route to add to the website.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
interface RouteConfig {
|
type RouteConfig = {
|
||||||
path: string;
|
path: string;
|
||||||
component: string;
|
component: string;
|
||||||
modules?: RouteModules;
|
modules?: RouteModules;
|
||||||
routes?: RouteConfig[];
|
routes?: RouteConfig[];
|
||||||
exact?: boolean;
|
exact?: boolean;
|
||||||
priority?: number;
|
priority?: number;
|
||||||
}
|
};
|
||||||
interface RouteModules {
|
type RouteModules = {
|
||||||
[module: string]: Module | RouteModules | RouteModules[];
|
[module: string]: Module | RouteModules | RouteModules[];
|
||||||
}
|
};
|
||||||
type Module =
|
type Module =
|
||||||
| {
|
| {
|
||||||
path: string;
|
path: string;
|
||||||
|
@ -339,7 +339,7 @@ function injectHtmlTags(): {
|
||||||
|
|
||||||
type HtmlTags = string | HtmlTagObject | (string | HtmlTagObject)[];
|
type HtmlTags = string | HtmlTagObject | (string | HtmlTagObject)[];
|
||||||
|
|
||||||
interface HtmlTagObject {
|
type HtmlTagObject = {
|
||||||
/**
|
/**
|
||||||
* Attributes of the HTML tag
|
* Attributes of the HTML tag
|
||||||
* E.g. `{'disabled': true, 'value': 'demo', 'rel': 'preconnect'}`
|
* E.g. `{'disabled': true, 'value': 'demo', 'rel': 'preconnect'}`
|
||||||
|
@ -355,7 +355,7 @@ interface HtmlTagObject {
|
||||||
* The inner HTML
|
* The inner HTML
|
||||||
*/
|
*/
|
||||||
innerHTML?: string;
|
innerHTML?: string;
|
||||||
}
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
|
@ -341,31 +341,31 @@ type PluginVersionInformation =
|
||||||
| {readonly type: 'local'}
|
| {readonly type: 'local'}
|
||||||
| {readonly type: 'synthetic'};
|
| {readonly type: 'synthetic'};
|
||||||
|
|
||||||
interface SiteMetadata {
|
type SiteMetadata = {
|
||||||
readonly docusaurusVersion: string;
|
readonly docusaurusVersion: string;
|
||||||
readonly siteVersion?: string;
|
readonly siteVersion?: string;
|
||||||
readonly pluginVersions: Record<string, PluginVersionInformation>;
|
readonly pluginVersions: Record<string, PluginVersionInformation>;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface I18nLocaleConfig {
|
type I18nLocaleConfig = {
|
||||||
label: string;
|
label: string;
|
||||||
direction: string;
|
direction: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface I18n {
|
type I18n = {
|
||||||
defaultLocale: string;
|
defaultLocale: string;
|
||||||
locales: [string, ...string[]];
|
locales: [string, ...string[]];
|
||||||
currentLocale: string;
|
currentLocale: string;
|
||||||
localeConfigs: Record<string, I18nLocaleConfig>;
|
localeConfigs: Record<string, I18nLocaleConfig>;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface DocusaurusContext {
|
type DocusaurusContext = {
|
||||||
siteConfig: DocusaurusConfig;
|
siteConfig: DocusaurusConfig;
|
||||||
siteMetadata: SiteMetadata;
|
siteMetadata: SiteMetadata;
|
||||||
globalData: Record<string, unknown>;
|
globalData: Record<string, unknown>;
|
||||||
i18n: I18n;
|
i18n: I18n;
|
||||||
codeTranslations: Record<string, string>;
|
codeTranslations: Record<string, string>;
|
||||||
}
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Usage example:
|
Usage example:
|
||||||
|
|
|
@ -9,14 +9,14 @@ import React, {type ReactNode, type ComponentProps} from 'react';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
|
|
||||||
export interface SvgIconProps extends ComponentProps<'svg'> {
|
export type SvgIconProps = ComponentProps<'svg'> & {
|
||||||
viewBox?: string;
|
viewBox?: string;
|
||||||
size?: 'inherit' | 'small' | 'medium' | 'large';
|
size?: 'inherit' | 'small' | 'medium' | 'large';
|
||||||
color?: 'inherit' | 'primary' | 'secondary' | 'success' | 'error' | 'warning';
|
color?: 'inherit' | 'primary' | 'secondary' | 'success' | 'error' | 'warning';
|
||||||
svgClass?: string; // Class attribute on the child
|
svgClass?: string; // Class attribute on the child
|
||||||
colorAttr?: string; // Applies a color attribute to the SVG element.
|
colorAttr?: string; // Applies a color attribute to the SVG element.
|
||||||
children: ReactNode; // Node passed into the SVG element.
|
children: ReactNode; // Node passed into the SVG element.
|
||||||
}
|
};
|
||||||
|
|
||||||
export default function Svg(props: SvgIconProps): JSX.Element {
|
export default function Svg(props: SvgIconProps): JSX.Element {
|
||||||
const {
|
const {
|
||||||
|
|
|
@ -19,13 +19,13 @@ function WebsiteLink({to, children}: {to: string; children?: ReactNode}) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ProfileProps {
|
type ProfileProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
name: string;
|
name: string;
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
githubUrl?: string;
|
githubUrl?: string;
|
||||||
twitterUrl?: string;
|
twitterUrl?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
function TeamProfileCard({
|
function TeamProfileCard({
|
||||||
className,
|
className,
|
||||||
|
|
|
@ -9,9 +9,9 @@ import React from 'react';
|
||||||
|
|
||||||
import type {Props as Tweet} from '../components/Tweet';
|
import type {Props as Tweet} from '../components/Tweet';
|
||||||
|
|
||||||
export interface TweetItem extends Tweet {
|
export type TweetItem = Tweet & {
|
||||||
showOnHomepage: boolean;
|
showOnHomepage: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
const TWEETS: TweetItem[] = [
|
const TWEETS: TweetItem[] = [
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue