@docusaurus/core 3.9.1 → 3.9.2-alpha.0-canary-6548

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/README.md CHANGED
@@ -1 +1,3 @@
1
- # Docusaurus core
1
+ # `@docusaurus/core`
2
+
3
+ The core package of Docusaurus
@@ -63,7 +63,7 @@ function Link({ isNavLink, to, href, activeClassName, isActive, 'data-noBrokenLi
63
63
  const preloaded = useRef(false);
64
64
  const LinkComponent = (isNavLink ? NavLink : RRLink);
65
65
  const IOSupported = ExecutionEnvironment.canUseIntersectionObserver;
66
- const ioRef = useRef();
66
+ const ioRef = useRef(undefined);
67
67
  const handleRef = (el) => {
68
68
  innerRef.current = el;
69
69
  if (IOSupported && el && isInternal) {
@@ -4,8 +4,11 @@
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
+ // Poor man's protocol detection
8
+ // Spec: https://datatracker.ietf.org/doc/html/rfc3986#section-3.1
9
+ // In particular: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
7
10
  export function hasProtocol(url) {
8
- return /^(?:\w*:|\/\/)/.test(url);
11
+ return /^(?:[A-Za-z][A-Za-z\d+.-]*:|\/\/)/.test(url);
9
12
  }
10
13
  export default function isInternalUrl(url) {
11
14
  return typeof url !== 'undefined' && !hasProtocol(url);
@@ -11,10 +11,9 @@ const tslib_1 = require("tslib");
11
11
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
12
  const logger_1 = tslib_1.__importStar(require("@docusaurus/logger"));
13
13
  const utils_1 = require("@docusaurus/utils");
14
- const site_1 = require("../../server/site");
15
14
  const i18n_1 = require("../../server/i18n");
16
15
  const buildLocale_1 = require("./buildLocale");
17
- const buildUtils_1 = require("./buildUtils");
16
+ const config_1 = require("../../server/config");
18
17
  async function build(siteDirParam = '.', cliOptions = {}) {
19
18
  process.env.BABEL_ENV = 'production';
20
19
  process.env.NODE_ENV = 'production';
@@ -50,24 +49,18 @@ function orderLocales({ locales, defaultLocale, }) {
50
49
  }
51
50
  }
52
51
  async function getLocalesToBuild({ siteDir, cliOptions, }) {
53
- // TODO we shouldn't need to load all context + i18n just to get that list
54
- // only loading siteConfig should be enough
55
- const context = await (0, site_1.loadContext)({
52
+ const { siteConfig } = await (0, config_1.loadSiteConfig)({
56
53
  siteDir,
57
- outDir: cliOptions.outDir,
58
- config: cliOptions.config,
59
- automaticBaseUrlLocalizationDisabled: (0, buildUtils_1.isAutomaticBaseUrlLocalizationDisabled)(cliOptions),
54
+ customConfigFilePath: cliOptions.config,
60
55
  });
61
- const i18n = await (0, i18n_1.loadI18n)({
62
- siteDir,
63
- config: context.siteConfig,
64
- currentLocale: context.siteConfig.i18n.defaultLocale, // Awkward but ok
65
- automaticBaseUrlLocalizationDisabled: false,
66
- });
67
- const locales = cliOptions.locale ?? i18n.locales;
56
+ const locales = cliOptions.locale ??
57
+ (0, i18n_1.getLocaleList)({
58
+ i18nConfig: siteConfig.i18n,
59
+ currentLocale: siteConfig.i18n.defaultLocale, // Awkward but ok
60
+ });
68
61
  return orderLocales({
69
62
  locales: locales,
70
- defaultLocale: i18n.defaultLocale,
63
+ defaultLocale: siteConfig.i18n.defaultLocale,
71
64
  });
72
65
  }
73
66
  async function tryToBuildLocale(params) {
@@ -22,6 +22,7 @@ const ssgExecutor_1 = require("../../ssg/ssgExecutor");
22
22
  const clearPath_1 = tslib_1.__importDefault(require("../utils/clearPath"));
23
23
  const buildUtils_1 = require("./buildUtils");
24
24
  const SkipBundling = process.env.DOCUSAURUS_SKIP_BUNDLING === 'true';
25
+ const ReturnAfterLoading = process.env.DOCUSAURUS_RETURN_AFTER_LOADING === 'true';
25
26
  const ExitAfterLoading = process.env.DOCUSAURUS_EXIT_AFTER_LOADING === 'true';
26
27
  const ExitAfterBundling = process.env.DOCUSAURUS_EXIT_AFTER_BUNDLING === 'true';
27
28
  async function buildLocale({ siteDir, locale, cliOptions, }) {
@@ -37,6 +38,9 @@ async function buildLocale({ siteDir, locale, cliOptions, }) {
37
38
  locale,
38
39
  automaticBaseUrlLocalizationDisabled: (0, buildUtils_1.isAutomaticBaseUrlLocalizationDisabled)(cliOptions),
39
40
  }));
41
+ if (ReturnAfterLoading) {
42
+ return;
43
+ }
40
44
  if (ExitAfterLoading) {
41
45
  return process.exit(0);
42
46
  }
@@ -128,7 +132,7 @@ async function getBuildClientConfig({ props, cliOptions, configureWebpackUtils,
128
132
  const result = await (0, client_1.createBuildClientConfig)({
129
133
  props,
130
134
  minify: cliOptions.minify ?? true,
131
- faster: props.siteConfig.future.experimental_faster,
135
+ faster: props.siteConfig.future.faster,
132
136
  configureWebpackUtils,
133
137
  bundleAnalyzer: cliOptions.bundleAnalyzer ?? false,
134
138
  });
@@ -135,8 +135,10 @@ async function createCLIProgram({ cli, cliArgs, siteDir, config, }) {
135
135
  cli
136
136
  .command('write-heading-ids [siteDir] [files...]')
137
137
  .description('Generate heading ids in Markdown content.')
138
+ .option('--syntax <syntax>', 'heading ID syntax: "classic" ({#id}) or "mdx-comment" ({/* #id */}) (default: "classic")')
139
+ .option('--migrate', 'migrate existing heading IDs to the target --syntax, if they are using a different syntax (default: false)')
140
+ .option('--overwrite', 'overwrite existing heading IDs, re-generate them from the heading text (default: false)')
138
141
  .option('--maintain-case', "keep the headings' casing, otherwise make all lowercase (default: false)")
139
- .option('--overwrite', 'overwrite existing heading IDs (default: false)')
140
142
  .action(writeHeadingIds_1.writeHeadingIds);
141
143
  cli.arguments('<command>').action((cmd) => {
142
144
  cli.outputHelp();
@@ -102,7 +102,7 @@ async function getStartClientConfig({ props, minify, poll, configureWebpackUtils
102
102
  let { clientConfig: config } = await (0, client_1.createStartClientConfig)({
103
103
  props,
104
104
  minify,
105
- faster: props.siteConfig.future.experimental_faster,
105
+ faster: props.siteConfig.future.faster,
106
106
  poll,
107
107
  configureWebpackUtils,
108
108
  });
@@ -10,7 +10,6 @@ exports.swizzle = swizzle;
10
10
  const tslib_1 = require("tslib");
11
11
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
12
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
13
- const utils_1 = require("@docusaurus/utils");
14
13
  const themes_1 = require("./themes");
15
14
  const components_1 = require("./components");
16
15
  const tables_1 = require("./tables");
@@ -33,7 +32,7 @@ async function getLanguageForThemeName({ themeName, plugins, options, }) {
33
32
  }
34
33
  // It's only useful to prompt the user for themes that support both JS/TS
35
34
  if (supportsTS) {
36
- return (0, utils_1.askPreferredLanguage)({ exit: true });
35
+ return (0, prompts_1.askSwizzlePreferredLanguage)();
37
36
  }
38
37
  return 'javascript';
39
38
  }
@@ -10,3 +10,4 @@ export declare function askThemeName(themeNames: string[]): Promise<string>;
10
10
  export declare function askComponentName(themeComponents: ThemeComponents): Promise<string>;
11
11
  export declare function askSwizzleDangerousComponent(): Promise<boolean>;
12
12
  export declare function askSwizzleAction(componentConfig: SwizzleComponentConfig): Promise<SwizzleAction>;
13
+ export declare function askSwizzlePreferredLanguage(): Promise<'javascript' | 'typescript'>;
@@ -10,6 +10,7 @@ exports.askThemeName = askThemeName;
10
10
  exports.askComponentName = askComponentName;
11
11
  exports.askSwizzleDangerousComponent = askSwizzleDangerousComponent;
12
12
  exports.askSwizzleAction = askSwizzleAction;
13
+ exports.askSwizzlePreferredLanguage = askSwizzlePreferredLanguage;
13
14
  const tslib_1 = require("tslib");
14
15
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
15
16
  const prompts_1 = tslib_1.__importDefault(require("prompts"));
@@ -107,3 +108,24 @@ async function askSwizzleAction(componentConfig) {
107
108
  }
108
109
  return action;
109
110
  }
111
+ async function askSwizzlePreferredLanguage() {
112
+ const choices = [
113
+ { title: logger_1.default.bold('JavaScript'), value: 'javascript' },
114
+ { title: logger_1.default.bold('TypeScript'), value: 'typescript' },
115
+ { title: logger_1.default.yellow('[Exit]'), value: '[Exit]' },
116
+ ];
117
+ const { language } = await (0, prompts_1.default)({
118
+ type: 'select',
119
+ name: 'language',
120
+ message: 'Which language do you want to use?',
121
+ choices,
122
+ }, {
123
+ onCancel() {
124
+ process.exit(0);
125
+ },
126
+ });
127
+ if (typeof language === 'undefined' || language === '[Exit]') {
128
+ process.exit(0);
129
+ }
130
+ return language;
131
+ }
@@ -69,6 +69,9 @@ async function tryOpenWithAppleScript({ url, browser, }) {
69
69
  // We open Google Chrome Canary in priority over Google Chrome
70
70
  return supportedChromiumBrowsers.filter((b) => activeBrowsers.includes(b));
71
71
  }
72
+ // Test this manually with:
73
+ // osascript ./packages/docusaurus/src/commands/utils/openBrowser/openChrome.applescript "http://localhost:8080" "Google Chrome"
74
+ // osascript ./packages/docusaurus/src/commands/utils/openBrowser/openChrome.applescript "http://localhost:8080" "Arc"
72
75
  async function tryBrowser(browserName) {
73
76
  try {
74
77
  // This command runs the openChrome.applescript (copied from CRA)
@@ -19,6 +19,16 @@ on run argv
19
19
  set theProgram to item 2 of argv
20
20
  end if
21
21
 
22
+ -- Arc: simple open + activate, no tab reuse
23
+ -- See https://github.com/facebook/docusaurus/issues/11582
24
+ if theProgram is "Arc" then
25
+ tell application "Arc"
26
+ activate
27
+ open location theURL
28
+ end tell
29
+ return
30
+ end if
31
+
22
32
  using terms from application "Google Chrome"
23
33
  tell application theProgram
24
34
 
@@ -13,9 +13,25 @@ const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
13
13
  const utils_1 = require("@docusaurus/utils");
14
14
  const site_1 = require("../server/site");
15
15
  const init_1 = require("../server/plugins/init");
16
+ function inferFallbackSyntax(_filepath) {
17
+ // TODO Docusaurus v4 - infer the syntax based on the file extensions?
18
+ // This is not ideal because we have many ways to define the syntax
19
+ // (front matter "format", siteConfig.markdown.format etc...)
20
+ // but probably good enough for now
21
+ // Until then, we default to the classic syntax
22
+ // The mdx-comment syntax is opt-in
23
+ return 'classic';
24
+ }
25
+ function getHeadingIdSyntax(filepath, options) {
26
+ return options?.syntax ?? inferFallbackSyntax(filepath);
27
+ }
16
28
  async function transformMarkdownFile(filepath, options) {
17
29
  const content = await fs_extra_1.default.readFile(filepath, 'utf8');
18
- const updatedContent = (0, utils_1.writeMarkdownHeadingId)(content, options);
30
+ const syntax = getHeadingIdSyntax(filepath, options);
31
+ const updatedContent = (0, utils_1.writeMarkdownHeadingId)(content, {
32
+ ...options,
33
+ syntax,
34
+ });
19
35
  if (content !== updatedContent) {
20
36
  await fs_extra_1.default.writeFile(filepath, updatedContent);
21
37
  return filepath;
@@ -33,17 +49,35 @@ async function getPathsToWatch(siteDir) {
33
49
  const plugins = await (0, init_1.initPlugins)(context);
34
50
  return plugins.flatMap((plugin) => plugin.getPathsToWatch?.() ?? []);
35
51
  }
52
+ // TODO Docusaurus v4 - Upgrade commander, use choices() API?
53
+ function validateOptions(options) {
54
+ const validSyntaxValues = ['classic', 'mdx-comment'];
55
+ if (options.syntax && !validSyntaxValues.includes(options.syntax)) {
56
+ throw new Error(`Invalid --syntax value "${options.syntax}". Valid values: ${validSyntaxValues.join(', ')}`);
57
+ }
58
+ if (options.overwrite && options.migrate) {
59
+ throw new Error("Options --overwrite and --migrate cannot be used together.\nThe --overwrite already re-generates IDs in the target syntax, so the --migrate option wouldn't have any effect.");
60
+ }
61
+ }
36
62
  async function writeHeadingIds(siteDirParam = '.', files = [], options = {}) {
63
+ validateOptions(options);
37
64
  const siteDir = await fs_extra_1.default.realpath(siteDirParam);
38
- const markdownFiles = await (0, utils_1.safeGlobby)(files ?? (await getPathsToWatch(siteDir)), {
65
+ const patterns = files.length ? files : await getPathsToWatch(siteDir);
66
+ const markdownFiles = await (0, utils_1.safeGlobby)(patterns, {
39
67
  expandDirectories: ['**/*.{md,mdx}'],
40
68
  });
69
+ if (markdownFiles.length === 0) {
70
+ logger_1.default.warn `No markdown files found in siteDir path=${siteDir} for patterns: ${patterns}`;
71
+ return;
72
+ }
41
73
  const result = await Promise.all(markdownFiles.map((p) => transformMarkdownFile(p, options)));
42
74
  const pathsModified = result.filter(Boolean);
43
75
  if (pathsModified.length) {
44
76
  logger_1.default.success `Heading ids added to Markdown files (number=${`${pathsModified.length}/${markdownFiles.length}`} files): ${pathsModified}`;
45
77
  }
46
78
  else {
47
- logger_1.default.warn `number=${markdownFiles.length} Markdown files already have explicit heading IDs. If you intend to overwrite the existing heading IDs, use the code=${'--overwrite'} option.`;
79
+ logger_1.default.warn `number=${markdownFiles.length} Markdown files already have explicit heading IDs.
80
+ If you intend to overwrite the existing heading IDs, use the code=${'--overwrite'} option.
81
+ If you intend to change their heading ID syntax, use the code=${'--migrate'} option.`;
48
82
  }
49
83
  }
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import { Joi } from '@docusaurus/utils-validation';
8
- import type { FasterConfig, FutureConfig, FutureV4Config, StorageConfig, DocusaurusConfig, I18nConfig, MarkdownConfig, MarkdownHooks } from '@docusaurus/types';
8
+ import type { DocusaurusConfig, FasterConfig, FutureConfig, FutureV4Config, I18nConfig, MarkdownConfig, MarkdownHooks, StorageConfig } from '@docusaurus/types';
9
9
  export declare const DEFAULT_I18N_CONFIG: I18nConfig;
10
10
  export declare const DEFAULT_STORAGE_CONFIG: StorageConfig;
11
11
  export declare const DEFAULT_FASTER_CONFIG: FasterConfig;
@@ -15,6 +15,6 @@ export declare const DEFAULT_FUTURE_V4_CONFIG_TRUE: FutureV4Config;
15
15
  export declare const DEFAULT_FUTURE_CONFIG: FutureConfig;
16
16
  export declare const DEFAULT_MARKDOWN_HOOKS: MarkdownHooks;
17
17
  export declare const DEFAULT_MARKDOWN_CONFIG: MarkdownConfig;
18
- export declare const DEFAULT_CONFIG: Pick<DocusaurusConfig, 'i18n' | 'future' | 'onBrokenLinks' | 'onBrokenAnchors' | 'onBrokenMarkdownLinks' | 'onDuplicateRoutes' | 'plugins' | 'themes' | 'presets' | 'headTags' | 'stylesheets' | 'scripts' | 'clientModules' | 'customFields' | 'themeConfig' | 'titleDelimiter' | 'noIndex' | 'tagline' | 'baseUrlIssueBanner' | 'staticDirectories' | 'markdown'>;
18
+ export declare const DEFAULT_CONFIG: Pick<DocusaurusConfig, 'i18n' | 'storage' | 'future' | 'onBrokenLinks' | 'onBrokenAnchors' | 'onBrokenMarkdownLinks' | 'onDuplicateRoutes' | 'plugins' | 'themes' | 'presets' | 'headTags' | 'stylesheets' | 'scripts' | 'clientModules' | 'customFields' | 'themeConfig' | 'titleDelimiter' | 'noIndex' | 'tagline' | 'baseUrlIssueBanner' | 'staticDirectories' | 'markdown'>;
19
19
  export declare const ConfigSchema: Joi.ObjectSchema<DocusaurusConfig>;
20
20
  export declare function validateConfig(config: unknown, siteConfigPath: string): DocusaurusConfig;
@@ -55,6 +55,7 @@ exports.DEFAULT_FASTER_CONFIG = {
55
55
  rspackBundler: false,
56
56
  rspackPersistentCache: false,
57
57
  ssgWorkerThreads: false,
58
+ gitEagerVcs: false,
58
59
  };
59
60
  // When using the "faster: true" shortcut
60
61
  exports.DEFAULT_FASTER_CONFIG_TRUE = {
@@ -66,20 +67,25 @@ exports.DEFAULT_FASTER_CONFIG_TRUE = {
66
67
  rspackBundler: true,
67
68
  rspackPersistentCache: true,
68
69
  ssgWorkerThreads: true,
70
+ gitEagerVcs: true,
69
71
  };
70
72
  exports.DEFAULT_FUTURE_V4_CONFIG = {
71
73
  removeLegacyPostBuildHeadAttribute: false,
72
74
  useCssCascadeLayers: false,
75
+ siteStorageNamespacing: false,
76
+ fasterByDefault: false,
73
77
  };
74
78
  // When using the "v4: true" shortcut
75
79
  exports.DEFAULT_FUTURE_V4_CONFIG_TRUE = {
76
80
  removeLegacyPostBuildHeadAttribute: true,
77
81
  useCssCascadeLayers: true,
82
+ siteStorageNamespacing: true,
83
+ fasterByDefault: true,
78
84
  };
79
85
  exports.DEFAULT_FUTURE_CONFIG = {
80
86
  v4: exports.DEFAULT_FUTURE_V4_CONFIG,
81
- experimental_faster: exports.DEFAULT_FASTER_CONFIG,
82
- experimental_storage: exports.DEFAULT_STORAGE_CONFIG,
87
+ faster: exports.DEFAULT_FASTER_CONFIG,
88
+ experimental_vcs: (0, utils_1.getVcsPreset)('default-v1'),
83
89
  experimental_router: 'browser',
84
90
  };
85
91
  exports.DEFAULT_MARKDOWN_HOOKS = {
@@ -105,6 +111,7 @@ exports.DEFAULT_MARKDOWN_CONFIG = {
105
111
  };
106
112
  exports.DEFAULT_CONFIG = {
107
113
  i18n: exports.DEFAULT_I18N_CONFIG,
114
+ storage: exports.DEFAULT_STORAGE_CONFIG,
108
115
  future: exports.DEFAULT_FUTURE_CONFIG,
109
116
  onBrokenLinks: 'throw',
110
117
  onBrokenAnchors: 'warn', // TODO Docusaurus v4: change to throw
@@ -180,6 +187,7 @@ const LocaleConfigSchema = utils_validation_1.Joi.object({
180
187
  direction: utils_validation_1.Joi.string().equal('ltr', 'rtl'),
181
188
  calendar: utils_validation_1.Joi.string(),
182
189
  path: utils_validation_1.Joi.string(),
190
+ translate: utils_validation_1.Joi.boolean(),
183
191
  url: SiteUrlSchema,
184
192
  baseUrl: BaseUrlSchema,
185
193
  });
@@ -193,25 +201,30 @@ const I18N_CONFIG_SCHEMA = utils_validation_1.Joi.object({
193
201
  })
194
202
  .optional()
195
203
  .default(exports.DEFAULT_I18N_CONFIG);
204
+ // Individual boolean defaults are not set here on purpose
205
+ // They are resolved in postProcessDocusaurusConfig based on
206
+ // the future.v4.fasterByDefault flag
196
207
  const FASTER_CONFIG_SCHEMA = utils_validation_1.Joi.alternatives()
197
208
  .try(utils_validation_1.Joi.object({
198
- swcJsLoader: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FASTER_CONFIG.swcJsLoader),
199
- swcJsMinimizer: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FASTER_CONFIG.swcJsMinimizer),
200
- swcHtmlMinimizer: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FASTER_CONFIG.swcHtmlMinimizer),
201
- lightningCssMinimizer: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FASTER_CONFIG.lightningCssMinimizer),
202
- mdxCrossCompilerCache: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FASTER_CONFIG.mdxCrossCompilerCache),
203
- rspackBundler: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FASTER_CONFIG.rspackBundler),
204
- rspackPersistentCache: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FASTER_CONFIG.rspackPersistentCache),
205
- ssgWorkerThreads: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FASTER_CONFIG.ssgWorkerThreads),
209
+ swcJsLoader: utils_validation_1.Joi.boolean(),
210
+ swcJsMinimizer: utils_validation_1.Joi.boolean(),
211
+ swcHtmlMinimizer: utils_validation_1.Joi.boolean(),
212
+ lightningCssMinimizer: utils_validation_1.Joi.boolean(),
213
+ mdxCrossCompilerCache: utils_validation_1.Joi.boolean(),
214
+ rspackBundler: utils_validation_1.Joi.boolean(),
215
+ rspackPersistentCache: utils_validation_1.Joi.boolean(),
216
+ ssgWorkerThreads: utils_validation_1.Joi.boolean(),
217
+ gitEagerVcs: utils_validation_1.Joi.boolean(),
206
218
  }), utils_validation_1.Joi.boolean()
207
219
  .required()
208
220
  .custom((bool) => bool ? exports.DEFAULT_FASTER_CONFIG_TRUE : exports.DEFAULT_FASTER_CONFIG))
209
- .optional()
210
- .default(exports.DEFAULT_FASTER_CONFIG);
221
+ .optional();
211
222
  const FUTURE_V4_SCHEMA = utils_validation_1.Joi.alternatives()
212
223
  .try(utils_validation_1.Joi.object({
213
224
  removeLegacyPostBuildHeadAttribute: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FUTURE_V4_CONFIG.removeLegacyPostBuildHeadAttribute),
214
225
  useCssCascadeLayers: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FUTURE_V4_CONFIG.useCssCascadeLayers),
226
+ siteStorageNamespacing: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FUTURE_V4_CONFIG.siteStorageNamespacing),
227
+ fasterByDefault: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FUTURE_V4_CONFIG.fasterByDefault),
215
228
  }), utils_validation_1.Joi.boolean()
216
229
  .required()
217
230
  .custom((bool) => bool ? exports.DEFAULT_FUTURE_V4_CONFIG_TRUE : exports.DEFAULT_FUTURE_V4_CONFIG))
@@ -221,19 +234,58 @@ const STORAGE_CONFIG_SCHEMA = utils_validation_1.Joi.object({
221
234
  type: utils_validation_1.Joi.string()
222
235
  .equal('localStorage', 'sessionStorage')
223
236
  .default(exports.DEFAULT_STORAGE_CONFIG.type),
224
- namespace: utils_validation_1.Joi.alternatives()
225
- .try(utils_validation_1.Joi.string(), utils_validation_1.Joi.boolean())
226
- .default(exports.DEFAULT_STORAGE_CONFIG.namespace),
237
+ // namespace default is not set here on purpose
238
+ // It is resolved in postProcessDocusaurusConfig based on
239
+ // the future.v4.siteStorageNamespacing flag
240
+ namespace: utils_validation_1.Joi.alternatives().try(utils_validation_1.Joi.string(), utils_validation_1.Joi.boolean()),
227
241
  })
228
242
  .optional()
229
- .default(exports.DEFAULT_STORAGE_CONFIG);
243
+ .default({ type: exports.DEFAULT_STORAGE_CONFIG.type });
244
+ const VCS_CONFIG_OBJECT_SCHEMA = utils_validation_1.Joi.object({
245
+ // All the fields are required on purpose
246
+ // You either provide a full VCS config or nothing
247
+ initialize: utils_validation_1.Joi.function().maxArity(1).required(),
248
+ getFileCreationInfo: utils_validation_1.Joi.function().arity(1).required(),
249
+ getFileLastUpdateInfo: utils_validation_1.Joi.function().arity(1).required(),
250
+ });
251
+ const VCS_CONFIG_SCHEMA = utils_validation_1.Joi.custom((input) => {
252
+ if (typeof input === 'string') {
253
+ const presetName = input;
254
+ if (!utils_1.VcsPresetNames.includes(presetName)) {
255
+ throw new Error(`VCS config preset name '${input}' is not valid.`);
256
+ }
257
+ return (0, utils_1.getVcsPreset)(presetName);
258
+ }
259
+ if (typeof input === 'boolean') {
260
+ // We return the boolean on purpose
261
+ // We'll normalize it to a real VcsConfig later
262
+ // This is annoying, but we have to read the future flag to switch to the
263
+ // new "default-v2" config (not easy to do it here)
264
+ return input;
265
+ }
266
+ const { error, value } = VCS_CONFIG_OBJECT_SCHEMA.validate(input);
267
+ if (error) {
268
+ throw error;
269
+ }
270
+ return value;
271
+ }).default(true);
230
272
  const FUTURE_CONFIG_SCHEMA = utils_validation_1.Joi.object({
231
273
  v4: FUTURE_V4_SCHEMA,
232
- experimental_faster: FASTER_CONFIG_SCHEMA,
233
- experimental_storage: STORAGE_CONFIG_SCHEMA,
274
+ faster: FASTER_CONFIG_SCHEMA,
275
+ experimental_vcs: VCS_CONFIG_SCHEMA,
234
276
  experimental_router: utils_validation_1.Joi.string()
235
277
  .equal('browser', 'hash')
236
278
  .default(exports.DEFAULT_FUTURE_CONFIG.experimental_router),
279
+ experimental_storage: utils_validation_1.Joi.any()
280
+ .forbidden()
281
+ .messages({
282
+ 'any.unknown': `The Docusaurus config ${logger_1.default.code('future.experimental_storage')} has been promoted to a stable top-level ${logger_1.default.code('storage')} config attribute. Please move your storage config to the top level.`,
283
+ }),
284
+ experimental_faster: utils_validation_1.Joi.any()
285
+ .forbidden()
286
+ .messages({
287
+ 'any.unknown': `The Docusaurus config ${logger_1.default.code('future.experimental_faster')} has been renamed to ${logger_1.default.code('future.faster')}. Please update your Docusaurus config.`,
288
+ }),
237
289
  })
238
290
  .optional()
239
291
  .default(exports.DEFAULT_FUTURE_CONFIG);
@@ -246,6 +298,7 @@ exports.ConfigSchema = utils_validation_1.Joi.object({
246
298
  title: utils_validation_1.Joi.string().required(),
247
299
  trailingSlash: utils_validation_1.Joi.boolean(), // No default value! undefined = retrocompatible legacy behavior!
248
300
  i18n: I18N_CONFIG_SCHEMA,
301
+ storage: STORAGE_CONFIG_SCHEMA,
249
302
  future: FUTURE_CONFIG_SCHEMA,
250
303
  onBrokenLinks: utils_validation_1.Joi.string()
251
304
  .equal('ignore', 'log', 'warn', 'throw')
@@ -288,9 +341,14 @@ exports.ConfigSchema = utils_validation_1.Joi.object({
288
341
  headTags: utils_validation_1.Joi.array()
289
342
  .items(utils_validation_1.Joi.object({
290
343
  tagName: utils_validation_1.Joi.string().required(),
291
- attributes: utils_validation_1.Joi.object()
292
- .pattern(/[\w-]+/, utils_validation_1.Joi.string())
293
- .required(),
344
+ attributes: utils_validation_1.Joi.object().when('customElement', {
345
+ is: utils_validation_1.Joi.valid(true),
346
+ then: utils_validation_1.Joi.optional(),
347
+ otherwise: utils_validation_1.Joi.object()
348
+ .pattern(/[\w-]+/, utils_validation_1.Joi.string())
349
+ .required(),
350
+ }),
351
+ customElement: utils_validation_1.Joi.bool().default(false),
294
352
  }).unknown())
295
353
  .messages({
296
354
  'array.includes': '{#label} is invalid. A headTag must be an object with at least a "tagName" and an "attributes" property.',
@@ -355,6 +413,41 @@ exports.ConfigSchema = utils_validation_1.Joi.object({
355
413
  // Expressing this kind of logic in Joi is a pain
356
414
  // We also want to decouple logic from Joi: easier to remove it later!
357
415
  function postProcessDocusaurusConfig(config) {
416
+ // Resolve storage.namespace based on the v4 future flag
417
+ // undefined means "not explicitly set by user"
418
+ if (config.storage.namespace === undefined) {
419
+ config.storage.namespace = config.future.v4.siteStorageNamespacing;
420
+ }
421
+ // Resolve faster config based on the v4.fasterByDefault flag
422
+ // undefined means "not explicitly set by user"
423
+ if (config.future.faster === undefined) {
424
+ config.future.faster = {};
425
+ }
426
+ const fasterDefault = config.future.v4.fasterByDefault;
427
+ const fasterKeys = Object.keys(exports.DEFAULT_FASTER_CONFIG);
428
+ for (const key of fasterKeys) {
429
+ if (config.future.faster[key] === undefined) {
430
+ config.future.faster[key] = fasterDefault;
431
+ }
432
+ }
433
+ // Docusaurus Faster doesn't fully support Yarn PnP :s
434
+ // Until we support Rspack + PnP, we simply revert to Webpack with a warning
435
+ // See https://github.com/facebook/docusaurus/issues/10787
436
+ if (process.versions.pnp) {
437
+ if (config.future.faster.rspackBundler) {
438
+ logger_1.default.warn(`Docusaurus Faster doesn't fully support the Yarn PnP linker yet.
439
+ We recommend to use Yarn node-linker instead.
440
+ Docusaurus will still attempt to build your app with Webpack (instead of Rspack) and use slower minimizers.
441
+ See also https://github.com/facebook/docusaurus/issues/10787`);
442
+ config.future.faster.rspackBundler = false;
443
+ config.future.faster.rspackPersistentCache = false;
444
+ // This also won't work due to Webpack libs using peerDependencies :s
445
+ // This could eventually work if the deps are added at the site level
446
+ // TODO Docusaurus v4 clean this up
447
+ config.future.faster.lightningCssMinimizer = false;
448
+ config.future.faster.swcJsMinimizer = false;
449
+ }
450
+ }
358
451
  if (config.onBrokenMarkdownLinks) {
359
452
  logger_1.default.warn `The code=${'siteConfig.onBrokenMarkdownLinks'} config option is deprecated and will be removed in Docusaurus v4.
360
453
  Please migrate and move this option to code=${'siteConfig.markdown.hooks.onBrokenMarkdownLinks'} instead.`;
@@ -363,15 +456,24 @@ Please migrate and move this option to code=${'siteConfig.markdown.hooks.onBroke
363
456
  // We erase the former one to ensure we don't use it anywhere
364
457
  config.onBrokenMarkdownLinks = undefined;
365
458
  }
366
- if (config.future.experimental_faster.ssgWorkerThreads &&
459
+ // We normalize the VCS config when using a boolean value
460
+ if (typeof config.future.experimental_vcs === 'boolean') {
461
+ const vcsConfig = config.future.experimental_vcs
462
+ ? config.future.faster.gitEagerVcs
463
+ ? (0, utils_1.getVcsPreset)('default-v2')
464
+ : (0, utils_1.getVcsPreset)('default-v1')
465
+ : (0, utils_1.getVcsPreset)('disabled');
466
+ config.future.experimental_vcs = vcsConfig;
467
+ }
468
+ if (config.future.faster.ssgWorkerThreads &&
367
469
  !config.future.v4.removeLegacyPostBuildHeadAttribute) {
368
- throw new Error(`Docusaurus config ${logger_1.default.code('future.experimental_faster.ssgWorkerThreads')} requires the future flag ${logger_1.default.code('future.v4.removeLegacyPostBuildHeadAttribute')} to be turned on.
470
+ throw new Error(`Docusaurus config ${logger_1.default.code('future.faster.ssgWorkerThreads')} requires the future flag ${logger_1.default.code('future.v4.removeLegacyPostBuildHeadAttribute')} to be turned on.
369
471
  If you use Docusaurus Faster, we recommend that you also activate Docusaurus v4 future flags: ${logger_1.default.code('{future: {v4: true}}')}
370
472
  All the v4 future flags are documented here: https://docusaurus.io/docs/api/docusaurus-config#future`);
371
473
  }
372
- if (config.future.experimental_faster.rspackPersistentCache &&
373
- !config.future.experimental_faster.rspackBundler) {
374
- throw new Error(`Docusaurus config flag ${logger_1.default.code('future.experimental_faster.rspackPersistentCache')} requires the flag ${logger_1.default.code('future.experimental_faster.rspackBundler')} to be turned on.`);
474
+ if (config.future.faster.rspackPersistentCache &&
475
+ !config.future.faster.rspackBundler) {
476
+ throw new Error(`Docusaurus config flag ${logger_1.default.code('future.faster.rspackPersistentCache')} requires the flag ${logger_1.default.code('future.faster.rspackBundler')} to be turned on.`);
375
477
  }
376
478
  }
377
479
  // TODO move to @docusaurus/utils-validation
@@ -12,15 +12,18 @@ const lodash_1 = tslib_1.__importDefault(require("lodash"));
12
12
  const html_tags_1 = tslib_1.__importDefault(require("html-tags"));
13
13
  const void_1 = tslib_1.__importDefault(require("html-tags/void"));
14
14
  const escape_html_1 = tslib_1.__importDefault(require("escape-html"));
15
+ // TODO this should be done at config validation time, not here
15
16
  function assertIsHtmlTagObject(val) {
16
17
  if (typeof val !== 'object' || !val) {
17
18
  throw new Error(`"${val}" is not a valid HTML tag object.`);
18
19
  }
19
- if (typeof val.tagName !== 'string') {
20
+ const htmlTag = val;
21
+ if (typeof htmlTag.tagName !== 'string') {
20
22
  throw new Error(`${JSON.stringify(val)} is not a valid HTML tag object. "tagName" must be defined as a string.`);
21
23
  }
22
- if (!html_tags_1.default.includes(val.tagName)) {
23
- throw new Error(`Error loading ${JSON.stringify(val)}, "${val.tagName}" is not a valid HTML tag.`);
24
+ if (!htmlTag.customElement &&
25
+ !html_tags_1.default.includes(htmlTag.tagName)) {
26
+ throw new Error(`Error loading ${JSON.stringify(val)}, "${htmlTag.tagName}" is not a valid HTML tag. Either use a valid "tagName" or set "customElement: true".`);
24
27
  }
25
28
  }
26
29
  function hashRouterAbsoluteToRelativeTagAttribute(name, value) {
@@ -4,8 +4,12 @@
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 { I18n, DocusaurusConfig, I18nLocaleConfig } from '@docusaurus/types';
7
+ import type { I18n, DocusaurusConfig, I18nLocaleConfig, I18nConfig } from '@docusaurus/types';
8
8
  export declare function getDefaultLocaleConfig(locale: string): Omit<I18nLocaleConfig, 'translate' | 'url' | 'baseUrl'>;
9
+ export declare function getLocaleList({ i18nConfig, currentLocale, }: {
10
+ i18nConfig: I18nConfig;
11
+ currentLocale: string;
12
+ }): [string, ...string[]];
9
13
  export declare function loadI18n({ siteDir, config, currentLocale, automaticBaseUrlLocalizationDisabled, }: {
10
14
  siteDir: string;
11
15
  config: DocusaurusConfig;
@@ -7,6 +7,7 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.getDefaultLocaleConfig = getDefaultLocaleConfig;
10
+ exports.getLocaleList = getLocaleList;
10
11
  exports.loadI18n = loadI18n;
11
12
  const tslib_1 = require("tslib");
12
13
  const path_1 = tslib_1.__importDefault(require("path"));
@@ -82,22 +83,29 @@ function getDefaultLocaleConfig(locale) {
82
83
  };
83
84
  }
84
85
  catch (e) {
85
- throw new Error(`Docusaurus couldn't get default locale config for ${locale}`, { cause: e });
86
+ throw new Error(`Docusaurus couldn't infer a default locale config for ${logger_1.default.name(locale)}.
87
+ Make sure it is a valid BCP 47 locale name (e.g. en, fr, fr-FR, etc.) and/or provide a valid BCP 47 ${logger_1.default.code(`siteConfig.i18n.localeConfig['${locale}'].htmlLang`)} attribute.`, { cause: e });
86
88
  }
87
89
  }
88
- async function loadI18n({ siteDir, config, currentLocale, automaticBaseUrlLocalizationDisabled, }) {
89
- const { i18n: i18nConfig } = config;
90
+ function getLocaleList({ i18nConfig, currentLocale, }) {
90
91
  if (!i18nConfig.locales.includes(currentLocale)) {
91
- logger_1.default.warn `The locale name=${currentLocale} was not found in your site configuration: Available locales are: ${i18nConfig.locales}
92
- Note: Docusaurus only support running one locale at a time.`;
92
+ logger_1.default.warn `The locale name=${currentLocale} was not found in your Docusaurus site configuration.
93
+ We recommend adding the name=${currentLocale} to your site i18n config, but we will still try to run your site.
94
+ Declared site config locales are: ${i18nConfig.locales}`;
95
+ return i18nConfig.locales.concat(currentLocale);
93
96
  }
94
- const locales = i18nConfig.locales.includes(currentLocale)
95
- ? i18nConfig.locales
96
- : i18nConfig.locales.concat(currentLocale);
97
+ return i18nConfig.locales;
98
+ }
99
+ async function loadI18n({ siteDir, config, currentLocale, automaticBaseUrlLocalizationDisabled, }) {
100
+ const { i18n: i18nConfig } = config;
101
+ const locales = getLocaleList({
102
+ i18nConfig,
103
+ currentLocale,
104
+ });
97
105
  async function getFullLocaleConfig(locale) {
98
106
  const localeConfigInput = i18nConfig.localeConfigs[locale] ?? {};
99
107
  const localeConfig = {
100
- ...getDefaultLocaleConfig(locale),
108
+ ...getDefaultLocaleConfig(localeConfigInput.htmlLang ?? locale),
101
109
  ...localeConfigInput,
102
110
  };
103
111
  // By default, translations will be enabled if i18n/<locale> dir exists
@@ -60,7 +60,7 @@ function createBootstrapPlugin({ siteDir, siteConfig, }) {
60
60
  */
61
61
  async function createMDXFallbackPlugin({ siteDir, siteConfig, }) {
62
62
  const mdxLoaderItem = await (0, mdx_loader_1.createMDXLoaderItem)({
63
- useCrossCompilerCache: siteConfig.future.experimental_faster.mdxCrossCompilerCache,
63
+ useCrossCompilerCache: siteConfig.future.faster.mdxCrossCompilerCache,
64
64
  admonitions: true,
65
65
  staticDirs: siteConfig.staticDirectories.map((dir) => path_1.default.resolve(siteDir, dir)),
66
66
  siteDir,
@@ -43,6 +43,14 @@ async function loadContext(params) {
43
43
  customConfigFilePath,
44
44
  }),
45
45
  });
46
+ // Not sure where is the best place to put this VCS initialization call?
47
+ // The sooner is probably the better
48
+ // Note: we don't await the result on purpose!
49
+ // VCS initialization can be slow for large repos, and we don't want to block
50
+ // VCS integrations should be carefully designed to avoid blocking
51
+ logger_1.PerfLogger.async('VCS init', () => {
52
+ return initialSiteConfig.future.experimental_vcs.initialize({ siteDir });
53
+ });
46
54
  const currentBundler = await (0, bundler_1.getCurrentBundler)({
47
55
  siteConfig: initialSiteConfig,
48
56
  });
@@ -15,7 +15,7 @@ const babel_1 = require("@docusaurus/babel");
15
15
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
16
16
  const uselessBabelConfigMessages = async ({ site }) => {
17
17
  const { props: { siteDir, siteConfig }, } = site;
18
- if (siteConfig.future.experimental_faster.swcJsLoader) {
18
+ if (siteConfig.future.faster.swcJsLoader) {
19
19
  const babelConfigFilePath = await (0, babel_1.getCustomBabelConfigFilePath)(siteDir);
20
20
  if (babelConfigFilePath) {
21
21
  return [
@@ -5,9 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { DocusaurusConfig, SiteStorage } from '@docusaurus/types';
8
- type PartialFuture = Pick<DocusaurusConfig['future'], 'experimental_storage'>;
9
- type PartialConfig = Pick<DocusaurusConfig, 'url' | 'baseUrl'> & {
10
- future: PartialFuture;
11
- };
8
+ type PartialConfig = Pick<DocusaurusConfig, 'url' | 'baseUrl' | 'storage'>;
12
9
  export declare function createSiteStorage(config: PartialConfig): SiteStorage;
13
10
  export {};
@@ -14,18 +14,18 @@ function automaticNamespace(config) {
14
14
  return (0, utils_1.simpleHash)(normalizedUrl, 3);
15
15
  }
16
16
  function getNamespaceString(config) {
17
- if (config.future.experimental_storage.namespace === true) {
17
+ if (config.storage.namespace === true) {
18
18
  return automaticNamespace(config);
19
19
  }
20
- else if (config.future.experimental_storage.namespace === false) {
20
+ else if (config.storage.namespace === false) {
21
21
  return null;
22
22
  }
23
23
  else {
24
- return config.future.experimental_storage.namespace;
24
+ return config.storage.namespace;
25
25
  }
26
26
  }
27
27
  function createSiteStorage(config) {
28
- const { type } = config.future.experimental_storage;
28
+ const { type } = config.storage;
29
29
  const namespaceString = getNamespaceString(config);
30
30
  const namespace = namespaceString ? `-${namespaceString}` : '';
31
31
  return {
@@ -136,8 +136,7 @@ async function executeSSG({ props, serverBundlePath, clientManifestPath, router,
136
136
  logger_1.PerfLogger.end('Generate Hash Router entry point');
137
137
  return { collectedData: {} };
138
138
  }
139
- const createExecutor = props.siteConfig.future.experimental_faster
140
- .ssgWorkerThreads
139
+ const createExecutor = props.siteConfig.future.faster.ssgWorkerThreads
141
140
  ? createPooledSSGExecutor
142
141
  : createSimpleSSGExecutor;
143
142
  const executor = await createExecutor({ params, pathnames: props.routesPaths });
@@ -26,8 +26,7 @@ async function createSSGParams({ props, serverBundlePath, clientManifestPath, })
26
26
  noIndex: props.siteConfig.noIndex,
27
27
  DOCUSAURUS_VERSION: utils_1.DOCUSAURUS_VERSION,
28
28
  serverBundlePath,
29
- htmlMinifierType: props.siteConfig.future.experimental_faster
30
- .swcHtmlMinimizer
29
+ htmlMinifierType: props.siteConfig.future.faster.swcHtmlMinimizer
31
30
  ? 'swc'
32
31
  : 'terser',
33
32
  v4RemoveLegacyPostBuildHeadAttribute: props.siteConfig.future.v4.removeLegacyPostBuildHeadAttribute,
@@ -39,6 +39,13 @@ async function createAliasesForTheme(themePath, addOriginalAlias) {
39
39
  }
40
40
  const themeComponentFiles = await (0, utils_1.Globby)(['**/*.{js,jsx,ts,tsx}'], {
41
41
  cwd: themePath,
42
+ ignore: [
43
+ // Ignore co-located test files
44
+ '**/__tests__/**',
45
+ '**/*.test.{js,jsx,ts,tsx}',
46
+ // Ignore type declaration files
47
+ '**/*.d.ts',
48
+ ],
42
49
  });
43
50
  const aliases = {};
44
51
  themeComponentFiles.forEach((relativeSource) => {
@@ -86,7 +86,7 @@ async function createBaseConfig({ props, isServer, minify, faster, configureWebp
86
86
  return disabledPersistentCacheValue;
87
87
  }
88
88
  if (props.currentBundler.name === 'rspack') {
89
- if (props.siteConfig.future.experimental_faster.rspackPersistentCache) {
89
+ if (props.siteConfig.future.faster.rspackPersistentCache) {
90
90
  // Use cache: true + experiments.cache.type: "persistent"
91
91
  // See https://rspack.dev/config/experiments#persistent-cache
92
92
  return true;
@@ -118,24 +118,6 @@ async function createBaseConfig({ props, isServer, minify, faster, configureWebp
118
118
  buildDependencies: getCacheBuildDependencies(),
119
119
  };
120
120
  }
121
- if (process.env.DISABLE_RSPACK_INCREMENTAL) {
122
- // Enabled by default since Rspack 1.4
123
- console.log('Rspack incremental disabled');
124
- experiments.incremental = false;
125
- }
126
- // See https://rspack.rs/blog/announcing-1-5#barrel-file-optimization
127
- if (process.env.DISABLE_RSPACK_LAZY_BARREL) {
128
- console.log('Rspack lazyBarrel disabled');
129
- experiments.lazyBarrel = false;
130
- }
131
- else {
132
- // TODO remove after we upgrade to Rspack 1.6+
133
- // Enabled by default for Rspack >= 1.6
134
- experiments.lazyBarrel = true;
135
- }
136
- // TODO re-enable later, there's an Rspack performance issue
137
- // see https://github.com/facebook/docusaurus/pull/11178
138
- experiments.parallelCodeSplitting = false;
139
121
  return experiments;
140
122
  }
141
123
  return undefined;
@@ -18,7 +18,7 @@ async function createServerConfig({ props, configureWebpackUtils, }) {
18
18
  props,
19
19
  isServer: true,
20
20
  minify: false,
21
- faster: props.siteConfig.future.experimental_faster,
21
+ faster: props.siteConfig.future.faster,
22
22
  configureWebpackUtils,
23
23
  });
24
24
  const ProgressBarPlugin = await (0, bundler_1.getProgressBarPlugin)({
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@docusaurus/core",
3
3
  "description": "Easy to Maintain Open Source Documentation Websites",
4
- "version": "3.9.1",
4
+ "version": "3.9.2-alpha.0-canary-6548",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -33,13 +33,13 @@
33
33
  "url": "https://github.com/facebook/docusaurus/issues"
34
34
  },
35
35
  "dependencies": {
36
- "@docusaurus/babel": "3.9.1",
37
- "@docusaurus/bundler": "3.9.1",
38
- "@docusaurus/logger": "3.9.1",
39
- "@docusaurus/mdx-loader": "3.9.1",
40
- "@docusaurus/utils": "3.9.1",
41
- "@docusaurus/utils-common": "3.9.1",
42
- "@docusaurus/utils-validation": "3.9.1",
36
+ "@docusaurus/babel": "3.9.2-alpha.0-canary-6548",
37
+ "@docusaurus/bundler": "3.9.2-alpha.0-canary-6548",
38
+ "@docusaurus/logger": "3.9.2-alpha.0-canary-6548",
39
+ "@docusaurus/mdx-loader": "3.9.2-alpha.0-canary-6548",
40
+ "@docusaurus/utils": "3.9.2-alpha.0-canary-6548",
41
+ "@docusaurus/utils-common": "3.9.2-alpha.0-canary-6548",
42
+ "@docusaurus/utils-validation": "3.9.2-alpha.0-canary-6548",
43
43
  "boxen": "^6.2.1",
44
44
  "chalk": "^4.1.2",
45
45
  "chokidar": "^3.5.3",
@@ -51,7 +51,7 @@
51
51
  "escape-html": "^1.0.3",
52
52
  "eta": "^2.2.0",
53
53
  "eval": "^0.1.8",
54
- "execa": "5.1.1",
54
+ "execa": "^5.1.1",
55
55
  "fs-extra": "^11.1.1",
56
56
  "html-tags": "^3.3.1",
57
57
  "html-webpack-plugin": "^5.6.0",
@@ -77,26 +77,31 @@
77
77
  "webpack-merge": "^6.0.1"
78
78
  },
79
79
  "devDependencies": {
80
- "@docusaurus/module-type-aliases": "3.9.1",
81
- "@docusaurus/types": "3.9.1",
80
+ "@docusaurus/module-type-aliases": "3.9.2-alpha.0-canary-6548",
81
+ "@docusaurus/types": "3.9.2-alpha.0-canary-6548",
82
82
  "@total-typescript/shoehorn": "^0.1.2",
83
83
  "@types/detect-port": "^1.3.3",
84
- "@types/react-dom": "^18.2.7",
84
+ "@types/react-dom": "^19.2.3",
85
85
  "@types/react-router-config": "^5.0.7",
86
86
  "@types/serve-handler": "^6.1.4",
87
87
  "@types/update-notifier": "^6.0.4",
88
88
  "@types/webpack-bundle-analyzer": "^4.7.0",
89
- "react-test-renderer": "^18.0.0",
90
89
  "tmp-promise": "^3.0.3",
91
90
  "tree-node-cli": "^1.6.0"
92
91
  },
93
92
  "peerDependencies": {
93
+ "@docusaurus/faster": "*",
94
94
  "@mdx-js/react": "^3.0.0",
95
95
  "react": "^18.0.0 || ^19.0.0",
96
96
  "react-dom": "^18.0.0 || ^19.0.0"
97
97
  },
98
+ "peerDependenciesMeta": {
99
+ "@docusaurus/faster": {
100
+ "optional": true
101
+ }
102
+ },
98
103
  "engines": {
99
104
  "node": ">=20.0"
100
105
  },
101
- "gitHead": "c0dd59f0e712f85b6053c59e46b0514b5d2d1414"
106
+ "gitHead": "7694572787296be09b95c6ff0a541ae19185a9f5"
102
107
  }