diff --git a/packages/docusaurus-plugin-client-redirects/package.json b/packages/docusaurus-plugin-client-redirects/package.json index 269f85b80f..c632526d40 100644 --- a/packages/docusaurus-plugin-client-redirects/package.json +++ b/packages/docusaurus-plugin-client-redirects/package.json @@ -12,6 +12,7 @@ }, "license": "MIT", "dependencies": { + "@docusaurus/core": "^2.0.0-alpha.61", "@docusaurus/types": "^2.0.0-alpha.61", "@docusaurus/utils": "^2.0.0-alpha.61", "@hapi/joi": "^17.1.1", diff --git a/packages/docusaurus-plugin-client-redirects/src/__tests__/normalizePluginOptions.test.ts b/packages/docusaurus-plugin-client-redirects/src/__tests__/normalizePluginOptions.test.ts index 19ea156a22..c21fe24fd4 100644 --- a/packages/docusaurus-plugin-client-redirects/src/__tests__/normalizePluginOptions.test.ts +++ b/packages/docusaurus-plugin-client-redirects/src/__tests__/normalizePluginOptions.test.ts @@ -39,6 +39,7 @@ describe('normalizePluginOptions', () => { redirects: [{from: '/x', to: '/y'}], }), ).toEqual({ + id: 'default', fromExtensions: ['exe', 'zip'], toExtensions: ['html'], createRedirects, diff --git a/packages/docusaurus-plugin-client-redirects/src/normalizePluginOptions.ts b/packages/docusaurus-plugin-client-redirects/src/normalizePluginOptions.ts index b5e07f6623..b05bee9f10 100644 --- a/packages/docusaurus-plugin-client-redirects/src/normalizePluginOptions.ts +++ b/packages/docusaurus-plugin-client-redirects/src/normalizePluginOptions.ts @@ -8,8 +8,10 @@ import {PluginOptions, RedirectOption, UserPluginOptions} from './types'; import * as Joi from '@hapi/joi'; import {PathnameValidator} from './redirectValidation'; +import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants'; export const DefaultPluginOptions: PluginOptions = { + id: DEFAULT_PLUGIN_ID, // TODO temporary fromExtensions: [], toExtensions: [], redirects: [], @@ -26,6 +28,7 @@ const RedirectPluginOptionValidation = Joi.object({ const isString = Joi.string().required().not(null); const UserOptionsSchema = Joi.object({ + id: Joi.string().optional(), // TODO remove once validation migrated to new system fromExtensions: Joi.array().items(isString), toExtensions: Joi.array().items(isString), redirects: Joi.array().items(RedirectPluginOptionValidation), diff --git a/packages/docusaurus-plugin-client-redirects/src/types.ts b/packages/docusaurus-plugin-client-redirects/src/types.ts index 15c0987e0d..32ccdfd66d 100644 --- a/packages/docusaurus-plugin-client-redirects/src/types.ts +++ b/packages/docusaurus-plugin-client-redirects/src/types.ts @@ -8,6 +8,7 @@ import {Props} from '@docusaurus/types'; export type PluginOptions = { + id: string; fromExtensions: string[]; toExtensions: string[]; redirects: RedirectOption[]; diff --git a/packages/docusaurus-plugin-content-blog/src/index.ts b/packages/docusaurus-plugin-content-blog/src/index.ts index c77f082a7b..8a4573f596 100644 --- a/packages/docusaurus-plugin-content-blog/src/index.ts +++ b/packages/docusaurus-plugin-content-blog/src/index.ts @@ -28,7 +28,6 @@ import { import {PluginOptionSchema} from './pluginOptionSchema'; import { LoadContext, - PluginContentLoadedActions, ConfigureWebpackUtils, Props, Plugin, @@ -195,13 +194,7 @@ export default function pluginContentBlog( }; }, - async contentLoaded({ - content: blogContents, - actions, - }: { - content: BlogContent; - actions: PluginContentLoadedActions; - }) { + async contentLoaded({content: blogContents, actions}) { if (!blogContents) { return; } diff --git a/packages/docusaurus-plugin-debug/package.json b/packages/docusaurus-plugin-debug/package.json index edf4a03bca..b50d3e1307 100644 --- a/packages/docusaurus-plugin-debug/package.json +++ b/packages/docusaurus-plugin-debug/package.json @@ -13,7 +13,8 @@ "license": "MIT", "dependencies": { "@docusaurus/types": "^2.0.0-alpha.61", - "@docusaurus/utils": "^2.0.0-alpha.61" + "@docusaurus/utils": "^2.0.0-alpha.61", + "react-json-view": "^1.19.1" }, "peerDependencies": { "@docusaurus/core": "^2.0.0", diff --git a/packages/docusaurus-plugin-debug/src/index.ts b/packages/docusaurus-plugin-debug/src/index.ts index 8eadee8566..1ca9d6f0e1 100644 --- a/packages/docusaurus-plugin-debug/src/index.ts +++ b/packages/docusaurus-plugin-debug/src/index.ts @@ -6,13 +6,20 @@ */ import {LoadContext, Plugin} from '@docusaurus/types'; -import {normalizeUrl} from '@docusaurus/utils'; - +import {docuHash, normalizeUrl} from '@docusaurus/utils'; import path from 'path'; export default function pluginContentPages({ siteConfig: {baseUrl}, + generatedFilesDir, }: LoadContext): Plugin { + const pluginDataDirRoot = path.join( + generatedFilesDir, + 'docusaurus-plugin-debug', + ); + const aliasedSource = (source: string) => + `~debug/${path.relative(pluginDataDirRoot, source)}`; + return { name: 'docusaurus-plugin-debug', @@ -20,12 +27,63 @@ export default function pluginContentPages({ return path.resolve(__dirname, '../src/theme'); }, - contentLoaded({actions: {addRoute}}) { + async contentLoaded({actions: {createData, addRoute}, allContent}) { + const allContentPath = await createData( + // Note that this created data path must be in sync with + // metadataPath provided to mdx-loader. + `${docuHash('docusaurus-debug-allContent')}.json`, + JSON.stringify(allContent, null, 2), + ); + + // Home is config (duplicate for now) addRoute({ path: normalizeUrl([baseUrl, '__docusaurus/debug']), - component: '@theme/Debug', + component: '@theme/DebugConfig', exact: true, }); + + addRoute({ + path: normalizeUrl([baseUrl, '__docusaurus/debug/config']), + component: '@theme/DebugConfig', + exact: true, + }); + + addRoute({ + path: normalizeUrl([baseUrl, '__docusaurus/debug/metadata']), + component: '@theme/DebugMetadata', + exact: true, + }); + + addRoute({ + path: normalizeUrl([baseUrl, '__docusaurus/debug/registry']), + component: '@theme/DebugRegistry', + exact: true, + }); + + addRoute({ + path: normalizeUrl([baseUrl, '__docusaurus/debug/routes']), + component: '@theme/DebugRoutes', + exact: true, + }); + + addRoute({ + path: normalizeUrl([baseUrl, '__docusaurus/debug/content']), + component: '@theme/DebugContent', + exact: true, + modules: { + allContent: aliasedSource(allContentPath), + }, + }); + }, + + configureWebpack() { + return { + resolve: { + alias: { + '~debug': pluginDataDirRoot, + }, + }, + }; }, }; } diff --git a/packages/docusaurus-plugin-debug/src/theme/Debug/index.js b/packages/docusaurus-plugin-debug/src/theme/Debug/index.js deleted file mode 100644 index 49a3a9f451..0000000000 --- a/packages/docusaurus-plugin-debug/src/theme/Debug/index.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * 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. - */ - -import React from 'react'; -import Layout from '@theme/Layout'; - -import registry from '@generated/registry'; -import routes from '@generated/routes'; - -import styles from './styles.module.css'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; - -function Debug() { - const {siteMetadata} = useDocusaurusContext(); - return ( - -
-
-

Site Metadata

-
Docusaurus Version: {siteMetadata.docusaurusVersion}
-
- Site Version: {siteMetadata.siteVersion || 'No version specified'} -
-

Plugins and themes:

-
    - {Object.entries(siteMetadata.pluginVersions).map( - ([name, versionInformation]) => ( -
  • -
    Name: {name}
    -
    Type: {versionInformation.type}
    - {versionInformation.version && ( -
    Version: {versionInformation.version}
    - )} -
  • - ), - )} -
-
-
-

Registry

-
    - {Object.values(registry).map(([, aliasedPath, resolved]) => ( -
  • -
    Aliased Path: {aliasedPath}
    -
    Resolved Path: {resolved}
    -
  • - ))} -
-
-
-

Routes

-
    - {routes.map(({path, exact}) => ( -
  • -
    Route: {path}
    -
    Is exact: {String(Boolean(exact))}
    -
  • - ))} -
-
-
-
- ); -} - -export default Debug; diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugConfig/index.js b/packages/docusaurus-plugin-debug/src/theme/DebugConfig/index.js new file mode 100644 index 0000000000..99a4191bc8 --- /dev/null +++ b/packages/docusaurus-plugin-debug/src/theme/DebugConfig/index.js @@ -0,0 +1,23 @@ +/** + * 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. + */ + +import React from 'react'; + +import DebugLayout from '../DebugLayout'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; + +function DebugMetadata() { + const {siteConfig} = useDocusaurusContext(); + return ( + +

Site config

+
{JSON.stringify(siteConfig, null, 2)}
+
+ ); +} + +export default DebugMetadata; diff --git a/packages/docusaurus-plugin-debug/src/theme/Debug/styles.module.css b/packages/docusaurus-plugin-debug/src/theme/DebugConfig/styles.module.css similarity index 60% rename from packages/docusaurus-plugin-debug/src/theme/Debug/styles.module.css rename to packages/docusaurus-plugin-debug/src/theme/DebugConfig/styles.module.css index 8dee72f3c8..99ba01cb77 100644 --- a/packages/docusaurus-plugin-debug/src/theme/Debug/styles.module.css +++ b/packages/docusaurus-plugin-debug/src/theme/DebugConfig/styles.module.css @@ -5,13 +5,3 @@ * LICENSE file in the root directory of this source tree. */ -.Container { - display: flex; - flex-wrap: wrap; - justify-content: center; - margin: 1em; -} - -.Section { - width: 500px; -} diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugContent/index.js b/packages/docusaurus-plugin-debug/src/theme/DebugContent/index.js new file mode 100644 index 0000000000..c79f7899c4 --- /dev/null +++ b/packages/docusaurus-plugin-debug/src/theme/DebugContent/index.js @@ -0,0 +1,84 @@ +/** + * 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. + */ + +import React, {useState} from 'react'; + +import DebugLayout from '../DebugLayout'; +import DebugJsonView from '../DebugJsonView'; + +const PluginInstanceContent = ({pluginId, pluginInstanceContent}) => ( +
+

{`>> ${pluginId}`}

+
+ +
+
+); + +const PluginContent = ({pluginName, pluginContent}) => { + const [visible, setVisible] = useState(true); + return ( +
+

setVisible((v) => !v)} style={{cursor: 'pointer'}}> + {pluginName} +

+ {visible && ( +
+ {Object.entries(pluginContent) + // filter plugin instances with no content + .filter( + ([_pluginId, pluginInstanceContent]) => !!pluginInstanceContent, + ) + .map(([pluginId, pluginInstanceContent]) => { + return ( + + ); + })} +
+ )} +
+ ); +}; + +function DebugContent({allContent}) { + return ( + +

Plugin content

+
+ {Object.entries(allContent) + // filter plugins with no content + .filter(([_pluginName, pluginContent]) => + Object.values(pluginContent).some( + (instanceContent) => !!instanceContent, + ), + ) + .map(([pluginName, pluginContent]) => { + return ( + + ); + })} +
+
+ ); +} + +export default DebugContent; diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugContent/styles.module.css b/packages/docusaurus-plugin-debug/src/theme/DebugContent/styles.module.css new file mode 100644 index 0000000000..99ba01cb77 --- /dev/null +++ b/packages/docusaurus-plugin-debug/src/theme/DebugContent/styles.module.css @@ -0,0 +1,7 @@ +/** + * 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. + */ + diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugJsonView/index.js b/packages/docusaurus-plugin-debug/src/theme/DebugJsonView/index.js new file mode 100644 index 0000000000..558b31c71c --- /dev/null +++ b/packages/docusaurus-plugin-debug/src/theme/DebugJsonView/index.js @@ -0,0 +1,43 @@ +/** + * 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. + */ + +import React from 'react'; + +import BrowserOnly from '@docusaurus/BrowserOnly'; + +// avoids "react-json-view" to display "root" +const RootName = false; + +// Seems ReactJson does not work with SSR +// https://github.com/mac-s-g/react-json-view/issues/121 +const BrowserOnlyReactJson = (props) => { + return ( + + {() => { + const ReactJson = require('react-json-view').default; + return ; + }} + + ); +}; + +function DebugJsonView({src}) { + return ( + { + // By default, we collapse the json for performance reasons + // See https://github.com/mac-s-g/react-json-view/issues/235 + // only the "root" is not collapsed + return field.name !== RootName; + }} + /> + ); +} + +export default DebugJsonView; diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugJsonView/styles.module.css b/packages/docusaurus-plugin-debug/src/theme/DebugJsonView/styles.module.css new file mode 100644 index 0000000000..99ba01cb77 --- /dev/null +++ b/packages/docusaurus-plugin-debug/src/theme/DebugJsonView/styles.module.css @@ -0,0 +1,7 @@ +/** + * 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. + */ + diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugLayout/index.js b/packages/docusaurus-plugin-debug/src/theme/DebugLayout/index.js new file mode 100644 index 0000000000..02c2eb7f86 --- /dev/null +++ b/packages/docusaurus-plugin-debug/src/theme/DebugLayout/index.js @@ -0,0 +1,39 @@ +/** + * 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. + */ + +import React from 'react'; +import Link from '@docusaurus/Link'; +// import styles from './styles.module.css'; + +const DebugNavLink = ({to, children}) => ( + + {children} + +); + +function DebugLayout({children}) { + return ( +
+ +
{children}
+
+ ); +} + +export default DebugLayout; diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugLayout/styles.module.css b/packages/docusaurus-plugin-debug/src/theme/DebugLayout/styles.module.css new file mode 100644 index 0000000000..b5c0e33b4a --- /dev/null +++ b/packages/docusaurus-plugin-debug/src/theme/DebugLayout/styles.module.css @@ -0,0 +1,6 @@ +/** + * 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. + */ diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugMetadata/index.js b/packages/docusaurus-plugin-debug/src/theme/DebugMetadata/index.js new file mode 100644 index 0000000000..9cb98a2e1e --- /dev/null +++ b/packages/docusaurus-plugin-debug/src/theme/DebugMetadata/index.js @@ -0,0 +1,40 @@ +/** + * 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. + */ + +import React from 'react'; + +import DebugLayout from '../DebugLayout'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; + +function DebugMetadata() { + const {siteMetadata} = useDocusaurusContext(); + return ( + +

Site Metadata

+
Docusaurus Version: {siteMetadata.docusaurusVersion}
+
+ Site Version: {siteMetadata.siteVersion || 'No version specified'} +
+

Plugins and themes:

+
    + {Object.entries(siteMetadata.pluginVersions).map( + ([name, versionInformation]) => ( +
  • +
    Name: {name}
    +
    Type: {versionInformation.type}
    + {versionInformation.version && ( +
    Version: {versionInformation.version}
    + )} +
  • + ), + )} +
+
+ ); +} + +export default DebugMetadata; diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugMetadata/styles.module.css b/packages/docusaurus-plugin-debug/src/theme/DebugMetadata/styles.module.css new file mode 100644 index 0000000000..99ba01cb77 --- /dev/null +++ b/packages/docusaurus-plugin-debug/src/theme/DebugMetadata/styles.module.css @@ -0,0 +1,7 @@ +/** + * 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. + */ + diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugRegistry/index.js b/packages/docusaurus-plugin-debug/src/theme/DebugRegistry/index.js new file mode 100644 index 0000000000..f10a53a8a6 --- /dev/null +++ b/packages/docusaurus-plugin-debug/src/theme/DebugRegistry/index.js @@ -0,0 +1,30 @@ +/** + * 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. + */ + +import React from 'react'; + +import DebugLayout from '../DebugLayout'; +import registry from '@generated/registry'; + +function DebugRegistry() { + return ( + + {' '} +

Registry

+
    + {Object.values(registry).map(([, aliasedPath, resolved]) => ( +
  • +
    Aliased Path: {aliasedPath}
    +
    Resolved Path: {resolved}
    +
  • + ))} +
+
+ ); +} + +export default DebugRegistry; diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugRegistry/styles.module.css b/packages/docusaurus-plugin-debug/src/theme/DebugRegistry/styles.module.css new file mode 100644 index 0000000000..99ba01cb77 --- /dev/null +++ b/packages/docusaurus-plugin-debug/src/theme/DebugRegistry/styles.module.css @@ -0,0 +1,7 @@ +/** + * 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. + */ + diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugRoutes/index.js b/packages/docusaurus-plugin-debug/src/theme/DebugRoutes/index.js new file mode 100644 index 0000000000..5eedd036f4 --- /dev/null +++ b/packages/docusaurus-plugin-debug/src/theme/DebugRoutes/index.js @@ -0,0 +1,29 @@ +/** + * 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. + */ + +import React from 'react'; + +import DebugLayout from '../DebugLayout'; +import routes from '@generated/routes'; + +function DebugRoutes() { + return ( + +

Routes

+
    + {routes.map(({path, exact}) => ( +
  • +
    Route: {path}
    +
    Is exact: {String(Boolean(exact))}
    +
  • + ))} +
+
+ ); +} + +export default DebugRoutes; diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugRoutes/styles.module.css b/packages/docusaurus-plugin-debug/src/theme/DebugRoutes/styles.module.css new file mode 100644 index 0000000000..99ba01cb77 --- /dev/null +++ b/packages/docusaurus-plugin-debug/src/theme/DebugRoutes/styles.module.css @@ -0,0 +1,7 @@ +/** + * 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. + */ + diff --git a/packages/docusaurus-preset-classic/src/index.js b/packages/docusaurus-preset-classic/src/index.js index 894fe315c2..47f65208f1 100644 --- a/packages/docusaurus-preset-classic/src/index.js +++ b/packages/docusaurus-preset-classic/src/index.js @@ -11,6 +11,9 @@ module.exports = function preset(context, opts = {}) { const {algolia, googleAnalytics, gtag} = themeConfig; const isProd = process.env.NODE_ENV === 'production'; + const debug = + typeof opts.debug !== 'undefined' ? Boolean(opts.debug) : !isProd; + return { themes: [ [require.resolve('@docusaurus/theme-classic'), opts.theme], @@ -24,7 +27,7 @@ module.exports = function preset(context, opts = {}) { isProd && googleAnalytics && require.resolve('@docusaurus/plugin-google-analytics'), - !isProd && require.resolve('@docusaurus/plugin-debug'), + debug && require.resolve('@docusaurus/plugin-debug'), isProd && gtag && require.resolve('@docusaurus/plugin-google-gtag'), isProd && [require.resolve('@docusaurus/plugin-sitemap'), opts.sitemap], ], diff --git a/packages/docusaurus-theme-bootstrap/src/theme/Layout/index.js b/packages/docusaurus-theme-bootstrap/src/theme/DebugLayout/index.js similarity index 100% rename from packages/docusaurus-theme-bootstrap/src/theme/Layout/index.js rename to packages/docusaurus-theme-bootstrap/src/theme/DebugLayout/index.js diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index 14ee8dd2b9..d2b0bf4c61 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -126,8 +126,15 @@ export interface PluginContentLoadedActions { setGlobalData(data: T): void; } +export type AllContent = Record< + string, // plugin name + Record< + string, // plugin id + unknown // plugin data + > +>; + export interface Plugin { - id?: string; name: string; loadContent?(): Promise; validateOptions?(): ValidationResult; @@ -136,7 +143,8 @@ export interface Plugin { content, actions, }: { - content: T; + content: T; // the content loaded by this plugin instance + allContent: AllContent; // content loaded by ALL the plugins actions: PluginContentLoadedActions; }): void; routesLoaded?(routes: RouteConfig[]): void; // TODO remove soon, deprecated (alpha-60) diff --git a/packages/docusaurus/src/server/plugins/index.ts b/packages/docusaurus/src/server/plugins/index.ts index 619afeed6a..8d3306e3a1 100644 --- a/packages/docusaurus/src/server/plugins/index.ts +++ b/packages/docusaurus/src/server/plugins/index.ts @@ -9,6 +9,7 @@ import {generate} from '@docusaurus/utils'; import fs from 'fs-extra'; import path from 'path'; import { + AllContent, LoadContext, PluginConfig, PluginContentLoadedActions, @@ -17,6 +18,7 @@ import { import initPlugins, {InitPlugin} from './init'; import chalk from 'chalk'; import {DEFAULT_PLUGIN_ID} from '../../constants'; +import {chain} from 'lodash'; export function sortConfig(routeConfigs: RouteConfig[]): void { // Sort the route config. This ensures that route with nested @@ -68,23 +70,31 @@ export async function loadPlugins({ // Currently plugins run lifecycle methods in parallel and are not order-dependent. // We could change this in future if there are plugins which need to // run in certain order or depend on others for data. - const pluginsLoadedContent = await Promise.all( + type ContentLoadedPlugin = {plugin: InitPlugin; content: unknown}; + const contentLoadedPlugins: ContentLoadedPlugin[] = await Promise.all( plugins.map(async (plugin) => { - if (!plugin.loadContent) { - return null; - } - - return plugin.loadContent(); + const content = plugin.loadContent ? await plugin.loadContent() : null; + return {plugin, content}; }), ); + const allContent: AllContent = chain(contentLoadedPlugins) + .groupBy((item) => item.plugin.name) + .mapValues((nameItems) => { + return chain(nameItems) + .groupBy((item) => item.plugin.options.id ?? DEFAULT_PLUGIN_ID) + .mapValues((idItems) => idItems[0].content) + .value(); + }) + .value(); + // 3. Plugin Lifecycle - contentLoaded. const pluginsRouteConfigs: RouteConfig[] = []; const globalData = {}; await Promise.all( - plugins.map(async (plugin, index) => { + contentLoadedPlugins.map(async ({plugin, content}) => { if (!plugin.contentLoaded) { return; } @@ -100,11 +110,11 @@ export async function loadPlugins({ const createData: PluginContentLoadedActions['createData'] = async ( name, - content, + data, ) => { const modulePath = path.join(dataDir, name); await fs.ensureDir(path.dirname(modulePath)); - await generate(dataDir, name, content); + await generate(dataDir, name, data); return modulePath; }; @@ -125,8 +135,9 @@ export async function loadPlugins({ }; await plugin.contentLoaded({ - content: pluginsLoadedContent[index], + content, actions, + allContent, }); }), ); diff --git a/packages/docusaurus/src/server/plugins/init.ts b/packages/docusaurus/src/server/plugins/init.ts index 09f0e08ef5..d7e9de0e42 100644 --- a/packages/docusaurus/src/server/plugins/init.ts +++ b/packages/docusaurus/src/server/plugins/init.ts @@ -15,7 +15,7 @@ import { PluginConfig, DocusaurusPluginVersionInformation, } from '@docusaurus/types'; -import {CONFIG_FILE_NAME} from '../../constants'; +import {CONFIG_FILE_NAME, DEFAULT_PLUGIN_ID} from '../../constants'; import {getPluginVersion} from '../versions'; import {ensureUniquePluginInstanceIds} from './pluginIds'; import { @@ -79,6 +79,13 @@ export default function initPlugins({ options: pluginOptions, }); pluginOptions = normalizedOptions; + } else { + // Important to ensure all plugins have an id + // as we don't go through the Joi schema that adds it + pluginOptions = { + ...pluginOptions, + id: pluginOptions.id ?? DEFAULT_PLUGIN_ID, + }; } // support both commonjs and ES modules diff --git a/tsconfig.json b/tsconfig.json index e0b11fc6d7..179d7409ff 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,10 +17,12 @@ /* Additional Checks */ "noUnusedLocals": true, - "noUnusedParameters": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, + /* Disabled on purpose (handled by ESLint, should not block compilation) */ + "noUnusedParameters": false, + /* Module Resolution Options */ "moduleResolution": "node", "allowSyntheticDefaultImports": true, diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 191b1cec43..16f2fa3100 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -156,6 +156,7 @@ module.exports = { [ '@docusaurus/preset-classic', { + debug: true, // force debug plugin usage docs: { // routeBasePath: '/', path: 'docs', diff --git a/yarn.lock b/yarn.lock index f8ca800f29..4cdfbdeae7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5440,6 +5440,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +base16@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70" + integrity sha1-4pf2DX7BAUp6lxo568ipjAtoHnA= + base64-js@^1.0.2: version "1.3.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" @@ -9642,7 +9647,14 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" -fbjs@^0.8.0: +fbemitter@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/fbemitter/-/fbemitter-2.1.1.tgz#523e14fdaf5248805bb02f62efc33be703f51865" + integrity sha1-Uj4U/a9SSIBbsC9i78M75wP1GGU= + dependencies: + fbjs "^0.8.4" + +fbjs@^0.8.0, fbjs@^0.8.4: version "0.8.17" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= @@ -9956,6 +9968,14 @@ flush-write-stream@^2.0.0: inherits "^2.0.3" readable-stream "^3.1.1" +flux@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/flux/-/flux-3.1.3.tgz#d23bed515a79a22d933ab53ab4ada19d05b2f08a" + integrity sha1-0jvtUVp5oi2TOrU6tK2hnQWy8Io= + dependencies: + fbemitter "^2.0.0" + fbjs "^0.8.0" + fn.name@1.x.x: version "1.1.0" resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" @@ -13541,6 +13561,11 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= +lodash.curry@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170" + integrity sha1-JI42By7ekGUB11lmIAqG2riyMXA= + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -13581,6 +13606,11 @@ lodash.flattendeep@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= +lodash.flow@^3.3.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a" + integrity sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o= + lodash.foreach@^4.3.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" @@ -17227,7 +17257,7 @@ prop-types-exact@^1.2.0: object.assign "^4.1.0" reflect.ownkeys "^0.2.0" -prop-types@^15.0.0, prop-types@^15.5.0, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.0.0, prop-types@^15.5.0, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -17355,6 +17385,11 @@ pupa@^2.0.1: dependencies: escape-goat "^2.0.0" +pure-color@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e" + integrity sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4= + q@^1.1.2, q@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -17524,6 +17559,16 @@ react-attr-converter@^0.3.1: resolved "https://registry.yarnpkg.com/react-attr-converter/-/react-attr-converter-0.3.1.tgz#4a2abf6d907b7ddae4d862dfec80e489ce41ad6e" integrity sha512-dSxo2Mn6Zx4HajeCeQNLefwEO4kNtV/0E682R1+ZTyFRPqxDa5zYb5qM/ocqw9Bxr/kFQO0IUiqdV7wdHw+Cdg== +react-base16-styling@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/react-base16-styling/-/react-base16-styling-0.6.0.tgz#ef2156d66cf4139695c8a167886cb69ea660792c" + integrity sha1-7yFW1mz0E5aVyKFniGy2nqZgeSw= + dependencies: + base16 "^1.0.0" + lodash.curry "^4.0.1" + lodash.flow "^3.3.0" + pure-color "^1.2.0" + react-dev-utils@^10.2.1: version "10.2.1" resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19" @@ -17620,6 +17665,16 @@ react-is@^16.12.0, react-is@^16.6.0, react-is@^16.6.3, react-is@^16.7.0, react-i resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-json-view@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.19.1.tgz#95d8e59e024f08a25e5dc8f076ae304eed97cf5c" + integrity sha512-u5e0XDLIs9Rj43vWkKvwL8G3JzvXSl6etuS5G42a8klMohZuYFQzSN6ri+/GiBptDqlrXPTdExJVU7x9rrlXhg== + dependencies: + flux "^3.1.3" + react-base16-styling "^0.6.0" + react-lifecycles-compat "^3.0.4" + react-textarea-autosize "^6.1.0" + react-lifecycles-compat@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" @@ -17722,6 +17777,13 @@ react-test-renderer@^16.0.0-0: react-is "^16.8.6" scheduler "^0.19.1" +react-textarea-autosize@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-6.1.0.tgz#df91387f8a8f22020b77e3833c09829d706a09a5" + integrity sha512-F6bI1dgib6fSvG8so1HuArPUv+iVEfPliuLWusLF+gAKz0FbB4jLrWUrTAeq1afnPT2c9toEZYUdz/y1uKMy4A== + dependencies: + prop-types "^15.6.0" + react-toggle@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/react-toggle/-/react-toggle-4.1.1.tgz#2317f67bf918ea3508a96b09dd383efd9da572af"