@docusaurus/core 3.6.3 → 3.7.0

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.
@@ -4,5 +4,6 @@
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 ReactNode } from 'react';
7
8
  import '@generated/client-modules';
8
- export default function App(): JSX.Element;
9
+ export default function App(): ReactNode;
@@ -4,6 +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 ReactNode } from 'react';
7
8
  import './styles.module.css';
8
9
  /**
9
10
  * We want to help the users with a bad baseUrl configuration (very common
@@ -16,4 +17,4 @@ import './styles.module.css';
16
17
  *
17
18
  * @see https://github.com/facebook/docusaurus/pull/3621
18
19
  */
19
- export default function MaybeBaseUrlIssueBanner(): JSX.Element | null;
20
+ export default function MaybeBaseUrlIssueBanner(): ReactNode;
@@ -15,4 +15,4 @@ export declare const useBrokenLinksContext: () => BrokenLinks;
15
15
  export declare function BrokenLinksProvider({ children, brokenLinks, }: {
16
16
  children: ReactNode;
17
17
  brokenLinks: BrokenLinks;
18
- }): JSX.Element;
18
+ }): ReactNode;
@@ -4,7 +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 ReactElement } from 'react';
7
+ import type { ReactElement, ReactNode } from 'react';
8
8
  import type { ClientModule } from '@docusaurus/types';
9
9
  import type { Location } from 'history';
10
10
  export declare function dispatchLifecycleAction<K extends keyof ClientModule>(lifecycleAction: K, ...args: Parameters<NonNullable<ClientModule[K]>>): () => void;
@@ -12,5 +12,5 @@ declare function ClientLifecyclesDispatcher({ children, location, previousLocati
12
12
  children: ReactElement;
13
13
  location: Location;
14
14
  previousLocation: Location | null;
15
- }): JSX.Element;
15
+ }): ReactNode;
16
16
  export default ClientLifecyclesDispatcher;
@@ -4,11 +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
- import React from 'react';
7
+ import React, { type ReactNode } from 'react';
8
8
  import type { Location } from 'history';
9
9
  type Props = {
10
10
  readonly location: Location;
11
- readonly children: JSX.Element;
11
+ readonly children: ReactNode;
12
12
  };
13
13
  type State = {
14
14
  nextRouteHasLoaded: boolean;
@@ -18,6 +18,6 @@ declare class PendingNavigation extends React.Component<Props, State> {
18
18
  private routeUpdateCleanupCb;
19
19
  constructor(props: Props);
20
20
  shouldComponentUpdate(nextProps: Props, nextState: State): boolean;
21
- render(): JSX.Element;
21
+ render(): ReactNode;
22
22
  }
23
23
  export default PendingNavigation;
@@ -4,4 +4,5 @@
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
- export default function SiteMetadataDefaults(): JSX.Element;
7
+ import { type ReactNode } from 'react';
8
+ export default function SiteMetadataDefaults(): ReactNode;
@@ -8,4 +8,4 @@ import React, { type ReactNode } from 'react';
8
8
  export declare const Context: React.Context<boolean>;
9
9
  export declare function BrowserContextProvider({ children, }: {
10
10
  children: ReactNode;
11
- }): JSX.Element;
11
+ }): ReactNode;
@@ -9,4 +9,4 @@ import type { DocusaurusContext } from '@docusaurus/types';
9
9
  export declare const Context: React.Context<DocusaurusContext>;
10
10
  export declare function DocusaurusContextProvider({ children, }: {
11
11
  children: ReactNode;
12
- }): JSX.Element;
12
+ }): ReactNode;
@@ -4,5 +4,6 @@
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 ReactNode } from 'react';
7
8
  import type { Props } from '@docusaurus/BrowserOnly';
8
- export default function BrowserOnly({ children, fallback, }: Props): JSX.Element | null;
9
+ export default function BrowserOnly({ children, fallback }: Props): ReactNode;
@@ -8,7 +8,7 @@ import React, { isValidElement } from 'react';
8
8
  import useIsBrowser from '@docusaurus/useIsBrowser';
9
9
  // Similar comp to the one described here:
10
10
  // https://www.joshwcomeau.com/react/the-perils-of-rehydration/#abstractions
