@docusaurus/core 0.0.0-5858 → 0.0.0-5861

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.
Files changed (47) hide show
  1. package/lib/commands/build.d.ts +2 -2
  2. package/lib/commands/build.js +6 -6
  3. package/lib/commands/deploy.d.ts +2 -2
  4. package/lib/commands/deploy.js +2 -2
  5. package/lib/commands/external.js +2 -2
  6. package/lib/commands/serve.d.ts +2 -2
  7. package/lib/commands/{start.d.ts → start/start.d.ts} +3 -3
  8. package/lib/commands/start/start.js +47 -0
  9. package/lib/commands/start/utils.d.ts +31 -0
  10. package/lib/commands/start/utils.js +88 -0
  11. package/lib/commands/start/watcher.d.ts +42 -0
  12. package/lib/commands/start/watcher.js +78 -0
  13. package/lib/commands/start/webpack.d.ts +15 -0
  14. package/lib/commands/start/webpack.js +133 -0
  15. package/lib/commands/swizzle/context.js +2 -2
  16. package/lib/commands/writeHeadingIds.js +2 -2
  17. package/lib/commands/writeTranslations.d.ts +2 -2
  18. package/lib/commands/writeTranslations.js +2 -2
  19. package/lib/index.d.ts +1 -1
  20. package/lib/index.js +1 -1
  21. package/lib/server/brokenLinks.js +2 -2
  22. package/lib/server/codegen/codegen.d.ts +20 -0
  23. package/lib/server/codegen/codegen.js +65 -0
  24. package/lib/server/codegen/codegenRoutes.d.ts +49 -0
  25. package/lib/server/codegen/codegenRoutes.js +190 -0
  26. package/lib/server/i18n.d.ts +2 -2
  27. package/lib/server/plugins/actions.d.ts +19 -0
  28. package/lib/server/plugins/actions.js +61 -0
  29. package/lib/server/plugins/plugins.d.ts +27 -0
  30. package/lib/server/plugins/plugins.js +228 -0
  31. package/lib/server/plugins/routeConfig.d.ts +1 -1
  32. package/lib/server/plugins/routeConfig.js +4 -4
  33. package/lib/server/routes.d.ts +4 -45
  34. package/lib/server/routes.js +15 -166
  35. package/lib/server/{index.d.ts → site.d.ts} +12 -4
  36. package/lib/server/site.js +167 -0
  37. package/lib/server/translations/translations.d.ts +3 -0
  38. package/lib/server/translations/translations.js +7 -1
  39. package/lib/server/utils.d.ts +0 -2
  40. package/lib/server/utils.js +1 -9
  41. package/lib/utils.d.ts +1 -0
  42. package/lib/utils.js +14 -3
  43. package/package.json +11 -10
  44. package/lib/commands/start.js +0 -242
  45. package/lib/server/index.js +0 -154
  46. package/lib/server/plugins/index.d.ts +0 -18
  47. package/lib/server/plugins/index.js +0 -106
