From f5f598a92173b509279438b7907bdf7ae03eaad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lorber?= Date: Fri, 28 Jan 2022 17:49:25 +0100 Subject: [PATCH] fix(core): configValidation should allow inline theme functions (#6496) --- .../configValidation.test.ts.snap | 69 +++++++++++++++++++ .../server/__tests__/configValidation.test.ts | 64 +++++++++++++++++ .../docusaurus/src/server/configValidation.ts | 66 +++++++++++------- 3 files changed, 175 insertions(+), 24 deletions(-) diff --git a/packages/docusaurus/src/server/__tests__/__snapshots__/configValidation.test.ts.snap b/packages/docusaurus/src/server/__tests__/__snapshots__/configValidation.test.ts.snap index 23e5755f7d..db52b1256e 100644 --- a/packages/docusaurus/src/server/__tests__/__snapshots__/configValidation.test.ts.snap +++ b/packages/docusaurus/src/server/__tests__/__snapshots__/configValidation.test.ts.snap @@ -108,7 +108,76 @@ exports[`normalizeConfig should throw error if scripts doesn't have src 1`] = ` " `; +exports[`normalizeConfig should throw error if themes is not a string and it's not an array #1 for the input of: [123] 1`] = ` +" => Bad Docusaurus theme value as path [themes,0]. +Example valid theme config: +{ + themes: [ + [\\"@docusaurus/theme-classic\\",options], + \\"./myTheme\\", + [\\"./myTheme\\",{someOption: 42}], + function myTheme() { }, + [function myTheme() { },options] + ], +}; + +" +`; + +exports[`normalizeConfig should throw error if themes is not an array of [string, object][] #1 for the input of: [[Array]] 1`] = ` +" => Bad Docusaurus theme value as path [themes,0]. +Example valid theme config: +{ + themes: [ + [\\"@docusaurus/theme-classic\\",options], + \\"./myTheme\\", + [\\"./myTheme\\",{someOption: 42}], + function myTheme() { }, + [function myTheme() { },options] + ], +}; + +" +`; + +exports[`normalizeConfig should throw error if themes is not an array of [string, object][] #2 for the input of: [[Array]] 1`] = ` +" => Bad Docusaurus theme value as path [themes,0]. +Example valid theme config: +{ + themes: [ + [\\"@docusaurus/theme-classic\\",options], + \\"./myTheme\\", + [\\"./myTheme\\",{someOption: 42}], + function myTheme() { }, + [function myTheme() { },options] + ], +}; + +" +`; + +exports[`normalizeConfig should throw error if themes is not an array of [string, object][] #3 for the input of: [[Array]] 1`] = ` +" => Bad Docusaurus theme value as path [themes,0]. +Example valid theme config: +{ + themes: [ + [\\"@docusaurus/theme-classic\\",options], + \\"./myTheme\\", + [\\"./myTheme\\",{someOption: 42}], + function myTheme() { }, + [function myTheme() { },options] + ], +}; + +" +`; + exports[`normalizeConfig should throw error if themes is not array 1`] = ` "\\"themes\\" must be an array " `; + +exports[`normalizeConfig should throw error if themes is not array for the input of: {} 1`] = ` +"\\"themes\\" must be an array +" +`; diff --git a/packages/docusaurus/src/server/__tests__/configValidation.test.ts b/packages/docusaurus/src/server/__tests__/configValidation.test.ts index 75b2a9f9be..f9dedbab8a 100644 --- a/packages/docusaurus/src/server/__tests__/configValidation.test.ts +++ b/packages/docusaurus/src/server/__tests__/configValidation.test.ts @@ -117,6 +117,32 @@ describe('normalizeConfig', () => { }).toThrowErrorMatchingSnapshot(); }); + test.each([ + ['should throw error if themes is not array', {}], + [ + "should throw error if themes is not a string and it's not an array #1", + [123], + ], + [ + 'should throw error if themes is not an array of [string, object][] #1', + [['example/path', 'wrong parameter here']], + ], + [ + 'should throw error if themes is not an array of [string, object][] #2', + [[{}, 'example/path']], + ], + [ + 'should throw error if themes is not an array of [string, object][] #3', + [[{}, {}]], + ], + ])(`%s for the input of: %p`, (_message, themes) => { + expect(() => { + normalizeConfig({ + themes, + }); + }).toThrowErrorMatchingSnapshot(); + }); + test.each([ ['should accept [string] for plugins', ['plain/string']], [ @@ -155,6 +181,44 @@ describe('normalizeConfig', () => { }).not.toThrowError(); }); + test.each([ + ['should accept [string] for themes', ['plain/string']], + [ + 'should accept string[] for themes', + ['plain/string', 'another/plain/string/path'], + ], + [ + 'should accept [string, object] for themes', + [['plain/string', {it: 'should work'}]], + ], + [ + 'should accept [string, object][] for themes', + [ + ['plain/string', {it: 'should work'}], + ['this/should/work', {too: 'yes'}], + ], + ], + [ + 'should accept ([string, object]|string)[] for themes', + [ + 'plain/string', + ['plain', {it: 'should work'}], + ['this/should/work', {too: 'yes'}], + ], + ], + ['should accept function for theme', [function (_context, _options) {}]], + [ + 'should accept [function, object] for theme', + [[function (_context, _options) {}, {it: 'should work'}]], + ], + ])(`%s for the input of: %p`, (_message, themes) => { + expect(() => { + normalizeConfig({ + themes, + }); + }).not.toThrowError(); + }); + test('should throw error if themes is not array', () => { expect(() => { normalizeConfig({ diff --git a/packages/docusaurus/src/server/configValidation.ts b/packages/docusaurus/src/server/configValidation.ts index 420315ff0d..e5dad4adaf 100644 --- a/packages/docusaurus/src/server/configValidation.ts +++ b/packages/docusaurus/src/server/configValidation.ts @@ -55,21 +55,33 @@ export const DEFAULT_CONFIG: Pick< staticDirectories: [STATIC_DIR_NAME], }; -const PluginSchema = Joi.alternatives() - .try( - Joi.function(), - Joi.array().ordered(Joi.function().required(), Joi.object().required()), - Joi.string(), - Joi.array() - .ordered(Joi.string().required(), Joi.object().required()) - .length(2), - Joi.bool().equal(false), // In case of conditional adding of plugins. - ) - // @ts-expect-error: bad lib def, doesn't recognize an array of reports - .error((errors) => { - errors.forEach((error) => { - error.message = ` => Bad Docusaurus plugin value as path [${error.path}]. -Example valid plugin config: +function createPluginSchema(theme: boolean = false) { + return ( + Joi.alternatives() + .try( + Joi.function(), + Joi.array().ordered(Joi.function().required(), Joi.object().required()), + Joi.string(), + Joi.array() + .ordered(Joi.string().required(), Joi.object().required()) + .length(2), + Joi.bool().equal(false), // In case of conditional adding of plugins. + ) + // @ts-expect-error: bad lib def, doesn't recognize an array of reports + .error((errors) => { + errors.forEach((error) => { + const validConfigExample = theme + ? `Example valid theme config: +{ + themes: [ + ["@docusaurus/theme-classic",options], + "./myTheme", + ["./myTheme",{someOption: 42}], + function myTheme() { }, + [function myTheme() { },options] + ], +};` + : `Example valid plugin config: { plugins: [ ["@docusaurus/plugin-content-docs",options], @@ -78,16 +90,22 @@ Example valid plugin config: function myPlugin() { }, [function myPlugin() { },options] ], -}; -`; - }); - return errors; - }); +};`; -const ThemeSchema = Joi.alternatives().try( - Joi.string(), - Joi.array().items(Joi.string().required(), Joi.object().required()).length(2), -); + error.message = ` => Bad Docusaurus ${ + theme ? 'theme' : 'plugin' + } value as path [${error.path}]. +${validConfigExample} +`; + }); + return errors; + }) + ); +} + +const PluginSchema = createPluginSchema(false); + +const ThemeSchema = createPluginSchema(true); const PresetSchema = Joi.alternatives().try( Joi.string(),