11
- export default function BrowserOnly({ children, fallback, }) {
11
+ export default function BrowserOnly({ children, fallback }) {
12
12
  const isBrowser = useIsBrowser();
13
13
  if (isBrowser) {
14
14
  if (typeof children !== 'function' &&
@@ -4,5 +4,6 @@
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 ReactNode } from 'react';
7
8
  import type { Props } from '@docusaurus/Head';
8
- export default function Head(props: Props): JSX.Element;
9
+ export default function Head(props: Props): ReactNode;
@@ -8,4 +8,4 @@ import { type ReactNode } from 'react';
8
8
  import type { InterpolateProps, InterpolateValues } from '@docusaurus/Interpolate';
9
9
  export declare function interpolate<Str extends string>(text: Str, values?: InterpolateValues<Str, string | number>): string;
10
10
  export declare function interpolate<Str extends string, Value extends ReactNode>(text: Str, values?: InterpolateValues<Str, Value>): ReactNode;
11
- export default function Interpolate<Str extends string>({ children, values, }: InterpolateProps<Str>): JSX.Element;
11
+ export default function Interpolate<Str extends string>({ children, values, }: InterpolateProps<Str>): ReactNode;
@@ -4,7 +4,8 @@
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 ReactNode } from 'react';
7
8
  import { type InterpolateValues } from '@docusaurus/Interpolate';
8
9
  import type { TranslateParam, TranslateProps } from '@docusaurus/Translate';
9
10
  export declare function translate<Str extends string>({ message, id }: TranslateParam<Str>, values?: InterpolateValues<Str, string | number>): string;
10
- export default function Translate<Str extends string>({ children, id, values, }: TranslateProps<Str>): JSX.Element;
11
+ export default function Translate<Str extends string>({ children, id, values, }: TranslateProps<Str>): ReactNode;
@@ -4,4 +4,5 @@
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
- export default function HasHydratedDataAttribute(): JSX.Element;
7
+ import type { ReactNode } from 'react';
8
+ export default function HasHydratedDataAttribute(): ReactNode;
@@ -10,4 +10,4 @@ export declare const Context: React.Context<PluginRouteContext | null>;
10
10
  export declare function RouteContextProvider({ children, value, }: {
11
11
  children: ReactNode;
12
12
  value: PluginRouteContext | RouteContext | null;
13
- }): JSX.Element;
13
+ }): ReactNode;
@@ -4,5 +4,6 @@
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 ReactNode } from 'react';
7
8
  import type { Props } from '@theme/Error';
8
- export default function Error({ error, tryAgain }: Props): JSX.Element;
9
+ export default function Error({ error, tryAgain }: Props): ReactNode;
@@ -4,5 +4,6 @@
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 ReactNode } from 'react';
7
8
  import type { Props } from '@theme/Layout';
8
- export default function Layout({ children }: Props): JSX.Element;
9
+ export default function Layout({ children }: Props): ReactNode;
@@ -4,5 +4,6 @@
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 ReactNode } from 'react';
7
8
  import type { LoadingComponentProps } from 'react-loadable';
8
- export default function Loading({ error, retry, pastDelay, }: LoadingComponentProps): JSX.Element | null;
9
+ export default function Loading({ error, retry, pastDelay, }: LoadingComponentProps): ReactNode;
@@ -4,4 +4,5 @@
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
- export default function NotFound(): JSX.Element;
7
+ import { type ReactNode } from 'react';
8
+ export default function NotFound(): ReactNode;
@@ -4,5 +4,6 @@
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 ReactNode } from 'react';
7
8
  import type { Props } from '@theme/Root';
8
- export default function Root({ children }: Props): JSX.Element;
9
+ export default function Root({ children }: Props): ReactNode;
@@ -4,4 +4,5 @@
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
- export default function SiteMetadata(): JSX.Element | null;
7
+ import type { ReactNode } from 'react';
8
+ export default function SiteMetadata(): ReactNode;
@@ -1,9 +1,3 @@
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
1
  // To be implemented by the theme with <Head>