@@ -0,0 +1,228 @@
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.reloadPlugin = exports.getPluginByIdentifier = exports.loadPlugins = exports.mergeGlobalData = void 0;
10
+ const tslib_1 = require("tslib");
11
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
12
+ const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
13
+ const init_1 = require("./init");
14
+ const synthetic_1 = require("./synthetic");
15
+ const translations_1 = require("../translations/translations");
16
+ const routeConfig_1 = require("./routeConfig");
17
+ const utils_1 = require("../../utils");
18
+ const actions_1 = require("./actions");
19
+ async function translatePlugin({ plugin, context, }) {
20
+ const { content } = plugin;
21
+ const rawTranslationFiles = (await plugin.getTranslationFiles?.({ content: plugin.content })) ?? [];
22
+ const translationFiles = await Promise.all(rawTranslationFiles.map((translationFile) => (0, translations_1.localizePluginTranslationFile)({
23
+ localizationDir: context.localizationDir,
24
+ translationFile,
25
+ plugin,
26
+ })));
27
+ const translatedContent = plugin.translateContent?.({ content, translationFiles }) ?? content;
28
+ const translatedThemeConfigSlice = plugin.translateThemeConfig?.({
29
+ themeConfig: context.siteConfig.themeConfig,
30
+ translationFiles,
31
+ });
32
+ // TODO dangerous legacy, need to be refactored!
33
+ // Side-effect to merge theme config translations. A plugin should only
34
+ // translate its own slice of theme config and should make no assumptions
35
+ // about other plugins' keys, so this is safe to run in parallel.
36
+ Object.assign(context.siteConfig.themeConfig, translatedThemeConfigSlice);
37
+ return { ...plugin, content: translatedContent };
38
+ }
39
+ async function executePluginLoadContent({ plugin, context, }) {
40
+ return utils_1.PerfLogger.async(`Plugin - loadContent - ${plugin.name}@${plugin.options.id}`, async () => {
41
+ const content = await plugin.loadContent?.();
42
+ const loadedPlugin = { ...plugin, content };
43
+ return translatePlugin({ plugin: loadedPlugin, context });
44
+ });
45
+ }
46
+ async function executePluginsLoadContent({ plugins, context, }) {
47
+ return utils_1.PerfLogger.async(`Plugins - loadContent`, () => Promise.all(plugins.map((plugin) => executePluginLoadContent({ plugin, context }))));
48
+ }
49
+ function aggregateAllContent(loadedPlugins) {
50
+ return lodash_1.default.chain(loadedPlugins)
51
+ .groupBy((item) => item.name)
52
+ .mapValues((nameItems) => lodash_1.default.chain(nameItems)
53
+ .groupBy((item) => item.options.id)
54
+ .mapValues((idItems) => idItems[0].content)
55
+ .value())
56
+ .value();
57
+ }
58
+ async function executePluginContentLoaded({ plugin, context, }) {
59
+ return utils_1.PerfLogger.async(`Plugins - contentLoaded - ${plugin.name}@${plugin.options.id}`, async () => {
60
+ if (!plugin.contentLoaded) {
61
+ return { routes: [], globalData: undefined };
62
+ }
63
+ const pluginActionsUtils = await (0, actions_1.createPluginActionsUtils)({
64
+ plugin,
65
+ generatedFilesDir: context.generatedFilesDir,
66
+ baseUrl: context.siteConfig.baseUrl,
67
+ trailingSlash: context.siteConfig.trailingSlash,
68
+ });
69
+ await plugin.contentLoaded({
70
+ content: plugin.content,
71
+ actions: pluginActionsUtils.getActions(),
72
+ });
73
+ return {
74
+ routes: pluginActionsUtils.getRoutes(),
75
+ globalData: pluginActionsUtils.getGlobalData(),
76
+ };
77
+ });
78
+ }
79
+ async function executePluginAllContentLoaded({ plugin, context, allContent, }) {
80
+ return utils_1.PerfLogger.async(`Plugins - allContentLoaded - ${plugin.name}@${plugin.options.id}`, async () => {
81
+ if (!plugin.allContentLoaded) {
82
+ return { routes: [], globalData: undefined };
83
+ }
84
+ const pluginActionsUtils = await (0, actions_1.createPluginActionsUtils)({
85
+ plugin,
86
+ generatedFilesDir: context.generatedFilesDir,
87
+ baseUrl: context.siteConfig.baseUrl,
88
+ trailingSlash: context.siteConfig.trailingSlash,
89
+ });
90
+ await plugin.allContentLoaded({
91
+ allContent,
92
+ actions: pluginActionsUtils.getActions(),
93
+ });
94
+ return {
95
+ routes: pluginActionsUtils.getRoutes(),
96
+ globalData: pluginActionsUtils.getGlobalData(),
97
+ };
98
+ });
99
+ }
100
+ async function executePluginsContentLoaded({ plugins, context, }) {
101
+ return utils_1.PerfLogger.async(`Plugins - contentLoaded`, async () => {
102
+ const routes = [];
103
+ const globalData = {};
104
+ await Promise.all(plugins.map(async (plugin) => {
105
+ var _a;
106
+ const { routes: pluginRoutes, globalData: pluginGlobalData } = await executePluginContentLoaded({
107
+ plugin,
108
+ context,
109
+ });
110
+ routes.push(...pluginRoutes);
111
+ if (pluginGlobalData !== undefined) {
112
+ globalData[_a = plugin.name] ?? (globalData[_a] = {});
113
+ globalData[plugin.name][plugin.options.id] = pluginGlobalData;
114
+ }
115
+ }));
116
+ // Sort the route config.
117
+ // This ensures that route with sub routes are always placed last.
118
+ (0, routeConfig_1.sortRoutes)(routes, context.siteConfig.baseUrl);
119
+ return { routes, globalData };
120
+ });
121
+ }
122
+ async function executePluginsAllContentLoaded({ plugins, context, }) {
123
+ return utils_1.PerfLogger.async(`Plugins - allContentLoaded`, async () => {
124
+ const allContent = aggregateAllContent(plugins);
125
+ const routes = [];
126
+ const globalData = {};
127
+ await Promise.all(plugins.map(async (plugin) => {
128
+ var _a;
129
+ const { routes: pluginRoutes, globalData: pluginGlobalData } = await executePluginAllContentLoaded({
130
+ plugin,
131
+ context,
132
+ allContent,
133
+ });
134
+ routes.push(...pluginRoutes);
135
+ if (pluginGlobalData !== undefined) {
136
+ globalData[_a = plugin.name] ?? (globalData[_a] = {});
137
+ globalData[plugin.name][plugin.options.id] = pluginGlobalData;
138
+ }
139
+ }));
140
+ // Sort the route config.
141
+ // This ensures that route with sub routes are always placed last.
142
+ (0, routeConfig_1.sortRoutes)(routes, context.siteConfig.baseUrl);
143
+ return { routes, globalData };
144
+ });
145
+ }
146
+ function mergeGlobalData(...globalDataList) {
147
+ const result = {};
148
+ const allPluginIdentifiers = globalDataList.flatMap((gd) => Object.keys(gd).flatMap((name) => Object.keys(gd[name]).map((id) => ({ name, id }))));
149
+ allPluginIdentifiers.forEach(({ name, id }) => {
150
+ const allData = globalDataList
151
+ .map((gd) => gd?.[name]?.[id])
152
+ .filter((d) => typeof d !== 'undefined');
153
+ const mergedData = allData.length === 1 ? allData[0] : Object.assign({}, ...allData);
154
+ result[name] ?? (result[name] = {});
155
+ result[name][id] = mergedData;
156
+ });
157
+ return result;
158
+ }
159
+ exports.mergeGlobalData = mergeGlobalData;
160
+ function mergeResults({ contentLoadedResult, allContentLoadedResult, }) {
161
+ const routes = [
162
+ ...contentLoadedResult.routes,
163
+ ...allContentLoadedResult.routes,
164
+ ];
165
+ (0, routeConfig_1.sortRoutes)(routes);
166
+ const globalData = mergeGlobalData(contentLoadedResult.globalData, allContentLoadedResult.globalData);
167
+ return { routes, globalData };
168
+ }
169
+ /**
170
+ * Initializes the plugins and run their lifecycle functions.
171
+ */
172
+ async function loadPlugins(context) {
173
+ return utils_1.PerfLogger.async('Plugins - loadPlugins', async () => {
174
+ const initializedPlugins = await utils_1.PerfLogger.async('Plugins - initPlugins', () => (0, init_1.initPlugins)(context));
175
+ initializedPlugins.push((0, synthetic_1.createBootstrapPlugin)(context), (0, synthetic_1.createMDXFallbackPlugin)(context));
176
+ const plugins = await executePluginsLoadContent({
177
+ plugins: initializedPlugins,
178
+ context,
179
+ });
180
+ const contentLoadedResult = await executePluginsContentLoaded({
181
+ plugins,
182
+ context,
183
+ });
184
+ const allContentLoadedResult = await executePluginsAllContentLoaded({
185
+ plugins,
186
+ context,
187
+ });
188
+ const { routes, globalData } = mergeResults({
189
+ contentLoadedResult,
190
+ allContentLoadedResult,
191
+ });
192
+ return { plugins, routes, globalData };
193
+ });
194
+ }
195
+ exports.loadPlugins = loadPlugins;
196
+ function getPluginByIdentifier({ plugins, pluginIdentifier, }) {
197
+ const plugin = plugins.find((p) => p.name === pluginIdentifier.name && p.options.id === pluginIdentifier.id);
198
+ if (!plugin) {
199
+ throw new Error(logger_1.default.interpolate `Plugin not found for identifier ${pluginIdentifier.name}@${pluginIdentifier.id}`);
200
+ }
201
+ return plugin;
202
+ }
203
+ exports.getPluginByIdentifier = getPluginByIdentifier;
204
+ async function reloadPlugin({ pluginIdentifier, plugins: previousPlugins, context, }) {
205
+ return utils_1.PerfLogger.async('Plugins - reloadPlugin', async () => {
206
+ const plugin = getPluginByIdentifier({
207
+ plugins: previousPlugins,
208
+ pluginIdentifier,
209
+ });
210
+ const reloadedPlugin = await executePluginLoadContent({ plugin, context });
211
+ const plugins = previousPlugins.with(previousPlugins.indexOf(plugin), reloadedPlugin);
212
+ // TODO optimize this, we shouldn't need to re-run this lifecycle
213
+ const contentLoadedResult = await executePluginsContentLoaded({
214
+ plugins,
215
+ context,
216
+ });
217
+ const allContentLoadedResult = await executePluginsAllContentLoaded({
218
+ plugins,
219
+ context,
220
+ });
221
+ const { routes, globalData } = mergeResults({
222
+ contentLoadedResult,
223
+ allContentLoadedResult,
224
+ });
225
+ return { plugins, routes, globalData };
226
+ });
227
+ }
228
+ exports.reloadPlugin = reloadPlugin;
@@ -8,4 +8,4 @@ import { type ApplyTrailingSlashParams } from '@docusaurus/utils-common';
8
8
  import type { RouteConfig } from '@docusaurus/types';
