@docusaurus/plugin-content-docs 3.7.0 → 3.8.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.
- package/lib/cli.js +17 -0
- package/lib/client/docsUtils.d.ts +5 -0
- package/lib/client/docsUtils.js +18 -0
- package/lib/client/index.d.ts +2 -1
- package/lib/client/index.js +2 -1
- package/lib/client/structuredDataUtils.d.ts +11 -0
- package/lib/client/structuredDataUtils.js +24 -0
- package/lib/index.js +23 -0
- package/lib/versions/files.d.ts +4 -0
- package/lib/versions/files.js +9 -0
- package/package.json +13 -13
- package/src/cli.ts +18 -0
- package/src/client/docsUtils.tsx +19 -0
- package/src/client/index.ts +3 -0
- package/src/client/structuredDataUtils.ts +32 -0
- package/src/index.ts +33 -0
- package/src/plugin-content-docs.d.ts +9 -1
- package/src/versions/files.ts +15 -0
package/lib/cli.js
CHANGED
|
@@ -76,6 +76,23 @@ async function cliDocsVersionCommand(version, { id: pluginId, path: docsPath, si
|
|
|
76
76
|
versionName: version,
|
|
77
77
|
});
|
|
78
78
|
await fs_extra_1.default.copy(docsDir, newVersionDir);
|
|
79
|
+
// Copy version JSON translation file for this locale
|
|
80
|
+
// i18n/<l>/docusaurus-plugin-content-docs/current.json => version-v1.json
|
|
81
|
+
// See https://docusaurus.io/docs/next/api/plugins/@docusaurus/plugin-content-docs#translation-files-location
|
|
82
|
+
if (locale !== i18n.defaultLocale) {
|
|
83
|
+
const dir = (0, files_1.getPluginDirPathLocalized)({
|
|
84
|
+
localizationDir,
|
|
85
|
+
pluginId,
|
|
86
|
+
});
|
|
87
|
+
const sourceFile = path_1.default.join(dir, 'current.json');
|
|
88
|
+
const dest = path_1.default.join(dir, `version-${version}.json`);
|
|
89
|
+
if (await fs_extra_1.default.pathExists(sourceFile)) {
|
|
90
|
+
await fs_extra_1.default.copy(sourceFile, dest);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
logger_1.default.warn `${pluginIdLogPrefix}: i18n translation file does not exist in path=${sourceFile}. Skipping.`;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
79
96
|
}));
|
|
80
97
|
await createVersionedSidebarFile({
|
|
81
98
|
siteDir,
|
|
@@ -34,6 +34,11 @@ export declare function findFirstSidebarItemLink(item: PropSidebarItem): string
|
|
|
34
34
|
* on category index pages.
|
|
35
35
|
*/
|
|
36
36
|
export declare function useCurrentSidebarCategory(): PropSidebarItemCategory;
|
|
37
|
+
/**
|
|
38
|
+
* Gets the category associated with the current location. Should only be used
|
|
39
|
+
* on category index pages.
|
|
40
|
+
*/
|
|
41
|
+
export declare function useCurrentSidebarSiblings(): PropSidebarItem[];
|
|
37
42
|
/**
|
|
38
43
|
* Checks if a sidebar item should be active, based on the active path.
|
|
39
44
|
*/
|
package/lib/client/docsUtils.js
CHANGED
|
@@ -91,6 +91,24 @@ export function useCurrentSidebarCategory() {
|
|
|
91
91
|
}
|
|
92
92
|
return deepestCategory;
|
|
93
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Gets the category associated with the current location. Should only be used
|
|
96
|
+
* on category index pages.
|
|
97
|
+
*/
|
|
98
|
+
export function useCurrentSidebarSiblings() {
|
|
99
|
+
const { pathname } = useLocation();
|
|
100
|
+
const sidebar = useDocsSidebar();
|
|
101
|
+
if (!sidebar) {
|
|
102
|
+
throw new Error('Unexpected: cant find current sidebar in context');
|
|
103
|
+
}
|
|
104
|
+
const categoryBreadcrumbs = getSidebarBreadcrumbs({
|
|
105
|
+
sidebarItems: sidebar.items,
|
|
106
|
+
pathname,
|
|
107
|
+
onlyCategories: true,
|
|
108
|
+
});
|
|
109
|
+
const deepestCategory = categoryBreadcrumbs.slice(-1)[0];
|
|
110
|
+
return deepestCategory?.items ?? sidebar.items;
|
|
111
|
+
}
|
|
94
112
|
const isActive = (testedPath, activePath) => typeof testedPath !== 'undefined' && isSamePath(testedPath, activePath);
|
|
95
113
|
const containsActiveSidebarItem = (items, activePath) => items.some((subItem) => isActiveSidebarItem(subItem, activePath));
|
|
96
114
|
/**
|
package/lib/client/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import type { UseDataOptions } from '@docusaurus/types';
|
|
8
|
-
export { useDocById, findSidebarCategory, findFirstSidebarItemLink, isActiveSidebarItem, isVisibleSidebarItem, useVisibleSidebarItems, useSidebarBreadcrumbs, useDocsVersionCandidates, useLayoutDoc, useLayoutDocsSidebar, useDocRootMetadata, useCurrentSidebarCategory, filterDocCardListItems, } from './docsUtils';
|
|
8
|
+
export { useDocById, findSidebarCategory, findFirstSidebarItemLink, isActiveSidebarItem, isVisibleSidebarItem, useVisibleSidebarItems, useSidebarBreadcrumbs, useDocsVersionCandidates, useLayoutDoc, useLayoutDocsSidebar, useDocRootMetadata, useCurrentSidebarCategory, useCurrentSidebarSiblings, filterDocCardListItems, } from './docsUtils';
|
|
9
9
|
export { useDocsPreferredVersion } from './docsPreferredVersion';
|
|
10
10
|
export { DocSidebarItemsExpandedStateProvider, useDocSidebarItemsExpandedState, } from './docSidebarItemsExpandedState';
|
|
11
11
|
export { DocsVersionProvider, useDocsVersion } from './docsVersion';
|
|
@@ -13,6 +13,7 @@ export { DocsSidebarProvider, useDocsSidebar } from './docsSidebar';
|
|
|
13
13
|
export { DocProvider, useDoc, type DocContextValue } from './doc';
|
|
14
14
|
export { useDocsPreferredVersionByPluginId, DocsPreferredVersionContextProvider, } from './docsPreferredVersion';
|
|
15
15
|
export { useDocsContextualSearchTags, getDocsVersionSearchTag, } from './docsSearch';
|
|
16
|
+
export { useBreadcrumbsStructuredData } from './structuredDataUtils';
|
|
16
17
|
export type ActivePlugin = {
|
|
17
18
|
pluginId: string;
|
|
18
19
|
pluginData: GlobalPluginData;
|
package/lib/client/index.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { useLocation } from '@docusaurus/router';
|
|
8
8
|
import { useAllPluginInstancesData, usePluginData, } from '@docusaurus/useGlobalData';
|
|
9
9
|
import { getActivePlugin, getLatestVersion, getActiveVersion, getActiveDocContext, getDocVersionSuggestions, } from './docsClientUtils';
|
|
10
|
-
export { useDocById, findSidebarCategory, findFirstSidebarItemLink, isActiveSidebarItem, isVisibleSidebarItem, useVisibleSidebarItems, useSidebarBreadcrumbs, useDocsVersionCandidates, useLayoutDoc, useLayoutDocsSidebar, useDocRootMetadata, useCurrentSidebarCategory, filterDocCardListItems, } from './docsUtils';
|
|
10
|
+
export { useDocById, findSidebarCategory, findFirstSidebarItemLink, isActiveSidebarItem, isVisibleSidebarItem, useVisibleSidebarItems, useSidebarBreadcrumbs, useDocsVersionCandidates, useLayoutDoc, useLayoutDocsSidebar, useDocRootMetadata, useCurrentSidebarCategory, useCurrentSidebarSiblings, filterDocCardListItems, } from './docsUtils';
|
|
11
11
|
export { useDocsPreferredVersion } from './docsPreferredVersion';
|
|
12
12
|
export { DocSidebarItemsExpandedStateProvider, useDocSidebarItemsExpandedState, } from './docSidebarItemsExpandedState';
|
|
13
13
|
export { DocsVersionProvider, useDocsVersion } from './docsVersion';
|
|
@@ -15,6 +15,7 @@ export { DocsSidebarProvider, useDocsSidebar } from './docsSidebar';
|
|
|
15
15
|
export { DocProvider, useDoc } from './doc';
|
|
16
16
|
export { useDocsPreferredVersionByPluginId, DocsPreferredVersionContextProvider, } from './docsPreferredVersion';
|
|
17
17
|
export { useDocsContextualSearchTags, getDocsVersionSearchTag, } from './docsSearch';
|
|
18
|
+
export { useBreadcrumbsStructuredData } from './structuredDataUtils';
|
|
18
19
|
// Important to use a constant object to avoid React useEffect executions etc.
|
|
19
20
|
// see https://github.com/facebook/docusaurus/issues/5089
|
|
20
21
|
const StableEmptyObject = {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import type { PropSidebarBreadcrumbsItem } from '@docusaurus/plugin-content-docs';
|
|
8
|
+
import type { WithContext, BreadcrumbList } from 'schema-dts';
|
|
9
|
+
export declare function useBreadcrumbsStructuredData({ breadcrumbs, }: {
|
|
10
|
+
breadcrumbs: PropSidebarBreadcrumbsItem[];
|
|
11
|
+
}): WithContext<BreadcrumbList>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
|
8
|
+
export function useBreadcrumbsStructuredData({ breadcrumbs, }) {
|
|
9
|
+
const { siteConfig } = useDocusaurusContext();
|
|
10
|
+
return {
|
|
11
|
+
'@context': 'https://schema.org',
|
|
12
|
+
'@type': 'BreadcrumbList',
|
|
13
|
+
itemListElement: breadcrumbs
|
|
14
|
+
// We filter breadcrumb items without links, they are not allowed
|
|
15
|
+
// See also https://github.com/facebook/docusaurus/issues/9319#issuecomment-2643560845
|
|
16
|
+
.filter((breadcrumb) => breadcrumb.href)
|
|
17
|
+
.map((breadcrumb, index) => ({
|
|
18
|
+
'@type': 'ListItem',
|
|
19
|
+
position: index + 1,
|
|
20
|
+
name: breadcrumb.label,
|
|
21
|
+
item: `${siteConfig.url}${breadcrumb.href}`,
|
|
22
|
+
})),
|
|
23
|
+
};
|
|
24
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -10,6 +10,7 @@ exports.validateOptions = void 0;
|
|
|
10
10
|
exports.default = pluginContentDocs;
|
|
11
11
|
const tslib_1 = require("tslib");
|
|
12
12
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
13
|
+
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
13
14
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
14
15
|
const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
|
|
15
16
|
const utils_1 = require("@docusaurus/utils");
|
|
@@ -26,6 +27,21 @@ const translations_1 = require("./translations");
|
|
|
26
27
|
const routes_1 = require("./routes");
|
|
27
28
|
const utils_2 = require("./sidebars/utils");
|
|
28
29
|
const contentHelpers_1 = require("./contentHelpers");
|
|
30
|
+
// MDX loader is not 100% deterministic, leading to cache invalidation issue
|
|
31
|
+
// This permits to invalidate the MDX loader cache entries when content changes
|
|
32
|
+
// Problem documented here: https://github.com/facebook/docusaurus/pull/10934
|
|
33
|
+
// TODO this is not a perfect solution, find better?
|
|
34
|
+
async function createMdxLoaderDependencyFile({ dataDir, options, versionsMetadata, }) {
|
|
35
|
+
const filePath = path_1.default.join(dataDir, '__mdx-loader-dependency.json');
|
|
36
|
+
// the cache is invalidated whenever this file content changes
|
|
37
|
+
const fileContent = {
|
|
38
|
+
options,
|
|
39
|
+
versionsMetadata,
|
|
40
|
+
};
|
|
41
|
+
await fs_extra_1.default.ensureDir(dataDir);
|
|
42
|
+
await fs_extra_1.default.writeFile(filePath, JSON.stringify(fileContent));
|
|
43
|
+
return filePath;
|
|
44
|
+
}
|
|
29
45
|
async function pluginContentDocs(context, options) {
|
|
30
46
|
const { siteDir, generatedFilesDir, baseUrl, siteConfig } = context;
|
|
31
47
|
// Mutate options to resolve sidebar path according to siteDir
|
|
@@ -50,6 +66,13 @@ async function pluginContentDocs(context, options) {
|
|
|
50
66
|
return (0, mdx_loader_1.createMDXLoaderRule)({
|
|
51
67
|
include: contentDirs,
|
|
52
68
|
options: {
|
|
69
|
+
dependencies: [
|
|
70
|
+
await createMdxLoaderDependencyFile({
|
|
71
|
+
dataDir,
|
|
72
|
+
options,
|
|
73
|
+
versionsMetadata,
|
|
74
|
+
}),
|
|
75
|
+
].filter((d) => typeof d === 'string'),
|
|
53
76
|
useCrossCompilerCache: siteConfig.future.experimental_faster.mdxCrossCompilerCache,
|
|
54
77
|
admonitions: options.admonitions,
|
|
55
78
|
remarkPlugins,
|
package/lib/versions/files.d.ts
CHANGED
|
@@ -15,6 +15,10 @@ export declare function getDocsDirPathLocalized({ localizationDir, pluginId, ver
|
|
|
15
15
|
pluginId: string;
|
|
16
16
|
versionName: string;
|
|
17
17
|
}): string;
|
|
18
|
+
export declare function getPluginDirPathLocalized({ localizationDir, pluginId, }: {
|
|
19
|
+
localizationDir: string;
|
|
20
|
+
pluginId: string;
|
|
21
|
+
}): string;
|
|
18
22
|
/** `community` => `[siteDir]/community_versions.json` */
|
|
19
23
|
export declare function getVersionsFilePath(siteDir: string, pluginId: string): string;
|
|
20
24
|
/**
|
package/lib/versions/files.js
CHANGED
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
9
9
|
exports.getVersionDocsDirPath = getVersionDocsDirPath;
|
|
10
10
|
exports.getVersionSidebarsPath = getVersionSidebarsPath;
|
|
11
11
|
exports.getDocsDirPathLocalized = getDocsDirPathLocalized;
|
|
12
|
+
exports.getPluginDirPathLocalized = getPluginDirPathLocalized;
|
|
12
13
|
exports.getVersionsFilePath = getVersionsFilePath;
|
|
13
14
|
exports.readVersionsFile = readVersionsFile;
|
|
14
15
|
exports.readVersionNames = readVersionNames;
|
|
@@ -45,6 +46,14 @@ function getDocsDirPathLocalized({ localizationDir, pluginId, versionName, }) {
|
|
|
45
46
|
],
|
|
46
47
|
});
|
|
47
48
|
}
|
|
49
|
+
function getPluginDirPathLocalized({ localizationDir, pluginId, }) {
|
|
50
|
+
return (0, utils_1.getPluginI18nPath)({
|
|
51
|
+
localizationDir,
|
|
52
|
+
pluginName: 'docusaurus-plugin-content-docs',
|
|
53
|
+
pluginId,
|
|
54
|
+
subPaths: [],
|
|
55
|
+
});
|
|
56
|
+
}
|
|
48
57
|
/** `community` => `[siteDir]/community_versions.json` */
|
|
49
58
|
function getVersionsFilePath(siteDir, pluginId) {
|
|
50
59
|
return path_1.default.join(siteDir, addPluginIdPrefix(constants_1.VERSIONS_JSON_FILE, pluginId));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docusaurus/plugin-content-docs",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.0",
|
|
4
4
|
"description": "Docs plugin for Docusaurus.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -35,20 +35,21 @@
|
|
|
35
35
|
},
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@docusaurus/core": "3.
|
|
39
|
-
"@docusaurus/logger": "3.
|
|
40
|
-
"@docusaurus/mdx-loader": "3.
|
|
41
|
-
"@docusaurus/module-type-aliases": "3.
|
|
42
|
-
"@docusaurus/theme-common": "3.
|
|
43
|
-
"@docusaurus/types": "3.
|
|
44
|
-
"@docusaurus/utils": "3.
|
|
45
|
-
"@docusaurus/utils-common": "3.
|
|
46
|
-
"@docusaurus/utils-validation": "3.
|
|
38
|
+
"@docusaurus/core": "3.8.0",
|
|
39
|
+
"@docusaurus/logger": "3.8.0",
|
|
40
|
+
"@docusaurus/mdx-loader": "3.8.0",
|
|
41
|
+
"@docusaurus/module-type-aliases": "3.8.0",
|
|
42
|
+
"@docusaurus/theme-common": "3.8.0",
|
|
43
|
+
"@docusaurus/types": "3.8.0",
|
|
44
|
+
"@docusaurus/utils": "3.8.0",
|
|
45
|
+
"@docusaurus/utils-common": "3.8.0",
|
|
46
|
+
"@docusaurus/utils-validation": "3.8.0",
|
|
47
47
|
"@types/react-router-config": "^5.0.7",
|
|
48
48
|
"combine-promises": "^1.1.0",
|
|
49
49
|
"fs-extra": "^11.1.1",
|
|
50
50
|
"js-yaml": "^4.1.0",
|
|
51
51
|
"lodash": "^4.17.21",
|
|
52
|
+
"schema-dts": "^1.1.2",
|
|
52
53
|
"tslib": "^2.6.0",
|
|
53
54
|
"utility-types": "^3.10.0",
|
|
54
55
|
"webpack": "^5.88.1"
|
|
@@ -57,8 +58,7 @@
|
|
|
57
58
|
"@types/js-yaml": "^4.0.5",
|
|
58
59
|
"@types/picomatch": "^2.3.0",
|
|
59
60
|
"commander": "^5.1.0",
|
|
60
|
-
"picomatch": "^2.3.1"
|
|
61
|
-
"shelljs": "^0.8.5"
|
|
61
|
+
"picomatch": "^2.3.1"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"engines": {
|
|
68
68
|
"node": ">=18.0"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "948d63c42fad0ba24b7b531a9deb6167e64dc845"
|
|
71
71
|
}
|
package/src/cli.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
getVersionDocsDirPath,
|
|
15
15
|
getVersionSidebarsPath,
|
|
16
16
|
getDocsDirPathLocalized,
|
|
17
|
+
getPluginDirPathLocalized,
|
|
17
18
|
readVersionsFile,
|
|
18
19
|
} from './versions/files';
|
|
19
20
|
import {validateVersionName} from './versions/validation';
|
|
@@ -123,6 +124,23 @@ async function cliDocsVersionCommand(
|
|
|
123
124
|
versionName: version,
|
|
124
125
|
});
|
|
125
126
|
await fs.copy(docsDir, newVersionDir);
|
|
127
|
+
|
|
128
|
+
// Copy version JSON translation file for this locale
|
|
129
|
+
// i18n/<l>/docusaurus-plugin-content-docs/current.json => version-v1.json
|
|
130
|
+
// See https://docusaurus.io/docs/next/api/plugins/@docusaurus/plugin-content-docs#translation-files-location
|
|
131
|
+
if (locale !== i18n.defaultLocale) {
|
|
132
|
+
const dir = getPluginDirPathLocalized({
|
|
133
|
+
localizationDir,
|
|
134
|
+
pluginId,
|
|
135
|
+
});
|
|
136
|
+
const sourceFile = path.join(dir, 'current.json');
|
|
137
|
+
const dest = path.join(dir, `version-${version}.json`);
|
|
138
|
+
if (await fs.pathExists(sourceFile)) {
|
|
139
|
+
await fs.copy(sourceFile, dest);
|
|
140
|
+
} else {
|
|
141
|
+
logger.warn`${pluginIdLogPrefix}: i18n translation file does not exist in path=${sourceFile}. Skipping.`;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
126
144
|
}),
|
|
127
145
|
);
|
|
128
146
|
|
package/src/client/docsUtils.tsx
CHANGED
|
@@ -132,6 +132,25 @@ export function useCurrentSidebarCategory(): PropSidebarItemCategory {
|
|
|
132
132
|
return deepestCategory;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Gets the category associated with the current location. Should only be used
|
|
137
|
+
* on category index pages.
|
|
138
|
+
*/
|
|
139
|
+
export function useCurrentSidebarSiblings(): PropSidebarItem[] {
|
|
140
|
+
const {pathname} = useLocation();
|
|
141
|
+
const sidebar = useDocsSidebar();
|
|
142
|
+
if (!sidebar) {
|
|
143
|
+
throw new Error('Unexpected: cant find current sidebar in context');
|
|
144
|
+
}
|
|
145
|
+
const categoryBreadcrumbs = getSidebarBreadcrumbs({
|
|
146
|
+
sidebarItems: sidebar.items,
|
|
147
|
+
pathname,
|
|
148
|
+
onlyCategories: true,
|
|
149
|
+
});
|
|
150
|
+
const deepestCategory = categoryBreadcrumbs.slice(-1)[0];
|
|
151
|
+
return deepestCategory?.items ?? sidebar.items;
|
|
152
|
+
}
|
|
153
|
+
|
|
135
154
|
const isActive = (testedPath: string | undefined, activePath: string) =>
|
|
136
155
|
typeof testedPath !== 'undefined' && isSamePath(testedPath, activePath);
|
|
137
156
|
const containsActiveSidebarItem = (
|
package/src/client/index.ts
CHANGED
|
@@ -33,6 +33,7 @@ export {
|
|
|
33
33
|
useLayoutDocsSidebar,
|
|
34
34
|
useDocRootMetadata,
|
|
35
35
|
useCurrentSidebarCategory,
|
|
36
|
+
useCurrentSidebarSiblings,
|
|
36
37
|
filterDocCardListItems,
|
|
37
38
|
} from './docsUtils';
|
|
38
39
|
|
|
@@ -59,6 +60,8 @@ export {
|
|
|
59
60
|
getDocsVersionSearchTag,
|
|
60
61
|
} from './docsSearch';
|
|
61
62
|
|
|
63
|
+
export {useBreadcrumbsStructuredData} from './structuredDataUtils';
|
|
64
|
+
|
|
62
65
|
export type ActivePlugin = {
|
|
63
66
|
pluginId: string;
|
|
64
67
|
pluginData: GlobalPluginData;
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
|
|
8
|
+
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
|
9
|
+
import type {PropSidebarBreadcrumbsItem} from '@docusaurus/plugin-content-docs';
|
|
10
|
+
import type {WithContext, BreadcrumbList} from 'schema-dts';
|
|
11
|
+
|
|
12
|
+
export function useBreadcrumbsStructuredData({
|
|
13
|
+
breadcrumbs,
|
|
14
|
+
}: {
|
|
15
|
+
breadcrumbs: PropSidebarBreadcrumbsItem[];
|
|
16
|
+
}): WithContext<BreadcrumbList> {
|
|
17
|
+
const {siteConfig} = useDocusaurusContext();
|
|
18
|
+
return {
|
|
19
|
+
'@context': 'https://schema.org',
|
|
20
|
+
'@type': 'BreadcrumbList',
|
|
21
|
+
itemListElement: breadcrumbs
|
|
22
|
+
// We filter breadcrumb items without links, they are not allowed
|
|
23
|
+
// See also https://github.com/facebook/docusaurus/issues/9319#issuecomment-2643560845
|
|
24
|
+
.filter((breadcrumb) => breadcrumb.href)
|
|
25
|
+
.map((breadcrumb, index) => ({
|
|
26
|
+
'@type': 'ListItem',
|
|
27
|
+
position: index + 1,
|
|
28
|
+
name: breadcrumb.label,
|
|
29
|
+
item: `${siteConfig.url}${breadcrumb.href}`,
|
|
30
|
+
})),
|
|
31
|
+
};
|
|
32
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import path from 'path';
|
|
9
|
+
import fs from 'fs-extra';
|
|
9
10
|
import _ from 'lodash';
|
|
10
11
|
import logger from '@docusaurus/logger';
|
|
11
12
|
import {
|
|
@@ -63,6 +64,30 @@ import type {LoadContext, Plugin} from '@docusaurus/types';
|
|
|
63
64
|
import type {DocFile, FullVersion} from './types';
|
|
64
65
|
import type {RuleSetRule} from 'webpack';
|
|
65
66
|
|
|
67
|
+
// MDX loader is not 100% deterministic, leading to cache invalidation issue
|
|
68
|
+
// This permits to invalidate the MDX loader cache entries when content changes
|
|
69
|
+
// Problem documented here: https://github.com/facebook/docusaurus/pull/10934
|
|
70
|
+
// TODO this is not a perfect solution, find better?
|
|
71
|
+
async function createMdxLoaderDependencyFile({
|
|
72
|
+
dataDir,
|
|
73
|
+
options,
|
|
74
|
+
versionsMetadata,
|
|
75
|
+
}: {
|
|
76
|
+
dataDir: string;
|
|
77
|
+
options: PluginOptions;
|
|
78
|
+
versionsMetadata: VersionMetadata[];
|
|
79
|
+
}): Promise<string | undefined> {
|
|
80
|
+
const filePath = path.join(dataDir, '__mdx-loader-dependency.json');
|
|
81
|
+
// the cache is invalidated whenever this file content changes
|
|
82
|
+
const fileContent = {
|
|
83
|
+
options,
|
|
84
|
+
versionsMetadata,
|
|
85
|
+
};
|
|
86
|
+
await fs.ensureDir(dataDir);
|
|
87
|
+
await fs.writeFile(filePath, JSON.stringify(fileContent));
|
|
88
|
+
return filePath;
|
|
89
|
+
}
|
|
90
|
+
|
|
66
91
|
export default async function pluginContentDocs(
|
|
67
92
|
context: LoadContext,
|
|
68
93
|
options: PluginOptions,
|
|
@@ -107,6 +132,14 @@ export default async function pluginContentDocs(
|
|
|
107
132
|
return createMDXLoaderRule({
|
|
108
133
|
include: contentDirs,
|
|
109
134
|
options: {
|
|
135
|
+
dependencies: [
|
|
136
|
+
await createMdxLoaderDependencyFile({
|
|
137
|
+
dataDir,
|
|
138
|
+
options,
|
|
139
|
+
versionsMetadata,
|
|
140
|
+
}),
|
|
141
|
+
].filter((d): d is string => typeof d === 'string'),
|
|
142
|
+
|
|
110
143
|
useCrossCompilerCache:
|
|
111
144
|
siteConfig.future.experimental_faster.mdxCrossCompilerCache,
|
|
112
145
|
admonitions: options.admonitions,
|
|
@@ -20,7 +20,11 @@ declare module '@docusaurus/plugin-content-docs' {
|
|
|
20
20
|
TagMetadata,
|
|
21
21
|
TagsPluginOptions,
|
|
22
22
|
} from '@docusaurus/utils';
|
|
23
|
-
import type {
|
|
23
|
+
import type {
|
|
24
|
+
Plugin,
|
|
25
|
+
LoadContext,
|
|
26
|
+
OptionValidationContext,
|
|
27
|
+
} from '@docusaurus/types';
|
|
24
28
|
import type {Overwrite, Required} from 'utility-types';
|
|
25
29
|
|
|
26
30
|
export type Assets = {
|
|
@@ -559,6 +563,10 @@ declare module '@docusaurus/plugin-content-docs' {
|
|
|
559
563
|
context: LoadContext,
|
|
560
564
|
options: PluginOptions,
|
|
561
565
|
): Promise<Plugin<LoadedContent>>;
|
|
566
|
+
|
|
567
|
+
export function validateOptions(
|
|
568
|
+
args: OptionValidationContext<Options | undefined, PluginOptions>,
|
|
569
|
+
): PluginOptions;
|
|
562
570
|
}
|
|
563
571
|
|
|
564
572
|
declare module '@theme/DocItem' {
|
package/src/versions/files.ts
CHANGED
|
@@ -75,6 +75,21 @@ export function getDocsDirPathLocalized({
|
|
|
75
75
|
});
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
export function getPluginDirPathLocalized({
|
|
79
|
+
localizationDir,
|
|
80
|
+
pluginId,
|
|
81
|
+
}: {
|
|
82
|
+
localizationDir: string;
|
|
83
|
+
pluginId: string;
|
|
84
|
+
}): string {
|
|
85
|
+
return getPluginI18nPath({
|
|
86
|
+
localizationDir,
|
|
87
|
+
pluginName: 'docusaurus-plugin-content-docs',
|
|
88
|
+
pluginId,
|
|
89
|
+
subPaths: [],
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
78
93
|
/** `community` => `[siteDir]/community_versions.json` */
|
|
79
94
|
export function getVersionsFilePath(siteDir: string, pluginId: string): string {
|
|
80
95
|
return path.join(siteDir, addPluginIdPrefix(VERSIONS_JSON_FILE, pluginId));
|