diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index 7d24b70a47..7a5b9ad5ec 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -27,9 +27,15 @@ export type PluginConfig = | string | [string, PluginOptions] | [PluginModule, PluginOptions] - | PluginModule; + | PluginModule + | false + | null; -export type PresetConfig = string | [string, {[key: string]: unknown}]; +export type PresetConfig = + | string + | [string, {[key: string]: unknown}] + | false + | null; export type ThemeConfig = { [key: string]: unknown; diff --git a/packages/docusaurus/src/server/__tests__/configValidation.test.ts b/packages/docusaurus/src/server/__tests__/configValidation.test.ts index b6d606b417..1f8838efa7 100644 --- a/packages/docusaurus/src/server/__tests__/configValidation.test.ts +++ b/packages/docusaurus/src/server/__tests__/configValidation.test.ts @@ -173,6 +173,7 @@ describe('normalizeConfig', () => { 'should accept [function, object] for plugin', [[() => {}, {it: 'should work'}]], ], + ['should accept false/null for plugin', [false, null, 'classic']], ])(`%s for the input of: %p`, (_message, plugins) => { expect(() => { normalizeConfig({ @@ -211,6 +212,7 @@ describe('normalizeConfig', () => { 'should accept [function, object] for theme', [[function theme() {}, {it: 'should work'}]], ], + ['should accept false/null for themes', [false, null, 'classic']], ])(`%s for the input of: %p`, (_message, themes) => { expect(() => { normalizeConfig({ @@ -254,6 +256,14 @@ describe('normalizeConfig', () => { `); }); + it('accepts presets as false / null', () => { + expect(() => { + normalizeConfig({ + presets: [false, null, 'classic'], + }); + }).not.toThrow(); + }); + it("throws error if scripts doesn't have src", () => { expect(() => { normalizeConfig({ diff --git a/packages/docusaurus/src/server/configValidation.ts b/packages/docusaurus/src/server/configValidation.ts index a25659ae89..74f3836b0e 100644 --- a/packages/docusaurus/src/server/configValidation.ts +++ b/packages/docusaurus/src/server/configValidation.ts @@ -71,7 +71,7 @@ function createPluginSchema(theme: boolean) { Joi.array() .ordered(Joi.string().required(), Joi.object().required()) .length(2), - Joi.bool().equal(false), // In case of conditional adding of plugins. + Joi.any().valid(false, null), ) // @ts-expect-error: bad lib def, doesn't recognize an array of reports .error((errors) => { @@ -119,6 +119,7 @@ const PresetSchema = Joi.alternatives() Joi.array() .items(Joi.string().required(), Joi.object().required()) .length(2), + Joi.any().valid(false, null), ) .messages({ 'alternatives.types': `{#label} does not look like a valid preset config. A preset config entry should be one of: diff --git a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/presets/preset-mixed.js b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/presets/preset-mixed.js index fdd55264f6..bbe10eaa44 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/presets/preset-mixed.js +++ b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/presets/preset-mixed.js @@ -7,7 +7,7 @@ module.exports = function preset(context, opts = {}) { return { - themes: [['@docusaurus/theme-classic', opts.test]], - plugins: [['@docusaurus/plugin-test', opts.test]], + themes: [['@docusaurus/theme-classic', opts.test], null], + plugins: [['@docusaurus/plugin-test', opts.test], false], }; }; diff --git a/packages/docusaurus/src/server/plugins/__tests__/__snapshots__/presets.test.ts.snap b/packages/docusaurus/src/server/plugins/__tests__/__snapshots__/presets.test.ts.snap index 84f8e1be4b..d5da620ec5 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/__snapshots__/presets.test.ts.snap +++ b/packages/docusaurus/src/server/plugins/__tests__/__snapshots__/presets.test.ts.snap @@ -107,6 +107,7 @@ exports[`loadPresets mixed form with themes 1`] = ` "@docusaurus/plugin-test", undefined, ], + false, ], "themes": [ [ @@ -121,6 +122,7 @@ exports[`loadPresets mixed form with themes 1`] = ` "@docusaurus/theme-classic", undefined, ], + null, ], } `; diff --git a/packages/docusaurus/src/server/plugins/configs.ts b/packages/docusaurus/src/server/plugins/configs.ts index 2662ddc69b..5c4b7711c0 100644 --- a/packages/docusaurus/src/server/plugins/configs.ts +++ b/packages/docusaurus/src/server/plugins/configs.ts @@ -17,7 +17,7 @@ import type { } from '@docusaurus/types'; async function normalizePluginConfig( - pluginConfig: PluginConfig, + pluginConfig: Exclude, configPath: string, pluginRequire: NodeRequire, ): Promise { @@ -120,7 +120,7 @@ export async function loadPluginConfigs( // Site config should be the highest priority. ...standalonePlugins, ...standaloneThemes, - ]; + ].filter((x: T | null | false): x is T => Boolean(x)); return Promise.all( pluginConfigs.map((pluginConfig) => normalizePluginConfig( diff --git a/packages/docusaurus/src/server/plugins/presets.ts b/packages/docusaurus/src/server/plugins/presets.ts index 877150cc67..27788b747d 100644 --- a/packages/docusaurus/src/server/plugins/presets.ts +++ b/packages/docusaurus/src/server/plugins/presets.ts @@ -33,6 +33,9 @@ export async function loadPresets( presets.forEach((presetItem) => { let presetModuleImport: string; let presetOptions = {}; + if (!presetItem) { + return; + } if (typeof presetItem === 'string') { presetModuleImport = presetItem; } else { @@ -53,10 +56,10 @@ export async function loadPresets( ); if (preset.plugins) { - plugins.push(...preset.plugins.filter(Boolean)); + plugins.push(...preset.plugins); } if (preset.themes) { - themes.push(...preset.themes.filter(Boolean)); + themes.push(...preset.themes); } });