8
2
  export default function SiteMetadata() {
9
3
  return null;
@@ -76,14 +76,14 @@ async function wrap({ siteDir, themePath, componentName: themeComponentName, typ
76
76
  await fs_extra_1.default.ensureDir(path_1.default.resolve(siteDir, utils_1.THEME_PATH));
77
77
  const toPath = path_1.default.resolve(siteDir, utils_1.THEME_PATH, wrapperFileName);
78
78
  const content = typescript
79
- ? `import React from 'react';
79
+ ? `import React, {type ReactNode} from 'react';
80
80
  import ${componentName} from '@theme-${importType}/${themeComponentName}';
81
81
  import type ${componentName}Type from '@theme/${themeComponentName}';
82
82
  import type {WrapperProps} from '@docusaurus/types';
83
83
 
84
84
  type Props = WrapperProps<typeof ${componentName}Type>;
85
85
 
86
- export default function ${wrapperComponentName}(props: Props): JSX.Element {
86
+ export default function ${wrapperComponentName}(props: Props): ReactNode {
87
87
  return (
88
88
  <>
89
89
  <${componentName} {...props} />
@@ -116,14 +116,37 @@ function genChunkNames(routeModule, prefix, name, res) {
116
116
  * config node, it returns the node's serialized form, and mutates `registry`,
117
117
  * `routesPaths`, and `routesChunkNames` accordingly.
118
118
  */
119
- function genRouteCode(routeConfig, res) {
119
+ function genRouteCode(routeConfig, res, index, level) {
120
120
  const { path: routePath, component, modules = {}, context, routes: subroutes, priority, exact, metadata, props, plugin, ...attributes } = routeConfig;
121
121
  if (typeof routePath !== 'string' || !component) {
122
122
  throw new Error(`Invalid route config: path must be a string and component is required.
123
123
  ${JSON.stringify(routeConfig)}`);
124
124
  }
125
- const routeHash = (0, utils_1.simpleHash)(JSON.stringify(routeConfig), 3);
126
- res.routesChunkNames[`${routePath}-${routeHash}`] = {
125
+ // Because 2 routes with the same path could lead to hash collisions
126
+ // See https://github.com/facebook/docusaurus/issues/10718#issuecomment-2498516394
127
+ function generateUniqueRouteKey() {
128
+ const hashes = [
129
+ // // OG algo to keep former snapshots
130
+ () => (0, utils_1.simpleHash)(JSON.stringify(routeConfig), 3),
131
+ // Other attempts, not ideal but good enough
132
+ // Technically we could use Math.random() here but it's annoying for tests
133
+ () => (0, utils_1.simpleHash)(`${level}${index}`, 3),
134
+ () => (0, utils_1.simpleHash)(JSON.stringify(routeConfig), 4),
135
+ () => (0, utils_1.simpleHash)(`${level}${index}`, 4),
136
+ ];
137
+ for (const tryHash of hashes) {
138
+ const routeHash = tryHash();
139
+ const routeKey = `${routePath}-${routeHash}`;
140
+ if (!res.routesChunkNames[routeKey]) {
141
+ return { routeKey, routeHash };
142
+ }
143
+ }
144
+ throw new Error(`Docusaurus couldn't generate a unique hash for route ${routeConfig.path} (level=${level} - index=${index}).
145
+ This is a bug, please report it here!
146
+ https://github.com/facebook/docusaurus/issues/10718`);
147
+ }
148
+ const { routeKey, routeHash } = generateUniqueRouteKey();
149
+ res.routesChunkNames[routeKey] = {
127
150
  // Avoid clash with a prop called "component"
128
151
  ...genChunkNames({ __comp: component }, 'component', component, res),
129
152
  ...(context &&
@@ -133,7 +156,7 @@ ${JSON.stringify(routeConfig)}`);
133
156
  return serializeRouteConfig({
134
157
  routePath: routePath.replace(/'/g, "\\'"),
135
158
  routeHash,
136
- subroutesCodeStrings: subroutes?.map((r) => genRouteCode(r, res)),
159
+ subroutesCodeStrings: subroutes?.map((r, i) => genRouteCode(r, res, i, level + 1)),
137
160
  exact,
138
161
  attributes,
139
162
  });
@@ -156,7 +179,7 @@ function generateRoutesCode(routeConfigs) {
156
179
  };
157
180
  // `genRouteCode` would mutate `res`
158
181
  const routeConfigSerialized = routeConfigs
159
- .map((r) => genRouteCode(r, res))
182
+ .map((r, i) => genRouteCode(r, res, i, 0))
160
183
  .join(',\n');
161
184
  res.routesConfig = `import React from 'react';
162
185
  import ComponentCreator from '@docusaurus/ComponentCreator';
@@ -10,7 +10,6 @@ exports.getDefaultLocaleConfig = getDefaultLocaleConfig;
10
10
  exports.loadI18n = loadI18n;
11
11
  const tslib_1 = require("tslib");
12
12
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
13
- const rtl_detect_1 = require("rtl-detect");
14
13
  function inferLanguageDisplayName(locale) {
15
14
  const tryLocale = (l) => {
16
15
  try {
@@ -58,11 +57,20 @@ function getDefaultCalendar(localeStr) {
58
57
  }
59
58
  return 'gregory';
60
59
  }
60
+ function getDefaultDirection(localeStr) {
61
+ const locale = new Intl.Locale(localeStr);
62
+ // see https://github.com/tc39/proposal-intl-locale-info
63
+ // see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/getTextInfo
64
+ // Node 18.0 implements a former version of the getTextInfo() proposal
65
+ // @ts-expect-error: The TC39 proposal was updated
66
+ const textInto = locale.getTextInfo?.() ?? locale.textInfo;
67
+ return textInto.direction;
68
+ }
61
69
  function getDefaultLocaleConfig(locale) {
62
70
  try {
63
71
  return {
64
72
  label: getDefaultLocaleLabel(locale),
65
- direction: (0, rtl_detect_1.getLangDir)(locale),
73
+ direction: getDefaultDirection(locale),
66
74
  htmlLang: locale,
67
75
  calendar: getDefaultCalendar(locale),
68
76
  path: locale,
@@ -23,14 +23,18 @@ const LibrariesToTranspile = [
23
23
  'copy-text-to-clipboard', // Contains optional catch binding, incompatible with recent versions of Edge
24
24
  ];
25
25
  const LibrariesToTranspileRegex = new RegExp(LibrariesToTranspile.map((libName) => `(node_modules/${libName})`).join('|'));
26
- const ReactAliases = process.env
27
- .DOCUSAURUS_NO_REACT_ALIASES
28
- ? {}
29
- : {
30
- react: path_1.default.dirname(require.resolve('react/package.json')),
31
- 'react-dom': path_1.default.dirname(require.resolve('react-dom/package.json')),
32
- '@mdx-js/react': path_1.default.dirname(require.resolve('@mdx-js/react')),
26
+ function getReactAliases(siteDir) {
27
+ // Escape hatch
28
+ if (process.env.DOCUSAURUS_NO_REACT_ALIASES) {
29
+ return {};
30
+ }
31
+ const resolveSitePkg = (id) => require.resolve(id, { paths: [siteDir] });
32
+ return {
33
+ react: path_1.default.dirname(resolveSitePkg('react/package.json')),
34
+ 'react-dom': path_1.default.dirname(resolveSitePkg('react-dom/package.json')),
35
+ '@mdx-js/react': path_1.default.dirname(resolveSitePkg('@mdx-js/react')),
33
36
  };
37
+ }
34
38
  function excludeJS(modulePath) {
35
39
  // Always transpile client dir
36
40
  if (modulePath.startsWith(exports.clientDir)) {
@@ -96,11 +100,11 @@ async function createBaseConfig({ props, isServer, minify, faster, configureWebp
96
100
  // See https://rspack.dev/config/experiments#experimentsincremental
97
101
  // Produces warnings in production builds
98
102
  // See https://github.com/web-infra-dev/rspack/pull/8311#issuecomment-2476014664
99
- // @ts-expect-error: Rspack-only
100
- // incremental: !isProd,
101
- // TODO restore incremental mode in dev + opt-in/opt-out flag?
102
- // temporarily disabled due to https://github.com/facebook/docusaurus/issues/10646#issuecomment-2490675451
103
- incremental: undefined,
103
+ // We use the same integration as Rspress, with ability to disable
104
+ // See https://github.com/web-infra-dev/rspress/pull/1631
105
+ // See https://github.com/facebook/docusaurus/issues/10646
106
+ // @ts-expect-error: Rspack-only, not available in Webpack typedefs
107
+ incremental: !isProd && !process.env.DISABLE_RSPACK_INCREMENTAL,
104
108
  };
105
109
  }
106
110
  return undefined;
@@ -137,7 +141,7 @@ async function createBaseConfig({ props, isServer, minify, faster, configureWebp
137
141
  process.cwd(),
138
142
  ],
139
143
  alias: {
140
- ...ReactAliases,
144
+ ...getReactAliases(siteDir),
141
145
  '@site': siteDir,
142
146
  '@generated': generatedFilesDir,
143
147
  ...(await (0, aliases_1.loadDocusaurusAliases)()),
@@ -199,7 +203,6 @@ async function createBaseConfig({ props, isServer, minify, faster, configureWebp
199
203
  fileLoaderUtils.rules.images(),
200
204
  fileLoaderUtils.rules.fonts(),
201
205
  fileLoaderUtils.rules.media(),
202
- fileLoaderUtils.rules.svg(),
203
206
  fileLoaderUtils.rules.otherAssets(),
204
207
  {
205
208
  test: /\.[jt]sx?$/i,
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.6.3",
4
+ "version": "3.7.0",
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.6.3",
37
- "@docusaurus/bundler": "3.6.3",
38
- "@docusaurus/logger": "3.6.3",
39
- "@docusaurus/mdx-loader": "3.6.3",
40
- "@docusaurus/utils": "3.6.3",
41
- "@docusaurus/utils-common": "3.6.3",
42
- "@docusaurus/utils-validation": "3.6.3",
36
+ "@docusaurus/babel": "3.7.0",
37
+ "@docusaurus/bundler": "3.7.0",
38
+ "@docusaurus/logger": "3.7.0",
39
+ "@docusaurus/mdx-loader": "3.7.0",
40
+ "@docusaurus/utils": "3.7.0",
41
+ "@docusaurus/utils-common": "3.7.0",
42
+ "@docusaurus/utils-validation": "3.7.0",
43
43
  "boxen": "^6.2.1",
44
44
  "chalk": "^4.1.2",
45
45
  "chokidar": "^3.5.3",
@@ -60,13 +60,12 @@
60
60
  "p-map": "^4.0.0",
61
61
  "prompts": "^2.4.2",
62
62
  "react-dev-utils": "^12.0.1",
63
- "react-helmet-async": "^1.3.0",
63
+ "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0",
64
64
  "react-loadable": "npm:@docusaurus/react-loadable@6.0.0",
65
65
  "react-loadable-ssr-addon-v5-slorber": "^1.0.1",
66
66
  "react-router": "^5.3.4",
67
67
  "react-router-config": "^5.1.1",
68
68
  "react-router-dom": "^5.3.4",
69
- "rtl-detect": "^1.0.4",
70
69
  "semver": "^7.5.4",
71
70
  "serve-handler": "^6.1.6",
72
71
  "shelljs": "^0.8.5",
@@ -78,13 +77,12 @@
78
77
  "webpack-merge": "^6.0.1"
79
78
  },
80
79
  "devDependencies": {
81
- "@docusaurus/module-type-aliases": "3.6.3",
82
- "@docusaurus/types": "3.6.3",
80
+ "@docusaurus/module-type-aliases": "3.7.0",
81
+ "@docusaurus/types": "3.7.0",
83
82
  "@total-typescript/shoehorn": "^0.1.2",
84
83
  "@types/detect-port": "^1.3.3",
85
84
  "@types/react-dom": "^18.2.7",
86
85
  "@types/react-router-config": "^5.0.7",
87
- "@types/rtl-detect": "^1.0.0",
88
86
  "@types/serve-handler": "^6.1.4",
89
87
  "@types/update-notifier": "^6.0.4",
90
88
  "@types/webpack-bundle-analyzer": "^4.7.0",
@@ -94,11 +92,11 @@
94
92
  },
95
93
  "peerDependencies": {
96
94
  "@mdx-js/react": "^3.0.0",
97
- "react": "^18.0.0",
98
- "react-dom": "^18.0.0"
95
+ "react": "^18.0.0 || ^19.0.0",
96
+ "react-dom": "^18.0.0 || ^19.0.0"
99
97
  },
100
98
  "engines": {
101
99
  "node": ">=18.0"
102
100
  },
103
- "gitHead": "9c0e19c669ffcbc0972bfd8527e8b93f1f74e7d8"
101
+ "gitHead": "dd59750c16fe6908a26f18806a54d4c3dbe6db43"
104
102
  }