@docusaurus/core 2.0.0-beta.18 → 2.0.0-beta.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/beforeCli.mjs +12 -7
- package/bin/docusaurus.mjs +21 -72
- package/lib/client/.eslintrc.js +2 -3
- package/lib/client/App.d.ts +1 -1
- package/lib/client/App.js +9 -5
- package/lib/client/{baseUrlIssueBanner/BaseUrlIssueBanner.d.ts → BaseUrlIssueBanner/index.d.ts} +10 -5
- package/lib/client/{baseUrlIssueBanner/BaseUrlIssueBanner.js → BaseUrlIssueBanner/index.js} +14 -9
- package/lib/client/{baseUrlIssueBanner → BaseUrlIssueBanner}/styles.module.css +0 -0
- package/lib/client/ClientLifecyclesDispatcher.d.ts +16 -0
- package/lib/client/ClientLifecyclesDispatcher.js +34 -0
- package/lib/client/LinksCollector.js +1 -2
- package/lib/client/PendingNavigation.d.ts +8 -17
- package/lib/client/PendingNavigation.js +39 -70
- package/lib/client/clientEntry.js +1 -2
- package/lib/client/docusaurus.d.ts +5 -5
- package/lib/client/docusaurus.js +25 -29
- package/lib/client/exports/BrowserOnly.d.ts +3 -4
- package/lib/client/exports/BrowserOnly.js +1 -1
- package/lib/client/exports/ComponentCreator.js +51 -46
- package/lib/client/exports/ErrorBoundary.d.ts +2 -2
- package/lib/client/exports/Interpolate.js +16 -39
- package/lib/client/exports/Link.d.ts +3 -15
- package/lib/client/exports/Link.js +21 -26
- package/lib/client/exports/useBaseUrl.js +3 -9
- package/lib/client/exports/useGlobalData.d.ts +3 -3
- package/lib/client/exports/useGlobalData.js +5 -5
- package/lib/client/flat.d.ts +10 -2
- package/lib/client/flat.js +11 -3
- package/lib/client/normalizeLocation.js +14 -5
- package/lib/client/prefetch.js +7 -25
- package/lib/client/preload.d.ts +1 -3
- package/lib/client/preload.js +2 -2
- package/lib/client/routeContext.js +1 -1
- package/lib/client/serverEntry.js +12 -11
- package/lib/client/theme-fallback/Error/index.js +2 -0
- package/lib/client/theme-fallback/Loading/index.js +2 -0
- package/lib/client/theme-fallback/NotFound/index.js +2 -0
- package/lib/commands/build.d.ts +6 -2
- package/lib/commands/build.js +35 -15
- package/lib/commands/clear.d.ts +1 -1
- package/lib/commands/clear.js +3 -2
- package/lib/commands/deploy.d.ts +5 -2
- package/lib/commands/deploy.js +12 -9
- package/lib/commands/external.d.ts +1 -1
- package/lib/commands/external.js +5 -6
- package/lib/commands/serve.d.ts +7 -2
- package/lib/commands/serve.js +12 -12
- package/lib/commands/start.d.ts +8 -2
- package/lib/commands/start.js +14 -9
- package/lib/commands/swizzle/actions.d.ts +2 -2
- package/lib/commands/swizzle/actions.js +5 -4
- package/lib/commands/swizzle/common.d.ts +3 -3
- package/lib/commands/swizzle/components.js +41 -3
- package/lib/commands/swizzle/config.js +14 -11
- package/lib/commands/swizzle/context.js +6 -10
- package/lib/commands/swizzle/index.d.ts +2 -2
- package/lib/commands/swizzle/index.js +4 -3
- package/lib/commands/writeHeadingIds.d.ts +1 -1
- package/lib/commands/writeHeadingIds.js +5 -8
- package/lib/commands/writeTranslations.d.ts +3 -4
- package/lib/commands/writeTranslations.js +7 -9
- package/lib/index.d.ts +9 -10
- package/lib/index.js +18 -19
- package/lib/server/brokenLinks.js +1 -2
- package/lib/server/{client-modules/index.d.ts → clientModules.d.ts} +5 -1
- package/lib/server/{client-modules/index.js → clientModules.js} +6 -1
- package/lib/server/config.d.ts +5 -2
- package/lib/server/config.js +11 -6
- package/lib/server/configValidation.js +6 -5
- package/lib/server/getHostPort.d.ts +14 -0
- package/lib/{choosePort.js → server/getHostPort.js} +21 -35
- package/lib/server/htmlTags.d.ts +12 -0
- package/lib/server/htmlTags.js +62 -0
- package/lib/server/i18n.d.ts +2 -11
- package/lib/server/i18n.js +4 -19
- package/lib/server/index.d.ts +28 -13
- package/lib/server/index.js +42 -210
- package/lib/server/plugins/configs.d.ts +51 -0
- package/lib/server/plugins/configs.js +101 -0
- package/lib/server/plugins/index.d.ts +8 -7
- package/lib/server/plugins/index.js +59 -134
- package/lib/server/plugins/init.d.ts +6 -19
- package/lib/server/plugins/init.js +16 -68
- package/lib/server/{moduleShorthand.d.ts → plugins/moduleShorthand.d.ts} +0 -0
- package/lib/server/{moduleShorthand.js → plugins/moduleShorthand.js} +0 -0
- package/lib/server/plugins/pluginIds.d.ts +4 -0
- package/lib/server/plugins/pluginIds.js +4 -2
- package/lib/server/plugins/presets.d.ts +12 -0
- package/lib/server/{presets/index.js → plugins/presets.js} +14 -6
- package/lib/server/plugins/{applyRouteTrailingSlash.d.ts → routeConfig.d.ts} +3 -1
- package/lib/server/plugins/routeConfig.js +54 -0
- package/lib/server/plugins/synthetic.d.ts +20 -0
- package/lib/server/plugins/synthetic.js +112 -0
- package/lib/server/routes.d.ts +42 -8
- package/lib/server/routes.js +150 -92
- package/lib/server/{versions/index.d.ts → siteMetadata.d.ts} +5 -2
- package/lib/server/{versions/index.js → siteMetadata.js} +36 -3
- package/lib/server/translations/translations.d.ts +5 -13
- package/lib/server/translations/translations.js +5 -8
- package/lib/server/translations/translationsExtractor.d.ts +2 -4
- package/lib/webpack/aliases/index.d.ts +34 -0
- package/lib/webpack/aliases/index.js +106 -0
- package/lib/webpack/base.d.ts +0 -3
- package/lib/webpack/base.js +8 -25
- package/lib/webpack/client.js +1 -1
- package/lib/webpack/plugins/CleanWebpackPlugin.d.ts +2 -2
- package/lib/webpack/plugins/WaitPlugin.d.ts +2 -2
- package/lib/webpack/server.d.ts +2 -2
- package/lib/webpack/server.js +5 -3
- package/lib/webpack/utils.d.ts +3 -3
- package/lib/webpack/utils.js +3 -3
- package/package.json +33 -36
- package/lib/choosePort.d.ts +0 -11
- package/lib/client/client-lifecycles-dispatcher.d.ts +0 -9
- package/lib/client/client-lifecycles-dispatcher.js +0 -23
- package/lib/client/nprogress.css +0 -36
- package/lib/commands/commandUtils.d.ts +0 -9
- package/lib/commands/commandUtils.js +0 -21
- package/lib/server/duplicateRoutes.d.ts +0 -8
- package/lib/server/duplicateRoutes.js +0 -42
- package/lib/server/html-tags/htmlTags.d.ts +0 -7
- package/lib/server/html-tags/htmlTags.js +0 -38
- package/lib/server/html-tags/index.d.ts +0 -8
- package/lib/server/html-tags/index.js +0 -42
- package/lib/server/plugins/applyRouteTrailingSlash.js +0 -19
- package/lib/server/presets/index.d.ts +0 -11
- package/lib/server/themes/alias.d.ts +0 -9
- package/lib/server/themes/alias.js +0 -50
- package/lib/server/themes/index.d.ts +0 -12
- package/lib/server/themes/index.js +0 -47
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import type { LoadContext, PluginModule, PluginOptions } from '@docusaurus/types';
|
|
8
|
+
declare type ImportedPluginModule = PluginModule & {
|
|
9
|
+
default?: PluginModule;
|
|
10
|
+
};
|
|
11
|
+
export declare type NormalizedPluginConfig = {
|
|
12
|
+
/**
|
|
13
|
+
* The default export of the plugin module, or alternatively, what's provided
|
|
14
|
+
* in the config file as inline plugins. Note that if a file is like:
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* export default plugin() {...}
|
|
18
|
+
* export validateOptions() {...}
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Then the static methods may not exist here. `pluginModule.module` will
|
|
22
|
+
* always take priority.
|
|
23
|
+
*/
|
|
24
|
+
plugin: PluginModule;
|
|
25
|
+
/** Options as they are provided in the config, not validated yet. */
|
|
26
|
+
options: PluginOptions;
|
|
27
|
+
/** Only available when a string is provided in config. */
|
|
28
|
+
pluginModule?: {
|
|
29
|
+
/**
|
|
30
|
+
* Raw module name as provided in the config. Shorthands have been resolved,
|
|
31
|
+
* so at least it's directly `require.resolve`able.
|
|
32
|
+
*/
|
|
33
|
+
path: string;
|
|
34
|
+
/** Whatever gets imported with `require`. */
|
|
35
|
+
module: ImportedPluginModule;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Different from `pluginModule.path`, this one is always an absolute path,
|
|
39
|
+
* used to resolve relative paths returned from lifecycles. If it's an inline
|
|
40
|
+
* plugin, it will be path to the config file.
|
|
41
|
+
*/
|
|
42
|
+
entryPath: string;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Reads the site config's `presets`, `themes`, and `plugins`, imports them, and
|
|
46
|
+
* normalizes the return value. Plugin configs are ordered, mostly for theme
|
|
47
|
+
* alias shadowing. Site themes have the highest priority, and preset plugins
|
|
48
|
+
* are the lowest.
|
|
49
|
+
*/
|
|
50
|
+
export declare function loadPluginConfigs(context: LoadContext): Promise<NormalizedPluginConfig[]>;
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.loadPluginConfigs = void 0;
|
|
10
|
+
const tslib_1 = require("tslib");
|
|
11
|
+
const module_1 = require("module");
|
|
12
|
+
const import_fresh_1 = tslib_1.__importDefault(require("import-fresh"));
|
|
13
|
+
const presets_1 = require("./presets");
|
|
14
|
+
const moduleShorthand_1 = require("./moduleShorthand");
|
|
15
|
+
async function normalizePluginConfig(pluginConfig, configPath, pluginRequire) {
|
|
16
|
+
// plugins: ["./plugin"]
|
|
17
|
+
if (typeof pluginConfig === 'string') {
|
|
18
|
+
const pluginModuleImport = pluginConfig;
|
|
19
|
+
const pluginPath = pluginRequire.resolve(pluginModuleImport);
|
|
20
|
+
const pluginModule = (0, import_fresh_1.default)(pluginPath);
|
|
21
|
+
return {
|
|
22
|
+
plugin: pluginModule?.default ?? pluginModule,
|
|
23
|
+
options: {},
|
|
24
|
+
pluginModule: {
|
|
25
|
+
path: pluginModuleImport,
|
|
26
|
+
module: pluginModule,
|
|
27
|
+
},
|
|
28
|
+
entryPath: pluginPath,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// plugins: [() => {...}]
|
|
32
|
+
if (typeof pluginConfig === 'function') {
|
|
33
|
+
return {
|
|
34
|
+
plugin: pluginConfig,
|
|
35
|
+
options: {},
|
|
36
|
+
entryPath: configPath,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
// plugins: [
|
|
40
|
+
// ["./plugin",options],
|
|
41
|
+
// ]
|
|
42
|
+
if (typeof pluginConfig[0] === 'string') {
|
|
43
|
+
const pluginModuleImport = pluginConfig[0];
|
|
44
|
+
const pluginPath = pluginRequire.resolve(pluginModuleImport);
|
|
45
|
+
const pluginModule = (0, import_fresh_1.default)(pluginPath);
|
|
46
|
+
return {
|
|
47
|
+
plugin: pluginModule?.default ?? pluginModule,
|
|
48
|
+
options: pluginConfig[1],
|
|
49
|
+
pluginModule: {
|
|
50
|
+
path: pluginModuleImport,
|
|
51
|
+
module: pluginModule,
|
|
52
|
+
},
|
|
53
|
+
entryPath: pluginPath,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// plugins: [
|
|
57
|
+
// [() => {...}, options],
|
|
58
|
+
// ]
|
|
59
|
+
return {
|
|
60
|
+
plugin: pluginConfig[0],
|
|
61
|
+
options: pluginConfig[1],
|
|
62
|
+
entryPath: configPath,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Reads the site config's `presets`, `themes`, and `plugins`, imports them, and
|
|
67
|
+
* normalizes the return value. Plugin configs are ordered, mostly for theme
|
|
68
|
+
* alias shadowing. Site themes have the highest priority, and preset plugins
|
|
69
|
+
* are the lowest.
|
|
70
|
+
*/
|
|
71
|
+
async function loadPluginConfigs(context) {
|
|
72
|
+
const preset = await (0, presets_1.loadPresets)(context);
|
|
73
|
+
const { siteConfig, siteConfigPath } = context;
|
|
74
|
+
const pluginRequire = (0, module_1.createRequire)(siteConfigPath);
|
|
75
|
+
function normalizeShorthand(pluginConfig, pluginType) {
|
|
76
|
+
if (typeof pluginConfig === 'string') {
|
|
77
|
+
return (0, moduleShorthand_1.resolveModuleName)(pluginConfig, pluginRequire, pluginType);
|
|
78
|
+
}
|
|
79
|
+
else if (Array.isArray(pluginConfig) &&
|
|
80
|
+
typeof pluginConfig[0] === 'string') {
|
|
81
|
+
return [
|
|
82
|
+
(0, moduleShorthand_1.resolveModuleName)(pluginConfig[0], pluginRequire, pluginType),
|
|
83
|
+
pluginConfig[1] ?? {},
|
|
84
|
+
];
|
|
85
|
+
}
|
|
86
|
+
return pluginConfig;
|
|
87
|
+
}
|
|
88
|
+
preset.plugins = preset.plugins.map((plugin) => normalizeShorthand(plugin, 'plugin'));
|
|
89
|
+
preset.themes = preset.themes.map((theme) => normalizeShorthand(theme, 'theme'));
|
|
90
|
+
const standalonePlugins = siteConfig.plugins.map((plugin) => normalizeShorthand(plugin, 'plugin'));
|
|
91
|
+
const standaloneThemes = siteConfig.themes.map((theme) => normalizeShorthand(theme, 'theme'));
|
|
92
|
+
const pluginConfigs = [
|
|
93
|
+
...preset.plugins,
|
|
94
|
+
...preset.themes,
|
|
95
|
+
// Site config should be the highest priority.
|
|
96
|
+
...standalonePlugins,
|
|
97
|
+
...standaloneThemes,
|
|
98
|
+
].filter((x) => Boolean(x));
|
|
99
|
+
return Promise.all(pluginConfigs.map((pluginConfig) => normalizePluginConfig(pluginConfig, context.siteConfigPath, pluginRequire)));
|
|
100
|
+
}
|
|
101
|
+
exports.loadPluginConfigs = loadPluginConfigs;
|
|
@@ -4,14 +4,15 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import type { LoadContext,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
import type { LoadContext, RouteConfig, GlobalData, LoadedPlugin } from '@docusaurus/types';
|
|
8
|
+
/**
|
|
9
|
+
* Initializes the plugins, runs `loadContent`, `translateContent`,
|
|
10
|
+
* `contentLoaded`, and `translateThemeConfig`. Because `contentLoaded` is
|
|
11
|
+
* side-effect-ful (it generates temp files), so is this function. This function
|
|
12
|
+
* would also mutate `context.siteConfig.themeConfig` to translate it.
|
|
13
|
+
*/
|
|
14
|
+
export declare function loadPlugins(context: LoadContext): Promise<{
|
|
13
15
|
plugins: LoadedPlugin[];
|
|
14
16
|
pluginsRouteConfigs: RouteConfig[];
|
|
15
17
|
globalData: GlobalData;
|
|
16
|
-
themeConfigTranslated: ThemeConfig;
|
|
17
18
|
}>;
|
|
@@ -6,77 +6,50 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.loadPlugins =
|
|
9
|
+
exports.loadPlugins = void 0;
|
|
10
10
|
const tslib_1 = require("tslib");
|
|
11
11
|
const utils_1 = require("@docusaurus/utils");
|
|
12
|
-
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
13
12
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
14
|
-
const init_1 =
|
|
15
|
-
const
|
|
13
|
+
const init_1 = require("./init");
|
|
14
|
+
const synthetic_1 = require("./synthetic");
|
|
16
15
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
17
16
|
const translations_1 = require("../translations/translations");
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
if (a.path !== baseUrl && b.path === baseUrl) {
|
|
28
|
-
return -1;
|
|
29
|
-
}
|
|
30
|
-
if (a.routes && !b.routes) {
|
|
31
|
-
return 1;
|
|
32
|
-
}
|
|
33
|
-
if (!a.routes && b.routes) {
|
|
34
|
-
return -1;
|
|
35
|
-
}
|
|
36
|
-
// Higher priority get placed first.
|
|
37
|
-
if (a.priority || b.priority) {
|
|
38
|
-
const priorityA = a.priority || 0;
|
|
39
|
-
const priorityB = b.priority || 0;
|
|
40
|
-
const score = priorityB - priorityA;
|
|
41
|
-
if (score !== 0) {
|
|
42
|
-
return score;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return a.path.localeCompare(b.path);
|
|
46
|
-
});
|
|
47
|
-
routeConfigs.forEach((routeConfig) => {
|
|
48
|
-
routeConfig.routes?.sort((a, b) => a.path.localeCompare(b.path));
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
exports.sortConfig = sortConfig;
|
|
52
|
-
async function loadPlugins({ pluginConfigs, context, }) {
|
|
17
|
+
const routeConfig_1 = require("./routeConfig");
|
|
18
|
+
/**
|
|
19
|
+
* Initializes the plugins, runs `loadContent`, `translateContent`,
|
|
20
|
+
* `contentLoaded`, and `translateThemeConfig`. Because `contentLoaded` is
|
|
21
|
+
* side-effect-ful (it generates temp files), so is this function. This function
|
|
22
|
+
* would also mutate `context.siteConfig.themeConfig` to translate it.
|
|
23
|
+
*/
|
|
24
|
+
async function loadPlugins(context) {
|
|
53
25
|
// 1. Plugin Lifecycle - Initialization/Constructor.
|
|
54
|
-
const plugins = await (0, init_1.
|
|
55
|
-
|
|
56
|
-
context,
|
|
57
|
-
});
|
|
26
|
+
const plugins = await (0, init_1.initPlugins)(context);
|
|
27
|
+
plugins.push((0, synthetic_1.createBootstrapPlugin)(context), (0, synthetic_1.createMDXFallbackPlugin)(context));
|
|
58
28
|
// 2. Plugin Lifecycle - loadContent.
|
|
59
29
|
// Currently plugins run lifecycle methods in parallel and are not
|
|
60
30
|
// order-dependent. We could change this in future if there are plugins which
|
|
61
31
|
// need to run in certain order or depend on others for data.
|
|
32
|
+
// This would also translate theme config and content upfront, given the
|
|
33
|
+
// translation files that the plugin declares.
|
|
62
34
|
const loadedPlugins = await Promise.all(plugins.map(async (plugin) => {
|
|
63
35
|
const content = await plugin.loadContent?.();
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const contentLoadedTranslatedPlugins = await Promise.all(loadedPlugins.map(async (contentLoadedPlugin) => {
|
|
67
|
-
const translationFiles = (await contentLoadedPlugin?.getTranslationFiles?.({
|
|
68
|
-
content: contentLoadedPlugin.content,
|
|
69
|
-
})) ?? [];
|
|
70
|
-
const localizedTranslationFiles = await Promise.all(translationFiles.map((translationFile) => (0, translations_1.localizePluginTranslationFile)({
|
|
36
|
+
const rawTranslationFiles = (await plugin?.getTranslationFiles?.({ content })) ?? [];
|
|
37
|
+
const translationFiles = await Promise.all(rawTranslationFiles.map((translationFile) => (0, translations_1.localizePluginTranslationFile)({
|
|
71
38
|
locale: context.i18n.currentLocale,
|
|
72
39
|
siteDir: context.siteDir,
|
|
73
40
|
translationFile,
|
|
74
|
-
plugin
|
|
41
|
+
plugin,
|
|
75
42
|
})));
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
43
|
+
const translatedContent = plugin.translateContent?.({ content, translationFiles }) ?? content;
|
|
44
|
+
const translatedThemeConfigSlice = plugin.translateThemeConfig?.({
|
|
45
|
+
themeConfig: context.siteConfig.themeConfig,
|
|
46
|
+
translationFiles,
|
|
47
|
+
});
|
|
48
|
+
// Side-effect to merge theme config translations. A plugin should only
|
|
49
|
+
// translate its own slice of theme config and should make no assumptions
|
|
50
|
+
// about other plugins' keys, so this is safe to run in parallel.
|
|
51
|
+
Object.assign(context.siteConfig.themeConfig, translatedThemeConfigSlice);
|
|
52
|
+
return { ...plugin, content: translatedContent };
|
|
80
53
|
}));
|
|
81
54
|
const allContent = lodash_1.default.chain(loadedPlugins)
|
|
82
55
|
.groupBy((item) => item.name)
|
|
@@ -88,95 +61,47 @@ async function loadPlugins({ pluginConfigs, context, }) {
|
|
|
88
61
|
// 3. Plugin Lifecycle - contentLoaded.
|
|
89
62
|
const pluginsRouteConfigs = [];
|
|
90
63
|
const globalData = {};
|
|
91
|
-
await Promise.all(
|
|
64
|
+
await Promise.all(loadedPlugins.map(async ({ content, ...plugin }) => {
|
|
92
65
|
if (!plugin.contentLoaded) {
|
|
93
66
|
return;
|
|
94
67
|
}
|
|
95
68
|
const pluginId = plugin.options.id;
|
|
96
|
-
//
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
const createData = async (name, data) => {
|
|
100
|
-
const modulePath = path_1.default.join(dataDir, name);
|
|
101
|
-
await fs_extra_1.default.ensureDir(path_1.default.dirname(modulePath));
|
|
102
|
-
await (0, utils_1.generate)(dataDir, name, data);
|
|
103
|
-
return modulePath;
|
|
104
|
-
};
|
|
105
|
-
// TODO this would be better to do all that in the codegen phase
|
|
106
|
-
// TODO handle context for nested routes
|
|
69
|
+
// Plugins data files are namespaced by pluginName/pluginId
|
|
70
|
+
const dataDir = path_1.default.join(context.generatedFilesDir, plugin.name, pluginId);
|
|
71
|
+
const pluginRouteContextModulePath = path_1.default.join(dataDir, `${(0, utils_1.docuHash)('pluginRouteContextModule')}.json`);
|
|
107
72
|
const pluginRouteContext = {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
};
|
|
111
|
-
const pluginRouteContextModulePath = await createData(`${(0, utils_1.docuHash)('pluginRouteContextModule')}.json`, JSON.stringify(pluginRouteContext, null, 2));
|
|
112
|
-
const addRoute = (initialRouteConfig) => {
|
|
113
|
-
// Trailing slash behavior is handled in a generic way for all plugins
|
|
114
|
-
const finalRouteConfig = (0, applyRouteTrailingSlash_1.default)(initialRouteConfig, {
|
|
115
|
-
trailingSlash: context.siteConfig.trailingSlash,
|
|
116
|
-
baseUrl: context.siteConfig.baseUrl,
|
|
117
|
-
});
|
|
118
|
-
pluginsRouteConfigs.push({
|
|
119
|
-
...finalRouteConfig,
|
|
120
|
-
modules: {
|
|
121
|
-
...finalRouteConfig.modules,
|
|
122
|
-
__routeContextModule: pluginRouteContextModulePath,
|
|
123
|
-
},
|
|
124
|
-
});
|
|
125
|
-
};
|
|
126
|
-
// the plugins global data are namespaced to avoid data conflicts:
|
|
127
|
-
// - by plugin name
|
|
128
|
-
// - by plugin id (allow using multiple instances of the same plugin)
|
|
129
|
-
const setGlobalData = (data) => {
|
|
130
|
-
globalData[plugin.name] = globalData[plugin.name] ?? {};
|
|
131
|
-
globalData[plugin.name][pluginId] = data;
|
|
73
|
+
name: plugin.name,
|
|
74
|
+
id: pluginId,
|
|
132
75
|
};
|
|
76
|
+
await (0, utils_1.generate)('/', pluginRouteContextModulePath, JSON.stringify(pluginRouteContext, null, 2));
|
|
133
77
|
const actions = {
|
|
134
|
-
addRoute
|
|
135
|
-
|
|
136
|
-
|
|
78
|
+
addRoute(initialRouteConfig) {
|
|
79
|
+
// Trailing slash behavior is handled generically for all plugins
|
|
80
|
+
const finalRouteConfig = (0, routeConfig_1.applyRouteTrailingSlash)(initialRouteConfig, context.siteConfig);
|
|
81
|
+
pluginsRouteConfigs.push({
|
|
82
|
+
...finalRouteConfig,
|
|
83
|
+
context: {
|
|
84
|
+
...(finalRouteConfig.context && { data: finalRouteConfig.context }),
|
|
85
|
+
plugin: pluginRouteContextModulePath,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
async createData(name, data) {
|
|
90
|
+
const modulePath = path_1.default.join(dataDir, name);
|
|
91
|
+
await (0, utils_1.generate)(dataDir, name, data);
|
|
92
|
+
return modulePath;
|
|
93
|
+
},
|
|
94
|
+
setGlobalData(data) {
|
|
95
|
+
var _a;
|
|
96
|
+
globalData[_a = plugin.name] ?? (globalData[_a] = {});
|
|
97
|
+
globalData[plugin.name][pluginId] = data;
|
|
98
|
+
},
|
|
137
99
|
};
|
|
138
|
-
|
|
139
|
-
await plugin.contentLoaded({
|
|
140
|
-
content: translatedContent,
|
|
141
|
-
actions,
|
|
142
|
-
allContent,
|
|
143
|
-
});
|
|
144
|
-
}));
|
|
145
|
-
// 4. Plugin Lifecycle - routesLoaded.
|
|
146
|
-
// Currently plugins run lifecycle methods in parallel and are not
|
|
147
|
-
// order-dependent. We could change this in future if there are plugins which
|
|
148
|
-
// need to run in certain order or depend on others for data.
|
|
149
|
-
await Promise.all(contentLoadedTranslatedPlugins.map(async (plugin) => {
|
|
150
|
-
if (!plugin.routesLoaded) {
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
// TODO remove this deprecated lifecycle soon
|
|
154
|
-
// deprecated since alpha-60
|
|
155
|
-
// TODO, 1 user reported usage of this lifecycle! https://github.com/facebook/docusaurus/issues/3918
|
|
156
|
-
logger_1.default.error `Plugin code=${'routesLoaded'} lifecycle is deprecated. If you think we should keep this lifecycle, please report here: path=${'https://github.com/facebook/docusaurus/issues/3918'}`;
|
|
157
|
-
await plugin.routesLoaded(pluginsRouteConfigs);
|
|
100
|
+
await plugin.contentLoaded({ content, actions, allContent });
|
|
158
101
|
}));
|
|
159
102
|
// Sort the route config. This ensures that route with nested
|
|
160
103
|
// routes are always placed last.
|
|
161
|
-
sortConfig(pluginsRouteConfigs, context.siteConfig.baseUrl);
|
|
162
|
-
|
|
163
|
-
function translateThemeConfig(untranslatedThemeConfig) {
|
|
164
|
-
return contentLoadedTranslatedPlugins.reduce((currentThemeConfig, plugin) => {
|
|
165
|
-
const translatedThemeConfigSlice = plugin.translateThemeConfig?.({
|
|
166
|
-
themeConfig: currentThemeConfig,
|
|
167
|
-
translationFiles: plugin.translationFiles,
|
|
168
|
-
});
|
|
169
|
-
return {
|
|
170
|
-
...currentThemeConfig,
|
|
171
|
-
...translatedThemeConfigSlice,
|
|
172
|
-
};
|
|
173
|
-
}, untranslatedThemeConfig);
|
|
174
|
-
}
|
|
175
|
-
return {
|
|
176
|
-
plugins: loadedPlugins,
|
|
177
|
-
pluginsRouteConfigs,
|
|
178
|
-
globalData,
|
|
179
|
-
themeConfigTranslated: translateThemeConfig(context.siteConfig.themeConfig),
|
|
180
|
-
};
|
|
104
|
+
(0, routeConfig_1.sortConfig)(pluginsRouteConfigs, context.siteConfig.baseUrl);
|
|
105
|
+
return { plugins: loadedPlugins, pluginsRouteConfigs, globalData };
|
|
181
106
|
}
|
|
182
107
|
exports.loadPlugins = loadPlugins;
|
|
@@ -4,22 +4,9 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import type {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
module: ImportedPluginModule;
|
|
14
|
-
};
|
|
15
|
-
/**
|
|
16
|
-
* Different from pluginModule.path, this one is always an absolute path used
|
|
17
|
-
* to resolve relative paths returned from lifecycles
|
|
18
|
-
*/
|
|
19
|
-
entryPath: string;
|
|
20
|
-
};
|
|
21
|
-
export declare function normalizePluginConfigs(pluginConfigs: PluginConfig[], configPath: string): Promise<NormalizedPluginConfig[]>;
|
|
22
|
-
export default function initPlugins({ pluginConfigs, context, }: {
|
|
23
|
-
pluginConfigs: PluginConfig[];
|
|
24
|
-
context: LoadContext;
|
|
25
|
-
}): Promise<InitializedPlugin[]>;
|
|
7
|
+
import type { LoadContext, InitializedPlugin } from '@docusaurus/types';
|
|
8
|
+
/**
|
|
9
|
+
* Runs the plugin constructors and returns their return values. It would load
|
|
10
|
+
* plugin configs from `plugins`, `themes`, and `presets`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function initPlugins(context: LoadContext): Promise<InitializedPlugin[]>;
|
|
@@ -6,73 +6,18 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.
|
|
9
|
+
exports.initPlugins = void 0;
|
|
10
10
|
const tslib_1 = require("tslib");
|
|
11
11
|
const module_1 = require("module");
|
|
12
12
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
13
|
-
const import_fresh_1 = tslib_1.__importDefault(require("import-fresh"));
|
|
14
13
|
const utils_1 = require("@docusaurus/utils");
|
|
15
|
-
const
|
|
14
|
+
const siteMetadata_1 = require("../siteMetadata");
|
|
16
15
|
const pluginIds_1 = require("./pluginIds");
|
|
17
16
|
const utils_validation_1 = require("@docusaurus/utils-validation");
|
|
18
|
-
|
|
19
|
-
const pluginRequire = (0, module_1.createRequire)(configPath);
|
|
20
|
-
// plugins: ['./plugin']
|
|
21
|
-
if (typeof pluginConfig === 'string') {
|
|
22
|
-
const pluginModuleImport = pluginConfig;
|
|
23
|
-
const pluginPath = pluginRequire.resolve(pluginModuleImport);
|
|
24
|
-
const pluginModule = (0, import_fresh_1.default)(pluginPath);
|
|
25
|
-
return {
|
|
26
|
-
plugin: pluginModule?.default ?? pluginModule,
|
|
27
|
-
options: {},
|
|
28
|
-
pluginModule: {
|
|
29
|
-
path: pluginModuleImport,
|
|
30
|
-
module: pluginModule,
|
|
31
|
-
},
|
|
32
|
-
entryPath: pluginPath,
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
// plugins: [function plugin() { }]
|
|
36
|
-
if (typeof pluginConfig === 'function') {
|
|
37
|
-
return {
|
|
38
|
-
plugin: pluginConfig,
|
|
39
|
-
options: {},
|
|
40
|
-
entryPath: configPath,
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
// plugins: [
|
|
44
|
-
// ['./plugin',options],
|
|
45
|
-
// ]
|
|
46
|
-
if (typeof pluginConfig[0] === 'string') {
|
|
47
|
-
const pluginModuleImport = pluginConfig[0];
|
|
48
|
-
const pluginPath = pluginRequire.resolve(pluginModuleImport);
|
|
49
|
-
const pluginModule = (0, import_fresh_1.default)(pluginPath);
|
|
50
|
-
return {
|
|
51
|
-
plugin: pluginModule?.default ?? pluginModule,
|
|
52
|
-
options: pluginConfig[1],
|
|
53
|
-
pluginModule: {
|
|
54
|
-
path: pluginModuleImport,
|
|
55
|
-
module: pluginModule,
|
|
56
|
-
},
|
|
57
|
-
entryPath: pluginPath,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
// plugins: [
|
|
61
|
-
// [function plugin() { },options],
|
|
62
|
-
// ]
|
|
63
|
-
return {
|
|
64
|
-
plugin: pluginConfig[0],
|
|
65
|
-
options: pluginConfig[1],
|
|
66
|
-
entryPath: configPath,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
async function normalizePluginConfigs(pluginConfigs, configPath) {
|
|
70
|
-
return Promise.all(pluginConfigs.map((pluginConfig) => normalizePluginConfig(pluginConfig, configPath)));
|
|
71
|
-
}
|
|
72
|
-
exports.normalizePluginConfigs = normalizePluginConfigs;
|
|
17
|
+
const configs_1 = require("./configs");
|
|
73
18
|
function getOptionValidationFunction(normalizedPluginConfig) {
|
|
74
19
|
if (normalizedPluginConfig.pluginModule) {
|
|
75
|
-
//
|
|
20
|
+
// Support both CommonJS and ES modules
|
|
76
21
|
return (normalizedPluginConfig.pluginModule.module?.default?.validateOptions ??
|
|
77
22
|
normalizedPluginConfig.pluginModule.module?.validateOptions);
|
|
78
23
|
}
|
|
@@ -80,22 +25,25 @@ function getOptionValidationFunction(normalizedPluginConfig) {
|
|
|
80
25
|
}
|
|
81
26
|
function getThemeValidationFunction(normalizedPluginConfig) {
|
|
82
27
|
if (normalizedPluginConfig.pluginModule) {
|
|
83
|
-
//
|
|
28
|
+
// Support both CommonJS and ES modules
|
|
84
29
|
return (normalizedPluginConfig.pluginModule.module.default?.validateThemeConfig ??
|
|
85
30
|
normalizedPluginConfig.pluginModule.module.validateThemeConfig);
|
|
86
31
|
}
|
|
87
32
|
return normalizedPluginConfig.plugin.validateThemeConfig;
|
|
88
33
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Runs the plugin constructors and returns their return values. It would load
|
|
36
|
+
* plugin configs from `plugins`, `themes`, and `presets`.
|
|
37
|
+
*/
|
|
38
|
+
async function initPlugins(context) {
|
|
39
|
+
// We need to resolve plugins from the perspective of the site config, as if
|
|
40
|
+
// we are using `require.resolve` on those module names.
|
|
92
41
|
const pluginRequire = (0, module_1.createRequire)(context.siteConfigPath);
|
|
93
|
-
const
|
|
42
|
+
const pluginConfigs = await (0, configs_1.loadPluginConfigs)(context);
|
|
94
43
|
async function doGetPluginVersion(normalizedPluginConfig) {
|
|
95
|
-
// get plugin version
|
|
96
44
|
if (normalizedPluginConfig.pluginModule?.path) {
|
|
97
45
|
const pluginPath = pluginRequire.resolve(normalizedPluginConfig.pluginModule?.path);
|
|
98
|
-
return (0,
|
|
46
|
+
return (0, siteMetadata_1.getPluginVersion)(pluginPath, context.siteDir);
|
|
99
47
|
}
|
|
100
48
|
return { type: 'local' };
|
|
101
49
|
}
|
|
@@ -140,8 +88,8 @@ async function initPlugins({ pluginConfigs, context, }) {
|
|
|
140
88
|
path: path_1.default.dirname(normalizedPluginConfig.entryPath),
|
|
141
89
|
};
|
|
142
90
|
}
|
|
143
|
-
const plugins = await Promise.all(
|
|
91
|
+
const plugins = await Promise.all(pluginConfigs.map(initializePlugin));
|
|
144
92
|
(0, pluginIds_1.ensureUniquePluginInstanceIds)(plugins);
|
|
145
93
|
return plugins;
|
|
146
94
|
}
|
|
147
|
-
exports.
|
|
95
|
+
exports.initPlugins = initPlugins;
|
|
File without changes
|
|
File without changes
|
|
@@ -5,4 +5,8 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import type { InitializedPlugin } from '@docusaurus/types';
|
|
8
|
+
/**
|
|
9
|
+
* It is forbidden to have 2 plugins of the same name sharing the same ID.
|
|
10
|
+
* This is required to support multi-instance plugins without conflict.
|
|
11
|
+
*/
|
|
8
12
|
export declare function ensureUniquePluginInstanceIds(plugins: InitializedPlugin[]): void;
|
|
@@ -10,8 +10,10 @@ exports.ensureUniquePluginInstanceIds = void 0;
|
|
|
10
10
|
const tslib_1 = require("tslib");
|
|
11
11
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
12
12
|
const utils_1 = require("@docusaurus/utils");
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* It is forbidden to have 2 plugins of the same name sharing the same ID.
|
|
15
|
+
* This is required to support multi-instance plugins without conflict.
|
|
16
|
+
*/
|
|
15
17
|
function ensureUniquePluginInstanceIds(plugins) {
|
|
16
18
|
const pluginsByName = lodash_1.default.groupBy(plugins, (p) => p.name);
|
|
17
19
|
Object.entries(pluginsByName).forEach(([pluginName, pluginInstances]) => {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import type { LoadContext, DocusaurusConfig } from '@docusaurus/types';
|
|
8
|
+
/**
|
|
9
|
+
* Calls preset functions, aggregates each of their return values, and returns
|
|
10
|
+
* the plugin and theme configs.
|
|
11
|
+
*/
|
|
12
|
+
export declare function loadPresets(context: LoadContext): Promise<Pick<DocusaurusConfig, 'plugins' | 'themes'>>;
|
|
@@ -6,13 +6,18 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.loadPresets = void 0;
|
|
9
10
|
const tslib_1 = require("tslib");
|
|
10
11
|
const module_1 = require("module");
|
|
11
12
|
const import_fresh_1 = tslib_1.__importDefault(require("import-fresh"));
|
|
12
|
-
const moduleShorthand_1 = require("
|
|
13
|
+
const moduleShorthand_1 = require("./moduleShorthand");
|
|
14
|
+
/**
|
|
15
|
+
* Calls preset functions, aggregates each of their return values, and returns
|
|
16
|
+
* the plugin and theme configs.
|
|
17
|
+
*/
|
|
13
18
|
async function loadPresets(context) {
|
|
14
|
-
// We need to resolve
|
|
15
|
-
//
|
|
19
|
+
// We need to resolve plugins from the perspective of the site config, as if
|
|
20
|
+
// we are using `require.resolve` on those module names.
|
|
16
21
|
const presetRequire = (0, module_1.createRequire)(context.siteConfigPath);
|
|
17
22
|
const { presets } = context.siteConfig;
|
|
18
23
|
const plugins = [];
|
|
@@ -20,6 +25,9 @@ async function loadPresets(context) {
|
|
|
20
25
|
presets.forEach((presetItem) => {
|
|
21
26
|
let presetModuleImport;
|
|
22
27
|
let presetOptions = {};
|
|
28
|
+
if (!presetItem) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
23
31
|
if (typeof presetItem === 'string') {
|
|
24
32
|
presetModuleImport = presetItem;
|
|
25
33
|
}
|
|
@@ -30,12 +38,12 @@ async function loadPresets(context) {
|
|
|
30
38
|
const presetModule = (0, import_fresh_1.default)(presetRequire.resolve(presetName));
|
|
31
39
|
const preset = (presetModule.default ?? presetModule)(context, presetOptions);
|
|
32
40
|
if (preset.plugins) {
|
|
33
|
-
plugins.push(...preset.plugins
|
|
41
|
+
plugins.push(...preset.plugins);
|
|
34
42
|
}
|
|
35
43
|
if (preset.themes) {
|
|
36
|
-
themes.push(...preset.themes
|
|
44
|
+
themes.push(...preset.themes);
|
|
37
45
|
}
|
|
38
46
|
});
|
|
39
47
|
return { plugins, themes };
|
|
40
48
|
}
|
|
41
|
-
exports.
|
|
49
|
+
exports.loadPresets = loadPresets;
|
|
@@ -6,4 +6,6 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { RouteConfig } from '@docusaurus/types';
|
|
8
8
|
import { type ApplyTrailingSlashParams } from '@docusaurus/utils-common';
|
|
9
|
-
|
|
9
|
+
/** Recursively applies trailing slash config to all nested routes. */
|
|
10
|
+
export declare function applyRouteTrailingSlash(route: RouteConfig, params: ApplyTrailingSlashParams): RouteConfig;
|
|
11
|
+
export declare function sortConfig(routeConfigs: RouteConfig[], baseUrl?: string): void;
|