9
9
  /** Recursively applies trailing slash config to all nested routes. */
10
10
  export declare function applyRouteTrailingSlash(route: RouteConfig, params: ApplyTrailingSlashParams): RouteConfig;
11
- export declare function sortConfig(routeConfigs: RouteConfig[], baseUrl?: string): void;
11
+ export declare function sortRoutes(routeConfigs: RouteConfig[], baseUrl?: string): void;
@@ -6,7 +6,7 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.sortConfig = exports.applyRouteTrailingSlash = void 0;
9
+ exports.sortRoutes = exports.applyRouteTrailingSlash = void 0;
10
10
  const utils_common_1 = require("@docusaurus/utils-common");
11
11
  /** Recursively applies trailing slash config to all nested routes. */
12
12
  function applyRouteTrailingSlash(route, params) {
@@ -19,7 +19,7 @@ function applyRouteTrailingSlash(route, params) {
19
19
  };
20
20
  }
21
21
  exports.applyRouteTrailingSlash = applyRouteTrailingSlash;
22
- function sortConfig(routeConfigs, baseUrl = '/') {
22
+ function sortRoutes(routeConfigs, baseUrl = '/') {
23
23
  // Sort the route config. This ensures that route with nested
24
24
  // routes is always placed last.
25
25
  routeConfigs.sort((a, b) => {
@@ -49,8 +49,8 @@ function sortConfig(routeConfigs, baseUrl = '/') {
49
49
  });
50
50
  routeConfigs.forEach((routeConfig) => {
51
51
  if (routeConfig.routes) {
52
- sortConfig(routeConfig.routes, baseUrl);
52
+ sortRoutes(routeConfig.routes, baseUrl);
53
53
  }
54
54
  });
55
55
  }
56
- exports.sortConfig = sortConfig;
56
+ exports.sortRoutes = sortRoutes;
@@ -4,48 +4,7 @@
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 { RouteConfig, RouteChunkNames, ReportingSeverity } from '@docusaurus/types';
8
- type LoadedRoutes = {
9
- /** Serialized routes config that can be directly emitted into temp file. */
10
- routesConfig: string;
11
- /** @see {ChunkNames} */
12
- routesChunkNames: RouteChunkNames;
13
- /**
14
- * A map from chunk name to module paths. Module paths would have backslash
15
- * escaped already, so they can be directly printed.
16
- */
17
- registry: {
18
- [chunkName: string]: string;
19
- };
20
- /**
21
- * Collect all page paths for injecting it later in the plugin lifecycle.
22
- * This is useful for plugins like sitemaps, redirects etc... Only collects
23
- * "actual" pages, i.e. those without subroutes, because if a route has
24
- * subroutes, it is probably a wrapper.
25
- */
26
- routesPaths: string[];
27
- };
28
- /**
29
- * Generates a unique chunk name that can be used in the chunk registry.
30
- *
31
- * @param modulePath A path to generate chunk name from. The actual value has no
32
- * semantic significance.
33
- * @param prefix A prefix to append to the chunk name, to avoid name clash.
34
- * @param preferredName Chunk names default to `modulePath`, and this can supply
35
- * a more human-readable name.
36
- * @param shortId When `true`, the chunk name would only be a hash without any
37
- * other characters. Useful for bundle size. Defaults to `true` in production.
38
- */
39
- export declare function genChunkName(modulePath: string, prefix?: string, preferredName?: string, shortId?: boolean): string;
40
- export declare function handleDuplicateRoutes(pluginsRouteConfigs: RouteConfig[], onDuplicateRoutes: ReportingSeverity): void;
41
- /**
42
- * Routes are prepared into three temp files:
43
- *
44
- * - `routesConfig`, the route config passed to react-router. This file is kept
45
- * minimal, because it can't be code-splitted.
46
- * - `routesChunkNames`, a mapping from route paths (hashed) to code-splitted
47
- * chunk names.
48
- * - `registry`, a mapping from chunk names to options for react-loadable.
49
- */
50
- export declare function loadRoutes(routeConfigs: RouteConfig[], baseUrl: string, onDuplicateRoutes: ReportingSeverity): LoadedRoutes;
51
- export {};
7
+ import type { RouteConfig, ReportingSeverity } from '@docusaurus/types';
8
+ export declare function getAllFinalRoutes(routeConfig: RouteConfig[]): RouteConfig[];
9
+ export declare function handleDuplicateRoutes(routes: RouteConfig[], onDuplicateRoutes: ReportingSeverity): void;
10
+ export declare function getRoutesPaths(routeConfigs: RouteConfig[], baseUrl: string): string[];
@@ -6,115 +6,23 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.loadRoutes = exports.handleDuplicateRoutes = exports.genChunkName = void 0;
9
+ exports.getRoutesPaths = exports.handleDuplicateRoutes = exports.getAllFinalRoutes = void 0;
10
10
  const tslib_1 = require("tslib");
11
- const querystring_1 = tslib_1.__importDefault(require("querystring"));
12
- const lodash_1 = tslib_1.__importDefault(require("lodash"));
13
11
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
14
12
  const utils_1 = require("@docusaurus/utils");
15
- const utils_2 = require("./utils");
16
- /** Indents every line of `str` by one level. */
17
- function indent(str) {
18
- return ` ${str.replace(/\n/g, `\n `)}`;
19
- }
20
- const chunkNameCache = new Map();
21
- const chunkNameCount = new Map();
22
- /**
23
- * Generates a unique chunk name that can be used in the chunk registry.
24
- *
25
- * @param modulePath A path to generate chunk name from. The actual value has no
26
- * semantic significance.
27
- * @param prefix A prefix to append to the chunk name, to avoid name clash.
28
- * @param preferredName Chunk names default to `modulePath`, and this can supply
29
- * a more human-readable name.
30
- * @param shortId When `true`, the chunk name would only be a hash without any
31
- * other characters. Useful for bundle size. Defaults to `true` in production.
32
- */
33
- function genChunkName(modulePath, prefix, preferredName, shortId = process.env.NODE_ENV === 'production') {
34
- let chunkName = chunkNameCache.get(modulePath);
35
- if (!chunkName) {
36
- if (shortId) {
37
- chunkName = (0, utils_1.simpleHash)(modulePath, 8);
38
- }
39
- else {
40
- let str = modulePath;
41
- if (preferredName) {
42
- const shortHash = (0, utils_1.simpleHash)(modulePath, 3);
43
- str = `${preferredName}${shortHash}`;
44
- }
45
- const name = (0, utils_1.docuHash)(str);
46
- chunkName = prefix ? `${prefix}---${name}` : name;
47
- }
48
- const seenCount = (chunkNameCount.get(chunkName) ?? 0) + 1;
49
- if (seenCount > 1) {
50
- chunkName += seenCount.toString(36);
51
- }
52
- chunkNameCache.set(modulePath, chunkName);
53
- chunkNameCount.set(chunkName, seenCount);
54
- }
55
- return chunkName;
56
- }
57
- exports.genChunkName = genChunkName;
58
- /**
59
- * Takes a piece of route config, and serializes it into raw JS code. The shape
60
- * is the same as react-router's `RouteConfig`. Formatting is similar to
61
- * `JSON.stringify` but without all the quotes.
62
- */
63
- function serializeRouteConfig({ routePath, routeHash, exact, subroutesCodeStrings, props, }) {
64
- const parts = [
65
- `path: '${routePath}'`,
66
- `component: ComponentCreator('${routePath}', '${routeHash}')`,
67
- ];
68
- if (exact) {
69
- parts.push(`exact: true`);
13
+ // Recursively get the final routes (routes with no subroutes)
14
+ function getAllFinalRoutes(routeConfig) {
15
+ function getFinalRoutes(route) {
16
+ return route.routes ? route.routes.flatMap(getFinalRoutes) : [route];
70
17
  }
71
- if (subroutesCodeStrings) {
72
- parts.push(`routes: [
73
- ${indent(subroutesCodeStrings.join(',\n'))}
74
- ]`);
75
- }
76
- Object.entries(props).forEach(([propName, propValue]) => {
77
- const isIdentifier = /^[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*$/u.test(propName);
78
- const key = isIdentifier ? propName : JSON.stringify(propName);
79
- parts.push(`${key}: ${JSON.stringify(propValue)}`);
80
- });
81
- return `{
82
- ${indent(parts.join(',\n'))}
83
- }`;
18
+ return routeConfig.flatMap(getFinalRoutes);
84
19
  }
85
- const isModule = (value) => typeof value === 'string' ||
86
- (typeof value === 'object' &&
87
- // eslint-disable-next-line no-underscore-dangle
88
- !!value?.__import);
89
- /**
90
- * Takes a {@link Module} (which is nothing more than a path plus some metadata
91
- * like query) and returns the string path it represents.
92
- */
93
- function getModulePath(target) {
94
- if (typeof target === 'string') {
95
- return target;
96
- }
97
- const queryStr = target.query ? `?${querystring_1.default.stringify(target.query)}` : '';
98
- return `${target.path}${queryStr}`;
99
- }
100
- function genChunkNames(routeModule, prefix, name, res) {
101
- if (isModule(routeModule)) {
102
- // This is a leaf node, no need to recurse
103
- const modulePath = getModulePath(routeModule);
104
- const chunkName = genChunkName(modulePath, prefix, name);
105
- res.registry[chunkName] = (0, utils_1.escapePath)(modulePath);
106
- return chunkName;
107
- }
108
- if (Array.isArray(routeModule)) {
109
- return routeModule.map((val, index) => genChunkNames(val, `${index}`, name, res));
110
- }
111
- return lodash_1.default.mapValues(routeModule, (v, key) => genChunkNames(v, key, name, res));
112
- }
113
- function handleDuplicateRoutes(pluginsRouteConfigs, onDuplicateRoutes) {
20
+ exports.getAllFinalRoutes = getAllFinalRoutes;
21
+ function handleDuplicateRoutes(routes, onDuplicateRoutes) {
114
22
  if (onDuplicateRoutes === 'ignore') {
115
23
  return;
116
24
  }
117
- const allRoutes = (0, utils_2.getAllFinalRoutes)(pluginsRouteConfigs).map((routeConfig) => routeConfig.path);
25
+ const allRoutes = getAllFinalRoutes(routes).map((routeConfig) => routeConfig.path);
118
26
  const seenRoutes = new Set();
119
27
  const duplicatePaths = allRoutes.filter((route) => {
120
28
  if (seenRoutes.has(route)) {
@@ -129,36 +37,6 @@ This could lead to non-deterministic routing behavior.`;
129
37
  }
130
38
  }
131
39
  exports.handleDuplicateRoutes = handleDuplicateRoutes;
132
- /**
133
- * This is the higher level overview of route code generation. For each route
134
- * config node, it returns the node's serialized form, and mutates `registry`,
135
- * `routesPaths`, and `routesChunkNames` accordingly.
136
- */
137
- function genRouteCode(routeConfig, res) {
138
- const { path: routePath, component, modules = {}, context, routes: subroutes, priority, exact, ...props } = routeConfig;
139
- if (typeof routePath !== 'string' || !component) {
140
- throw new Error(`Invalid route config: path must be a string and component is required.
141
- ${JSON.stringify(routeConfig)}`);
142
- }
143
- if (!subroutes) {
144
- res.routesPaths.push(routePath);
145
- }
146
- const routeHash = (0, utils_1.simpleHash)(JSON.stringify(routeConfig), 3);
147
- res.routesChunkNames[`${routePath}-${routeHash}`] = {
148
- // Avoid clash with a prop called "component"
149
- ...genChunkNames({ __comp: component }, 'component', component, res),
150
- ...(context &&
151
- genChunkNames({ __context: context }, 'context', routePath, res)),
152
- ...genChunkNames(modules, 'module', routePath, res),
153
- };
154
- return serializeRouteConfig({
155
- routePath: routePath.replace(/'/g, "\\'"),
156
- routeHash,
157
- subroutesCodeStrings: subroutes?.map((r) => genRouteCode(r, res)),
158
- exact,
159
- props,
160
- });
161
- }
162
40
  /**
163
41
  * Old stuff
164
42
  * As far as I understand, this is what permits to SSG the 404.html file
@@ -167,39 +45,10 @@ ${JSON.stringify(routeConfig)}`);
167
45
  * The extension probably permits to avoid emitting "/404/index.html"
168
46
  */
169
47
  const NotFoundRoutePath = '/404.html';
170
- /**
171
- * Routes are prepared into three temp files:
172
- *
173
- * - `routesConfig`, the route config passed to react-router. This file is kept
174
- * minimal, because it can't be code-splitted.
175
- * - `routesChunkNames`, a mapping from route paths (hashed) to code-splitted
176
- * chunk names.
177
- * - `registry`, a mapping from chunk names to options for react-loadable.
178
- */
179
- function loadRoutes(routeConfigs, baseUrl, onDuplicateRoutes) {
180
- handleDuplicateRoutes(routeConfigs, onDuplicateRoutes);
181
- const res = {
182
- // To be written by `genRouteCode`
183
- routesConfig: '',
184
- routesChunkNames: {},
185
- registry: {},
186
- routesPaths: [(0, utils_1.normalizeUrl)([baseUrl, NotFoundRoutePath])],
187
- };
188
- // `genRouteCode` would mutate `res`
189
- const routeConfigSerialized = routeConfigs
190
- .map((r) => genRouteCode(r, res))
191
- .join(',\n');
192
- res.routesConfig = `import React from 'react';
193
- import ComponentCreator from '@docusaurus/ComponentCreator';
194
-
195
- export default [
196
- ${indent(routeConfigSerialized)},
197
- {
198
- path: '*',
199
- component: ComponentCreator('*'),
200
- },
201
- ];
202
- `;
203
- return res;
48
+ function getRoutesPaths(routeConfigs, baseUrl) {
49
+ return [
50
+ (0, utils_1.normalizeUrl)([baseUrl, NotFoundRoutePath]),
51
+ ...getAllFinalRoutes(routeConfigs).map((r) => r.path),
52
+ ];
204
53
  }
205
- exports.loadRoutes = loadRoutes;
54
+ exports.getRoutesPaths = getRoutesPaths;
@@ -5,7 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { LoadContext, Props } from '@docusaurus/types';
8
- export type LoadContextOptions = {
8
+ import type { PluginIdentifier } from '@docusaurus/types/src/plugin';
9
+ export type LoadContextParams = {
9
10
  /** Usually the CWD; can be overridden with command argument. */
10
11
  siteDir: string;
11
12
  /** Custom output directory. Can be customized with `--out-dir` option */
@@ -22,17 +23,24 @@ export type LoadContextOptions = {
22
23
  */
23
24
  localizePath?: boolean;
24
25
  };
26
+ export type LoadSiteParams = LoadContextParams;
27
+ export type Site = {
28
+ props: Props;
29
+ params: LoadSiteParams;
30
+ };
25
31
  /**
26
- * Loading context is the very first step in site building. Its options are
32
+ * Loading context is the very first step in site building. Its params are
27
33
  * directly acquired from CLI options. It mainly loads `siteConfig` and the i18n
28
34
  * context (which includes code translations). The `LoadContext` will be passed
29
35
  * to plugin constructors.
30
36
  */
31
- export declare function loadContext(options: LoadContextOptions): Promise<LoadContext>;
37
+ export declare function loadContext(params: LoadContextParams): Promise<LoadContext>;
32
38
  /**
33
39
  * This is the crux of the Docusaurus server-side. It reads everything it needs—
34
40
  * code translations, config file, plugin modules... Plugins then use their
35
41
  * lifecycles to generate content and other data. It is side-effect-ful because
36
42
  * it generates temp files in the `.docusaurus` folder for the bundler.
37
43
  */
38
- export declare function load(options: LoadContextOptions): Promise<Props>;
44
+ export declare function loadSite(params: LoadContextParams): Promise<Site>;
45
+ export declare function reloadSite(site: Site): Promise<Site>;
46
+ export declare function reloadSitePlugin(site: Site, pluginIdentifier: PluginIdentifier): Promise<Site>;