@docusaurus/plugin-content-docs 0.0.0-5262 → 0.0.0-5265
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/index.js +9 -71
- package/lib/options.js +7 -2
- package/lib/props.d.ts +3 -2
- package/lib/props.js +10 -1
- package/lib/routes.d.ts +12 -19
- package/lib/routes.js +107 -35
- package/lib/versions/index.d.ts +4 -1
- package/lib/versions/index.js +20 -1
- package/package.json +10 -9
- package/src/index.ts +12 -99
- package/src/options.ts +9 -2
- package/src/plugin-content-docs.d.ts +61 -24
- package/src/props.ts +13 -1
- package/src/routes.ts +164 -68
- package/src/versions/index.ts +25 -1
package/lib/index.js
CHANGED
|
@@ -19,10 +19,7 @@ const versions_1 = require("./versions");
|
|
|
19
19
|
const cli_1 = require("./cli");
|
|
20
20
|
const constants_1 = require("./constants");
|
|
21
21
|
const globalData_1 = require("./globalData");
|
|
22
|
-
const props_1 = require("./props");
|
|
23
|
-
const categoryGeneratedIndex_1 = require("./categoryGeneratedIndex");
|
|
24
22
|
const translations_1 = require("./translations");
|
|
25
|
-
const tags_1 = require("./tags");
|
|
26
23
|
const routes_1 = require("./routes");
|
|
27
24
|
const utils_2 = require("./sidebars/utils");
|
|
28
25
|
async function pluginContentDocs(context, options) {
|
|
@@ -125,77 +122,18 @@ async function pluginContentDocs(context, options) {
|
|
|
125
122
|
return (0, translations_1.translateLoadedContent)(content, translationFiles);
|
|
126
123
|
},
|
|
127
124
|
async contentLoaded({ content, actions }) {
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
return {
|
|
134
|
-
...version,
|
|
135
|
-
sidebarsUtils,
|
|
136
|
-
categoryGeneratedIndices: (0, categoryGeneratedIndex_1.getCategoryGeneratedIndexMetadataList)({
|
|
137
|
-
docs: version.docs,
|
|
138
|
-
sidebarsUtils,
|
|
139
|
-
}),
|
|
140
|
-
};
|
|
141
|
-
});
|
|
142
|
-
async function createVersionTagsRoutes(version) {
|
|
143
|
-
const versionTags = (0, tags_1.getVersionTags)(version.docs);
|
|
144
|
-
// TODO tags should be a sub route of the version route
|
|
145
|
-
async function createTagsListPage() {
|
|
146
|
-
const tagsProp = Object.values(versionTags).map((tagValue) => ({
|
|
147
|
-
label: tagValue.label,
|
|
148
|
-
permalink: tagValue.permalink,
|
|
149
|
-
count: tagValue.docIds.length,
|
|
150
|
-
}));
|
|
151
|
-
// Only create /tags page if there are tags.
|
|
152
|
-
if (tagsProp.length > 0) {
|
|
153
|
-
const tagsPropPath = await createData(`${(0, utils_1.docuHash)(`tags-list-${version.versionName}-prop`)}.json`, JSON.stringify(tagsProp, null, 2));
|
|
154
|
-
addRoute({
|
|
155
|
-
path: version.tagsPath,
|
|
156
|
-
exact: true,
|
|
157
|
-
component: options.docTagsListComponent,
|
|
158
|
-
modules: {
|
|
159
|
-
tags: aliasedSource(tagsPropPath),
|
|
160
|
-
},
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
// TODO tags should be a sub route of the version route
|
|
165
|
-
async function createTagDocListPage(tag) {
|
|
166
|
-
const tagProps = (0, props_1.toTagDocListProp)({
|
|
167
|
-
allTagsPath: version.tagsPath,
|
|
168
|
-
tag,
|
|
169
|
-
docs: version.docs,
|
|
170
|
-
});
|
|
171
|
-
const tagPropPath = await createData(`${(0, utils_1.docuHash)(`tag-${tag.permalink}`)}.json`, JSON.stringify(tagProps, null, 2));
|
|
172
|
-
addRoute({
|
|
173
|
-
path: tag.permalink,
|
|
174
|
-
component: options.docTagDocListComponent,
|
|
175
|
-
exact: true,
|
|
176
|
-
modules: {
|
|
177
|
-
tag: aliasedSource(tagPropPath),
|
|
178
|
-
},
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
await createTagsListPage();
|
|
182
|
-
await Promise.all(Object.values(versionTags).map(createTagDocListPage));
|
|
183
|
-
}
|
|
184
|
-
await Promise.all(versions.map((version) => (0, routes_1.createVersionRoutes)({
|
|
185
|
-
version,
|
|
186
|
-
docItemComponent,
|
|
187
|
-
docLayoutComponent,
|
|
188
|
-
docCategoryGeneratedIndexComponent,
|
|
189
|
-
pluginId,
|
|
190
|
-
aliasedSource,
|
|
125
|
+
const versions = content.loadedVersions.map(versions_1.toFullVersion);
|
|
126
|
+
await (0, routes_1.createAllRoutes)({
|
|
127
|
+
baseUrl,
|
|
128
|
+
versions,
|
|
129
|
+
options,
|
|
191
130
|
actions,
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
setGlobalData({
|
|
131
|
+
aliasedSource,
|
|
132
|
+
});
|
|
133
|
+
actions.setGlobalData({
|
|
196
134
|
path: (0, utils_1.normalizeUrl)([baseUrl, options.routeBasePath]),
|
|
197
135
|
versions: versions.map(globalData_1.toGlobalDataVersion),
|
|
198
|
-
breadcrumbs,
|
|
136
|
+
breadcrumbs: options.breadcrumbs,
|
|
199
137
|
});
|
|
200
138
|
},
|
|
201
139
|
configureWebpack(_config, isServer, utils, content) {
|
package/lib/options.js
CHANGED
|
@@ -21,7 +21,9 @@ exports.DEFAULT_OPTIONS = {
|
|
|
21
21
|
exclude: utils_1.GlobExcludeDefault,
|
|
22
22
|
sidebarItemsGenerator: generator_1.DefaultSidebarItemsGenerator,
|
|
23
23
|
numberPrefixParser: numberPrefix_1.DefaultNumberPrefixParser,
|
|
24
|
-
|
|
24
|
+
docsRootComponent: '@theme/DocsRoot',
|
|
25
|
+
docVersionRootComponent: '@theme/DocVersionRoot',
|
|
26
|
+
docRootComponent: '@theme/DocRoot',
|
|
25
27
|
docItemComponent: '@theme/DocItem',
|
|
26
28
|
docTagDocListComponent: '@theme/DocTagDocListPage',
|
|
27
29
|
docTagsListComponent: '@theme/DocTagsListPage',
|
|
@@ -49,6 +51,7 @@ const VersionOptionsSchema = utils_validation_1.Joi.object({
|
|
|
49
51
|
banner: utils_validation_1.Joi.string().equal('none', 'unreleased', 'unmaintained').optional(),
|
|
50
52
|
badge: utils_validation_1.Joi.boolean().optional(),
|
|
51
53
|
className: utils_validation_1.Joi.string().optional(),
|
|
54
|
+
noIndex: utils_validation_1.Joi.boolean().optional(),
|
|
52
55
|
});
|
|
53
56
|
const VersionsOptionsSchema = utils_validation_1.Joi.object()
|
|
54
57
|
.pattern(utils_validation_1.Joi.string().required(), VersionOptionsSchema)
|
|
@@ -80,7 +83,9 @@ const OptionsSchema = utils_validation_1.Joi.object({
|
|
|
80
83
|
then: utils_validation_1.Joi.custom((val) => val ? numberPrefix_1.DefaultNumberPrefixParser : numberPrefix_1.DisabledNumberPrefixParser),
|
|
81
84
|
}))
|
|
82
85
|
.default(() => exports.DEFAULT_OPTIONS.numberPrefixParser),
|
|
83
|
-
|
|
86
|
+
docsRootComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docsRootComponent),
|
|
87
|
+
docVersionRootComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docVersionRootComponent),
|
|
88
|
+
docRootComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docRootComponent),
|
|
84
89
|
docItemComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docItemComponent),
|
|
85
90
|
docTagsListComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docTagsListComponent),
|
|
86
91
|
docTagDocListComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docTagDocListComponent),
|
package/lib/props.d.ts
CHANGED
|
@@ -4,8 +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 { VersionTag } from './types';
|
|
8
|
-
import type { PropSidebars, PropVersionMetadata, PropTagDocList, DocMetadata, LoadedVersion } from '@docusaurus/plugin-content-docs';
|
|
7
|
+
import type { VersionTag, VersionTags } from './types';
|
|
8
|
+
import type { PropSidebars, PropVersionMetadata, PropTagDocList, PropTagsListPage, DocMetadata, LoadedVersion } from '@docusaurus/plugin-content-docs';
|
|
9
9
|
export declare function toSidebarsProp(loadedVersion: LoadedVersion): PropSidebars;
|
|
10
10
|
export declare function toVersionMetadataProp(pluginId: string, loadedVersion: LoadedVersion): PropVersionMetadata;
|
|
11
11
|
export declare function toTagDocListProp({ allTagsPath, tag, docs, }: {
|
|
@@ -13,3 +13,4 @@ export declare function toTagDocListProp({ allTagsPath, tag, docs, }: {
|
|
|
13
13
|
tag: VersionTag;
|
|
14
14
|
docs: DocMetadata[];
|
|
15
15
|
}): PropTagDocList;
|
|
16
|
+
export declare function toTagsListTagsProp(versionTags: VersionTags): PropTagsListPage['tags'];
|
package/lib/props.js
CHANGED
|
@@ -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.toTagDocListProp = exports.toVersionMetadataProp = exports.toSidebarsProp = void 0;
|
|
9
|
+
exports.toTagsListTagsProp = exports.toTagDocListProp = exports.toVersionMetadataProp = exports.toSidebarsProp = void 0;
|
|
10
10
|
const tslib_1 = require("tslib");
|
|
11
11
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
12
12
|
const docs_1 = require("./docs");
|
|
@@ -98,6 +98,7 @@ function toVersionMetadataProp(pluginId, loadedVersion) {
|
|
|
98
98
|
label: loadedVersion.label,
|
|
99
99
|
banner: loadedVersion.banner,
|
|
100
100
|
badge: loadedVersion.badge,
|
|
101
|
+
noIndex: loadedVersion.noIndex,
|
|
101
102
|
className: loadedVersion.className,
|
|
102
103
|
isLast: loadedVersion.isLast,
|
|
103
104
|
docsSidebars: toSidebarsProp(loadedVersion),
|
|
@@ -126,3 +127,11 @@ function toTagDocListProp({ allTagsPath, tag, docs, }) {
|
|
|
126
127
|
};
|
|
127
128
|
}
|
|
128
129
|
exports.toTagDocListProp = toTagDocListProp;
|
|
130
|
+
function toTagsListTagsProp(versionTags) {
|
|
131
|
+
return Object.values(versionTags).map((tagValue) => ({
|
|
132
|
+
label: tagValue.label,
|
|
133
|
+
permalink: tagValue.permalink,
|
|
134
|
+
count: tagValue.docIds.length,
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
exports.toTagsListTagsProp = toTagsListTagsProp;
|
package/lib/routes.d.ts
CHANGED
|
@@ -6,24 +6,17 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { PluginContentLoadedActions, RouteConfig } from '@docusaurus/types';
|
|
8
8
|
import type { FullVersion } from './types';
|
|
9
|
-
import type {
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
import type { PluginOptions } from '@docusaurus/plugin-content-docs';
|
|
10
|
+
declare type BuildAllRoutesParam = Omit<CreateAllRoutesParam, 'actions'> & {
|
|
11
|
+
actions: Omit<PluginContentLoadedActions, 'addRoute' | 'setGlobalData'>;
|
|
12
|
+
};
|
|
13
|
+
export declare function buildAllRoutes(param: BuildAllRoutesParam): Promise<RouteConfig[]>;
|
|
14
|
+
declare type CreateAllRoutesParam = {
|
|
15
|
+
baseUrl: string;
|
|
16
|
+
versions: FullVersion[];
|
|
17
|
+
options: PluginOptions;
|
|
12
18
|
actions: PluginContentLoadedActions;
|
|
13
|
-
docCategoryGeneratedIndexComponent: string;
|
|
14
19
|
aliasedSource: (str: string) => string;
|
|
15
|
-
}
|
|
16
|
-
export declare function
|
|
17
|
-
|
|
18
|
-
actions: PluginContentLoadedActions;
|
|
19
|
-
docItemComponent: string;
|
|
20
|
-
}): Promise<RouteConfig[]>;
|
|
21
|
-
export declare function createVersionRoutes({ version, actions, docItemComponent, docLayoutComponent, docCategoryGeneratedIndexComponent, pluginId, aliasedSource, }: {
|
|
22
|
-
version: FullVersion;
|
|
23
|
-
actions: PluginContentLoadedActions;
|
|
24
|
-
docLayoutComponent: string;
|
|
25
|
-
docItemComponent: string;
|
|
26
|
-
docCategoryGeneratedIndexComponent: string;
|
|
27
|
-
pluginId: string;
|
|
28
|
-
aliasedSource: (str: string) => string;
|
|
29
|
-
}): Promise<void>;
|
|
20
|
+
};
|
|
21
|
+
export declare function createAllRoutes(param: CreateAllRoutesParam): Promise<void>;
|
|
22
|
+
export {};
|
package/lib/routes.js
CHANGED
|
@@ -6,20 +6,22 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.
|
|
9
|
+
exports.createAllRoutes = exports.buildAllRoutes = void 0;
|
|
10
10
|
const tslib_1 = require("tslib");
|
|
11
|
+
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
11
12
|
const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
|
|
12
13
|
const utils_1 = require("@docusaurus/utils");
|
|
13
14
|
const props_1 = require("./props");
|
|
14
|
-
|
|
15
|
+
const tags_1 = require("./tags");
|
|
16
|
+
async function buildVersionCategoryGeneratedIndexRoutes({ version, actions, options, aliasedSource, }) {
|
|
15
17
|
const slugs = (0, utils_1.createSlugger)();
|
|
16
|
-
async function
|
|
18
|
+
async function buildCategoryGeneratedIndexRoute(categoryGeneratedIndex) {
|
|
17
19
|
const { sidebar, ...prop } = categoryGeneratedIndex;
|
|
18
20
|
const propFileName = slugs.slug(`${version.path}-${categoryGeneratedIndex.sidebar}-category-${categoryGeneratedIndex.title}`);
|
|
19
21
|
const propData = await actions.createData(`${(0, utils_1.docuHash)(`category/${propFileName}`)}.json`, JSON.stringify(prop, null, 2));
|
|
20
22
|
return {
|
|
21
23
|
path: categoryGeneratedIndex.permalink,
|
|
22
|
-
component: docCategoryGeneratedIndexComponent,
|
|
24
|
+
component: options.docCategoryGeneratedIndexComponent,
|
|
23
25
|
exact: true,
|
|
24
26
|
modules: {
|
|
25
27
|
categoryGeneratedIndex: aliasedSource(propData),
|
|
@@ -29,23 +31,22 @@ async function createCategoryGeneratedIndexRoutes({ version, actions, docCategor
|
|
|
29
31
|
...(sidebar && { sidebar }),
|
|
30
32
|
};
|
|
31
33
|
}
|
|
32
|
-
return Promise.all(version.categoryGeneratedIndices.map(
|
|
34
|
+
return Promise.all(version.categoryGeneratedIndices.map(buildCategoryGeneratedIndexRoute));
|
|
33
35
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return Promise.all(docs.map(async (metadataItem) => {
|
|
36
|
+
async function buildVersionDocRoutes({ version, actions, options, }) {
|
|
37
|
+
return Promise.all(version.docs.map(async (metadataItem) => {
|
|
37
38
|
await actions.createData(
|
|
38
39
|
// Note that this created data path must be in sync with
|
|
39
40
|
// metadataPath provided to mdx-loader.
|
|
40
41
|
`${(0, utils_1.docuHash)(metadataItem.source)}.json`, JSON.stringify(metadataItem, null, 2));
|
|
41
42
|
const docRoute = {
|
|
42
43
|
path: metadataItem.permalink,
|
|
43
|
-
component: docItemComponent,
|
|
44
|
+
component: options.docItemComponent,
|
|
44
45
|
exact: true,
|
|
45
46
|
modules: {
|
|
46
47
|
content: metadataItem.source,
|
|
47
48
|
},
|
|
48
|
-
// Because the parent (
|
|
49
|
+
// Because the parent (DocRoot) comp need to access it easily
|
|
49
50
|
// This permits to render the sidebar once without unmount/remount when
|
|
50
51
|
// navigating (and preserve sidebar state)
|
|
51
52
|
...(metadataItem.sidebar && {
|
|
@@ -55,42 +56,113 @@ async function createDocRoutes({ docs, actions, docItemComponent, }) {
|
|
|
55
56
|
return docRoute;
|
|
56
57
|
}));
|
|
57
58
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
59
|
+
async function buildVersionSidebarRoute(param) {
|
|
60
|
+
const [docRoutes, categoryGeneratedIndexRoutes] = await Promise.all([
|
|
61
|
+
buildVersionDocRoutes(param),
|
|
62
|
+
buildVersionCategoryGeneratedIndexRoutes(param),
|
|
63
|
+
]);
|
|
64
|
+
const subRoutes = [...docRoutes, ...categoryGeneratedIndexRoutes];
|
|
65
|
+
return {
|
|
66
|
+
path: param.version.path,
|
|
67
|
+
exact: false,
|
|
68
|
+
component: param.options.docRootComponent,
|
|
69
|
+
routes: subRoutes,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
async function buildVersionTagsRoutes(param) {
|
|
73
|
+
const { version, options, actions, aliasedSource } = param;
|
|
74
|
+
const versionTags = (0, tags_1.getVersionTags)(version.docs);
|
|
75
|
+
async function buildTagsListRoute() {
|
|
76
|
+
// Don't create a tags list page if there's no tag
|
|
77
|
+
if (Object.keys(versionTags).length === 0) {
|
|
78
|
+
return null;
|
|
75
79
|
}
|
|
76
|
-
|
|
80
|
+
const tagsProp = (0, props_1.toTagsListTagsProp)(versionTags);
|
|
81
|
+
const tagsPropPath = await actions.createData(`${(0, utils_1.docuHash)(`tags-list-${version.versionName}-prop`)}.json`, JSON.stringify(tagsProp, null, 2));
|
|
82
|
+
return {
|
|
83
|
+
path: version.tagsPath,
|
|
84
|
+
exact: true,
|
|
85
|
+
component: options.docTagsListComponent,
|
|
86
|
+
modules: {
|
|
87
|
+
tags: aliasedSource(tagsPropPath),
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
async function buildTagDocListRoute(tag) {
|
|
92
|
+
const tagProps = (0, props_1.toTagDocListProp)({
|
|
93
|
+
allTagsPath: version.tagsPath,
|
|
94
|
+
tag,
|
|
95
|
+
docs: version.docs,
|
|
96
|
+
});
|
|
97
|
+
const tagPropPath = await actions.createData(`${(0, utils_1.docuHash)(`tag-${tag.permalink}`)}.json`, JSON.stringify(tagProps, null, 2));
|
|
98
|
+
return {
|
|
99
|
+
path: tag.permalink,
|
|
100
|
+
component: options.docTagDocListComponent,
|
|
101
|
+
exact: true,
|
|
102
|
+
modules: {
|
|
103
|
+
tag: aliasedSource(tagPropPath),
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const [tagsListRoute, allTagsDocListRoutes] = await Promise.all([
|
|
108
|
+
buildTagsListRoute(),
|
|
109
|
+
Promise.all(Object.values(versionTags).map(buildTagDocListRoute)),
|
|
110
|
+
]);
|
|
111
|
+
return lodash_1.default.compact([tagsListRoute, ...allTagsDocListRoutes]);
|
|
112
|
+
}
|
|
113
|
+
async function buildVersionRoutes(param) {
|
|
114
|
+
const { version, actions, options, aliasedSource } = param;
|
|
115
|
+
async function buildVersionSubRoutes() {
|
|
116
|
+
const [sidebarRoute, tagsRoutes] = await Promise.all([
|
|
117
|
+
buildVersionSidebarRoute(param),
|
|
118
|
+
buildVersionTagsRoutes(param),
|
|
119
|
+
]);
|
|
120
|
+
return [sidebarRoute, ...tagsRoutes];
|
|
121
|
+
}
|
|
122
|
+
async function doBuildVersionRoutes() {
|
|
123
|
+
const versionProp = (0, props_1.toVersionMetadataProp)(options.id, version);
|
|
124
|
+
const versionPropPath = await actions.createData(`${(0, utils_1.docuHash)(`version-${version.versionName}-metadata-prop`)}.json`, JSON.stringify(versionProp, null, 2));
|
|
125
|
+
const subRoutes = await buildVersionSubRoutes();
|
|
126
|
+
return {
|
|
77
127
|
path: version.path,
|
|
78
|
-
// Allow matching /docs/* since this is the wrapping route
|
|
79
128
|
exact: false,
|
|
80
|
-
component:
|
|
81
|
-
routes:
|
|
129
|
+
component: options.docVersionRootComponent,
|
|
130
|
+
routes: subRoutes,
|
|
82
131
|
modules: {
|
|
83
|
-
|
|
132
|
+
version: aliasedSource(versionPropPath),
|
|
84
133
|
},
|
|
85
134
|
priority: version.routePriority,
|
|
86
|
-
}
|
|
135
|
+
};
|
|
87
136
|
}
|
|
88
137
|
try {
|
|
89
|
-
return await
|
|
138
|
+
return await doBuildVersionRoutes();
|
|
90
139
|
}
|
|
91
140
|
catch (err) {
|
|
92
141
|
logger_1.default.error `Can't create version routes for version name=${version.versionName}`;
|
|
93
142
|
throw err;
|
|
94
143
|
}
|
|
95
144
|
}
|
|
96
|
-
|
|
145
|
+
// TODO we want this buildAllRoutes function to be easily testable
|
|
146
|
+
// Ideally, we should avoid side effects here (ie not injecting actions)
|
|
147
|
+
async function buildAllRoutes(param) {
|
|
148
|
+
const subRoutes = await Promise.all(param.versions.map((version) => buildVersionRoutes({
|
|
149
|
+
...param,
|
|
150
|
+
version,
|
|
151
|
+
})));
|
|
152
|
+
// all docs routes are wrapped under a single parent route, this ensures
|
|
153
|
+
// the theme layout never unmounts/remounts when navigating between versions
|
|
154
|
+
return [
|
|
155
|
+
{
|
|
156
|
+
path: (0, utils_1.normalizeUrl)([param.baseUrl, param.options.routeBasePath]),
|
|
157
|
+
exact: false,
|
|
158
|
+
component: param.options.docsRootComponent,
|
|
159
|
+
routes: subRoutes,
|
|
160
|
+
},
|
|
161
|
+
];
|
|
162
|
+
}
|
|
163
|
+
exports.buildAllRoutes = buildAllRoutes;
|
|
164
|
+
async function createAllRoutes(param) {
|
|
165
|
+
const routes = await buildAllRoutes(param);
|
|
166
|
+
routes.forEach(param.actions.addRoute);
|
|
167
|
+
}
|
|
168
|
+
exports.createAllRoutes = createAllRoutes;
|
package/lib/versions/index.d.ts
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import type {
|
|
7
|
+
import type { FullVersion } from '../types';
|
|
8
8
|
import type { LoadContext } from '@docusaurus/types';
|
|
9
|
+
import type { LoadedVersion, PluginOptions, VersionBanner, VersionMetadata } from '@docusaurus/plugin-content-docs';
|
|
9
10
|
export declare type VersionContext = {
|
|
10
11
|
/** The version name to get banner of. */
|
|
11
12
|
versionName: string;
|
|
@@ -23,6 +24,7 @@ export declare type VersionContext = {
|
|
|
23
24
|
export declare function getDefaultVersionBanner({ versionName, versionNames, lastVersionName, }: VersionContext): VersionBanner | null;
|
|
24
25
|
export declare function getVersionBanner(context: VersionContext): VersionMetadata['banner'];
|
|
25
26
|
export declare function getVersionBadge({ versionName, versionNames, options, }: VersionContext): VersionMetadata['badge'];
|
|
27
|
+
export declare function getVersionNoIndex({ versionName, options, }: VersionContext): VersionMetadata['noIndex'];
|
|
26
28
|
/**
|
|
27
29
|
* Filter versions according to provided options (i.e. `onlyIncludeVersions`).
|
|
28
30
|
*
|
|
@@ -34,3 +36,4 @@ export declare function readVersionsMetadata({ context, options, }: {
|
|
|
34
36
|
context: LoadContext;
|
|
35
37
|
options: PluginOptions;
|
|
36
38
|
}): Promise<VersionMetadata[]>;
|
|
39
|
+
export declare function toFullVersion(version: LoadedVersion): FullVersion;
|
package/lib/versions/index.js
CHANGED
|
@@ -6,13 +6,15 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.readVersionsMetadata = exports.filterVersions = exports.getVersionBadge = exports.getVersionBanner = exports.getDefaultVersionBanner = void 0;
|
|
9
|
+
exports.toFullVersion = exports.readVersionsMetadata = exports.filterVersions = exports.getVersionNoIndex = exports.getVersionBadge = exports.getVersionBanner = exports.getDefaultVersionBanner = void 0;
|
|
10
10
|
const tslib_1 = require("tslib");
|
|
11
11
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
12
12
|
const utils_1 = require("@docusaurus/utils");
|
|
13
13
|
const constants_1 = require("../constants");
|
|
14
14
|
const validation_1 = require("./validation");
|
|
15
15
|
const files_1 = require("./files");
|
|
16
|
+
const utils_2 = require("../sidebars/utils");
|
|
17
|
+
const categoryGeneratedIndex_1 = require("../categoryGeneratedIndex");
|
|
16
18
|
function getVersionEditUrls({ contentPath, contentPathLocalized, context, options, }) {
|
|
17
19
|
// If the user is using the functional form of editUrl,
|
|
18
20
|
// she has total freedom and we can't compute a "version edit url"
|
|
@@ -71,6 +73,10 @@ function getVersionBadge({ versionName, versionNames, options, }) {
|
|
|
71
73
|
return options.versions[versionName]?.badge ?? defaultVersionBadge;
|
|
72
74
|
}
|
|
73
75
|
exports.getVersionBadge = getVersionBadge;
|
|
76
|
+
function getVersionNoIndex({ versionName, options, }) {
|
|
77
|
+
return options.versions[versionName]?.noIndex ?? false;
|
|
78
|
+
}
|
|
79
|
+
exports.getVersionNoIndex = getVersionNoIndex;
|
|
74
80
|
function getVersionClassName({ versionName, options, }) {
|
|
75
81
|
const defaultVersionClassName = `docs-version-${versionName}`;
|
|
76
82
|
return options.versions[versionName]?.className ?? defaultVersionClassName;
|
|
@@ -108,6 +114,7 @@ async function createVersionMetadata(context) {
|
|
|
108
114
|
label: getVersionLabel(context),
|
|
109
115
|
banner: getVersionBanner(context),
|
|
110
116
|
badge: getVersionBadge(context),
|
|
117
|
+
noIndex: getVersionNoIndex(context),
|
|
111
118
|
className: getVersionClassName(context),
|
|
112
119
|
path: routePath,
|
|
113
120
|
tagsPath: (0, utils_1.normalizeUrl)([routePath, options.tagsBasePath]),
|
|
@@ -152,3 +159,15 @@ async function readVersionsMetadata({ context, options, }) {
|
|
|
152
159
|
return versionsMetadata;
|
|
153
160
|
}
|
|
154
161
|
exports.readVersionsMetadata = readVersionsMetadata;
|
|
162
|
+
function toFullVersion(version) {
|
|
163
|
+
const sidebarsUtils = (0, utils_2.createSidebarsUtils)(version.sidebars);
|
|
164
|
+
return {
|
|
165
|
+
...version,
|
|
166
|
+
sidebarsUtils,
|
|
167
|
+
categoryGeneratedIndices: (0, categoryGeneratedIndex_1.getCategoryGeneratedIndexMetadataList)({
|
|
168
|
+
docs: version.docs,
|
|
169
|
+
sidebarsUtils,
|
|
170
|
+
}),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
exports.toFullVersion = toFullVersion;
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docusaurus/plugin-content-docs",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-5265",
|
|
4
4
|
"description": "Docs plugin for Docusaurus.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"exports": {
|
|
8
|
+
"./lib/*": "./lib/*",
|
|
8
9
|
"./src/*": "./src/*",
|
|
9
10
|
"./client": {
|
|
10
11
|
"type": "./lib/client/index.d.ts",
|
|
@@ -34,13 +35,13 @@
|
|
|
34
35
|
},
|
|
35
36
|
"license": "MIT",
|
|
36
37
|
"dependencies": {
|
|
37
|
-
"@docusaurus/core": "0.0.0-
|
|
38
|
-
"@docusaurus/logger": "0.0.0-
|
|
39
|
-
"@docusaurus/mdx-loader": "0.0.0-
|
|
40
|
-
"@docusaurus/module-type-aliases": "0.0.0-
|
|
41
|
-
"@docusaurus/types": "0.0.0-
|
|
42
|
-
"@docusaurus/utils": "0.0.0-
|
|
43
|
-
"@docusaurus/utils-validation": "0.0.0-
|
|
38
|
+
"@docusaurus/core": "0.0.0-5265",
|
|
39
|
+
"@docusaurus/logger": "0.0.0-5265",
|
|
40
|
+
"@docusaurus/mdx-loader": "0.0.0-5265",
|
|
41
|
+
"@docusaurus/module-type-aliases": "0.0.0-5265",
|
|
42
|
+
"@docusaurus/types": "0.0.0-5265",
|
|
43
|
+
"@docusaurus/utils": "0.0.0-5265",
|
|
44
|
+
"@docusaurus/utils-validation": "0.0.0-5265",
|
|
44
45
|
"@types/react-router-config": "^5.0.6",
|
|
45
46
|
"combine-promises": "^1.1.0",
|
|
46
47
|
"fs-extra": "^10.1.0",
|
|
@@ -66,5 +67,5 @@
|
|
|
66
67
|
"engines": {
|
|
67
68
|
"node": ">=16.14"
|
|
68
69
|
},
|
|
69
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "ac59d7c969c795c2163c8e8843c11d94e210f87f"
|
|
70
71
|
}
|
package/src/index.ts
CHANGED
|
@@ -27,22 +27,18 @@ import {
|
|
|
27
27
|
addDocNavigation,
|
|
28
28
|
type DocEnv,
|
|
29
29
|
} from './docs';
|
|
30
|
-
import {readVersionsMetadata} from './versions';
|
|
30
|
+
import {readVersionsMetadata, toFullVersion} from './versions';
|
|
31
31
|
import {cliDocsVersionCommand} from './cli';
|
|
32
32
|
import {VERSIONS_JSON_FILE} from './constants';
|
|
33
33
|
import {toGlobalDataVersion} from './globalData';
|
|
34
|
-
import {toTagDocListProp} from './props';
|
|
35
|
-
import {getCategoryGeneratedIndexMetadataList} from './categoryGeneratedIndex';
|
|
36
34
|
import {
|
|
37
35
|
translateLoadedContent,
|
|
38
36
|
getLoadedContentTranslationFiles,
|
|
39
37
|
} from './translations';
|
|
40
|
-
import {
|
|
41
|
-
import {createVersionRoutes} from './routes';
|
|
38
|
+
import {createAllRoutes} from './routes';
|
|
42
39
|
import {createSidebarsUtils} from './sidebars/utils';
|
|
43
40
|
|
|
44
41
|
import type {
|
|
45
|
-
PropTagsListPage,
|
|
46
42
|
PluginOptions,
|
|
47
43
|
DocMetadataBase,
|
|
48
44
|
VersionMetadata,
|
|
@@ -55,7 +51,6 @@ import type {
|
|
|
55
51
|
SourceToPermalink,
|
|
56
52
|
DocFile,
|
|
57
53
|
DocsMarkdownOption,
|
|
58
|
-
VersionTag,
|
|
59
54
|
FullVersion,
|
|
60
55
|
} from './types';
|
|
61
56
|
import type {RuleSetRule} from 'webpack';
|
|
@@ -209,102 +204,20 @@ export default async function pluginContentDocs(
|
|
|
209
204
|
},
|
|
210
205
|
|
|
211
206
|
async contentLoaded({content, actions}) {
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
const versions: FullVersion[] = loadedVersions.map((version) => {
|
|
221
|
-
const sidebarsUtils = createSidebarsUtils(version.sidebars);
|
|
222
|
-
return {
|
|
223
|
-
...version,
|
|
224
|
-
sidebarsUtils,
|
|
225
|
-
categoryGeneratedIndices: getCategoryGeneratedIndexMetadataList({
|
|
226
|
-
docs: version.docs,
|
|
227
|
-
sidebarsUtils,
|
|
228
|
-
}),
|
|
229
|
-
};
|
|
207
|
+
const versions: FullVersion[] = content.loadedVersions.map(toFullVersion);
|
|
208
|
+
|
|
209
|
+
await createAllRoutes({
|
|
210
|
+
baseUrl,
|
|
211
|
+
versions,
|
|
212
|
+
options,
|
|
213
|
+
actions,
|
|
214
|
+
aliasedSource,
|
|
230
215
|
});
|
|
231
216
|
|
|
232
|
-
|
|
233
|
-
const versionTags = getVersionTags(version.docs);
|
|
234
|
-
|
|
235
|
-
// TODO tags should be a sub route of the version route
|
|
236
|
-
async function createTagsListPage() {
|
|
237
|
-
const tagsProp: PropTagsListPage['tags'] = Object.values(
|
|
238
|
-
versionTags,
|
|
239
|
-
).map((tagValue) => ({
|
|
240
|
-
label: tagValue.label,
|
|
241
|
-
permalink: tagValue.permalink,
|
|
242
|
-
count: tagValue.docIds.length,
|
|
243
|
-
}));
|
|
244
|
-
|
|
245
|
-
// Only create /tags page if there are tags.
|
|
246
|
-
if (tagsProp.length > 0) {
|
|
247
|
-
const tagsPropPath = await createData(
|
|
248
|
-
`${docuHash(`tags-list-${version.versionName}-prop`)}.json`,
|
|
249
|
-
JSON.stringify(tagsProp, null, 2),
|
|
250
|
-
);
|
|
251
|
-
addRoute({
|
|
252
|
-
path: version.tagsPath,
|
|
253
|
-
exact: true,
|
|
254
|
-
component: options.docTagsListComponent,
|
|
255
|
-
modules: {
|
|
256
|
-
tags: aliasedSource(tagsPropPath),
|
|
257
|
-
},
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// TODO tags should be a sub route of the version route
|
|
263
|
-
async function createTagDocListPage(tag: VersionTag) {
|
|
264
|
-
const tagProps = toTagDocListProp({
|
|
265
|
-
allTagsPath: version.tagsPath,
|
|
266
|
-
tag,
|
|
267
|
-
docs: version.docs,
|
|
268
|
-
});
|
|
269
|
-
const tagPropPath = await createData(
|
|
270
|
-
`${docuHash(`tag-${tag.permalink}`)}.json`,
|
|
271
|
-
JSON.stringify(tagProps, null, 2),
|
|
272
|
-
);
|
|
273
|
-
addRoute({
|
|
274
|
-
path: tag.permalink,
|
|
275
|
-
component: options.docTagDocListComponent,
|
|
276
|
-
exact: true,
|
|
277
|
-
modules: {
|
|
278
|
-
tag: aliasedSource(tagPropPath),
|
|
279
|
-
},
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
await createTagsListPage();
|
|
284
|
-
await Promise.all(Object.values(versionTags).map(createTagDocListPage));
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
await Promise.all(
|
|
288
|
-
versions.map((version) =>
|
|
289
|
-
createVersionRoutes({
|
|
290
|
-
version,
|
|
291
|
-
docItemComponent,
|
|
292
|
-
docLayoutComponent,
|
|
293
|
-
docCategoryGeneratedIndexComponent,
|
|
294
|
-
pluginId,
|
|
295
|
-
aliasedSource,
|
|
296
|
-
actions,
|
|
297
|
-
}),
|
|
298
|
-
),
|
|
299
|
-
);
|
|
300
|
-
|
|
301
|
-
// TODO tags should be a sub route of the version route
|
|
302
|
-
await Promise.all(versions.map(createVersionTagsRoutes));
|
|
303
|
-
|
|
304
|
-
setGlobalData({
|
|
217
|
+
actions.setGlobalData({
|
|
305
218
|
path: normalizeUrl([baseUrl, options.routeBasePath]),
|
|
306
219
|
versions: versions.map(toGlobalDataVersion),
|
|
307
|
-
breadcrumbs,
|
|
220
|
+
breadcrumbs: options.breadcrumbs,
|
|
308
221
|
});
|
|
309
222
|
},
|
|
310
223
|
|
package/src/options.ts
CHANGED
|
@@ -30,7 +30,9 @@ export const DEFAULT_OPTIONS: Omit<PluginOptions, 'id' | 'sidebarPath'> = {
|
|
|
30
30
|
exclude: GlobExcludeDefault,
|
|
31
31
|
sidebarItemsGenerator: DefaultSidebarItemsGenerator,
|
|
32
32
|
numberPrefixParser: DefaultNumberPrefixParser,
|
|
33
|
-
|
|
33
|
+
docsRootComponent: '@theme/DocsRoot',
|
|
34
|
+
docVersionRootComponent: '@theme/DocVersionRoot',
|
|
35
|
+
docRootComponent: '@theme/DocRoot',
|
|
34
36
|
docItemComponent: '@theme/DocItem',
|
|
35
37
|
docTagDocListComponent: '@theme/DocTagDocListPage',
|
|
36
38
|
docTagsListComponent: '@theme/DocTagsListPage',
|
|
@@ -59,6 +61,7 @@ const VersionOptionsSchema = Joi.object({
|
|
|
59
61
|
banner: Joi.string().equal('none', 'unreleased', 'unmaintained').optional(),
|
|
60
62
|
badge: Joi.boolean().optional(),
|
|
61
63
|
className: Joi.string().optional(),
|
|
64
|
+
noIndex: Joi.boolean().optional(),
|
|
62
65
|
});
|
|
63
66
|
|
|
64
67
|
const VersionsOptionsSchema = Joi.object()
|
|
@@ -103,7 +106,11 @@ const OptionsSchema = Joi.object<PluginOptions>({
|
|
|
103
106
|
}),
|
|
104
107
|
)
|
|
105
108
|
.default(() => DEFAULT_OPTIONS.numberPrefixParser),
|
|
106
|
-
|
|
109
|
+
docsRootComponent: Joi.string().default(DEFAULT_OPTIONS.docsRootComponent),
|
|
110
|
+
docVersionRootComponent: Joi.string().default(
|
|
111
|
+
DEFAULT_OPTIONS.docVersionRootComponent,
|
|
112
|
+
),
|
|
113
|
+
docRootComponent: Joi.string().default(DEFAULT_OPTIONS.docRootComponent),
|
|
107
114
|
docItemComponent: Joi.string().default(DEFAULT_OPTIONS.docItemComponent),
|
|
108
115
|
docTagsListComponent: Joi.string().default(
|
|
109
116
|
DEFAULT_OPTIONS.docTagsListComponent,
|
|
@@ -125,6 +125,25 @@ declare module '@docusaurus/plugin-content-docs' {
|
|
|
125
125
|
// TODO support custom version banner?
|
|
126
126
|
// {type: "error", content: "html content"}
|
|
127
127
|
export type VersionBanner = 'unreleased' | 'unmaintained';
|
|
128
|
+
|
|
129
|
+
export type VersionOptions = {
|
|
130
|
+
/**
|
|
131
|
+
* The base path of the version, will be appended to `baseUrl` +
|
|
132
|
+
* `routeBasePath`.
|
|
133
|
+
*/
|
|
134
|
+
path?: string;
|
|
135
|
+
/** The label of the version to be used in badges, dropdowns, etc. */
|
|
136
|
+
label?: string;
|
|
137
|
+
/** The banner to show at the top of a doc of that version. */
|
|
138
|
+
banner?: 'none' | VersionBanner;
|
|
139
|
+
/** Show a badge with the version label at the top of each doc. */
|
|
140
|
+
badge?: boolean;
|
|
141
|
+
/** Prevents search engines from indexing this version */
|
|
142
|
+
noIndex?: boolean;
|
|
143
|
+
/** Add a custom class name to the <html> element of each doc. */
|
|
144
|
+
className?: string;
|
|
145
|
+
};
|
|
146
|
+
|
|
128
147
|
export type VersionsOptions = {
|
|
129
148
|
/**
|
|
130
149
|
* The version navigated to in priority and displayed by default for docs
|
|
@@ -144,23 +163,7 @@ declare module '@docusaurus/plugin-content-docs' {
|
|
|
144
163
|
/** Include the current version of your docs. */
|
|
145
164
|
includeCurrentVersion: boolean;
|
|
146
165
|
/** Independent customization of each version's properties. */
|
|
147
|
-
versions: {
|
|
148
|
-
[versionName: string]: {
|
|
149
|
-
/**
|
|
150
|
-
* The base path of the version, will be appended to `baseUrl` +
|
|
151
|
-
* `routeBasePath`.
|
|
152
|
-
*/
|
|
153
|
-
path?: string;
|
|
154
|
-
/** The label of the version to be used in badges, dropdowns, etc. */
|
|
155
|
-
label?: string;
|
|
156
|
-
/** The banner to show at the top of a doc of that version. */
|
|
157
|
-
banner?: 'none' | VersionBanner;
|
|
158
|
-
/** Show a badge with the version label at the top of each doc. */
|
|
159
|
-
badge?: boolean;
|
|
160
|
-
/** Add a custom class name to the <html> element of each doc. */
|
|
161
|
-
className?: string;
|
|
162
|
-
};
|
|
163
|
-
};
|
|
166
|
+
versions: {[versionName: string]: VersionOptions};
|
|
164
167
|
};
|
|
165
168
|
export type SidebarOptions = {
|
|
166
169
|
/**
|
|
@@ -195,10 +198,24 @@ declare module '@docusaurus/plugin-content-docs' {
|
|
|
195
198
|
*/
|
|
196
199
|
exclude: string[];
|
|
197
200
|
/**
|
|
198
|
-
*
|
|
199
|
-
*
|
|
201
|
+
* Parent component of all the docs plugin pages (including all versions).
|
|
202
|
+
* Stays mounted when navigation between docs pages and versions.
|
|
203
|
+
*/
|
|
204
|
+
docsRootComponent: string;
|
|
205
|
+
/**
|
|
206
|
+
* Parent component of all docs pages of an individual version:
|
|
207
|
+
* - docs pages with sidebars
|
|
208
|
+
* - tags pages
|
|
209
|
+
* Stays mounted when navigation between pages of that specific version.
|
|
210
|
+
*/
|
|
211
|
+
docVersionRootComponent: string;
|
|
212
|
+
/**
|
|
213
|
+
* Parent component of all docs pages with sidebars:
|
|
214
|
+
* - regular docs pages
|
|
215
|
+
* - category generated index pages
|
|
216
|
+
* Stays mounted when navigation between such pages.
|
|
200
217
|
*/
|
|
201
|
-
|
|
218
|
+
docRootComponent: string;
|
|
202
219
|
/** Main doc container, with TOC, pagination, etc. */
|
|
203
220
|
docItemComponent: string;
|
|
204
221
|
/** Root component of the "docs containing tag X" page. */
|
|
@@ -263,6 +280,8 @@ declare module '@docusaurus/plugin-content-docs' {
|
|
|
263
280
|
banner: VersionBanner | null;
|
|
264
281
|
/** Show a badge with the version label at the top of each doc. */
|
|
265
282
|
badge: boolean;
|
|
283
|
+
/** Prevents search engines from indexing this version */
|
|
284
|
+
noIndex: boolean;
|
|
266
285
|
/** Add a custom class name to the <html> element of each doc. */
|
|
267
286
|
className: string;
|
|
268
287
|
/**
|
|
@@ -500,7 +519,7 @@ declare module '@docusaurus/plugin-content-docs' {
|
|
|
500
519
|
|
|
501
520
|
export type PropVersionMetadata = Pick<
|
|
502
521
|
VersionMetadata,
|
|
503
|
-
'label' | 'banner' | 'badge' | 'className' | 'isLast'
|
|
522
|
+
'label' | 'banner' | 'badge' | 'className' | 'isLast' | 'noIndex'
|
|
504
523
|
> & {
|
|
505
524
|
/** ID of the docs plugin this version belongs to. */
|
|
506
525
|
pluginId: string;
|
|
@@ -605,14 +624,32 @@ declare module '@theme/DocBreadcrumbs' {
|
|
|
605
624
|
export default function DocBreadcrumbs(): JSX.Element;
|
|
606
625
|
}
|
|
607
626
|
|
|
608
|
-
declare module '@theme/
|
|
627
|
+
declare module '@theme/DocsRoot' {
|
|
628
|
+
import type {RouteConfigComponentProps} from 'react-router-config';
|
|
629
|
+
import type {Required} from 'utility-types';
|
|
630
|
+
|
|
631
|
+
export interface Props extends Required<RouteConfigComponentProps, 'route'> {}
|
|
632
|
+
|
|
633
|
+
export default function DocsRoot(props: Props): JSX.Element;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
declare module '@theme/DocVersionRoot' {
|
|
609
637
|
import type {PropVersionMetadata} from '@docusaurus/plugin-content-docs';
|
|
610
638
|
import type {RouteConfigComponentProps} from 'react-router-config';
|
|
611
639
|
import type {Required} from 'utility-types';
|
|
612
640
|
|
|
613
641
|
export interface Props extends Required<RouteConfigComponentProps, 'route'> {
|
|
614
|
-
readonly
|
|
642
|
+
readonly version: PropVersionMetadata;
|
|
615
643
|
}
|
|
616
644
|
|
|
617
|
-
export default function
|
|
645
|
+
export default function DocVersionRoot(props: Props): JSX.Element;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
declare module '@theme/DocRoot' {
|
|
649
|
+
import type {RouteConfigComponentProps} from 'react-router-config';
|
|
650
|
+
import type {Required} from 'utility-types';
|
|
651
|
+
|
|
652
|
+
export interface Props extends Required<RouteConfigComponentProps, 'route'> {}
|
|
653
|
+
|
|
654
|
+
export default function DocRoot(props: Props): JSX.Element;
|
|
618
655
|
}
|
package/src/props.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import _ from 'lodash';
|
|
9
9
|
import {createDocsByIdIndex} from './docs';
|
|
10
|
-
import type {VersionTag} from './types';
|
|
10
|
+
import type {VersionTag, VersionTags} from './types';
|
|
11
11
|
import type {
|
|
12
12
|
SidebarItemDoc,
|
|
13
13
|
SidebarItem,
|
|
@@ -21,6 +21,7 @@ import type {
|
|
|
21
21
|
PropSidebarItemCategory,
|
|
22
22
|
PropTagDocList,
|
|
23
23
|
PropTagDocListDoc,
|
|
24
|
+
PropTagsListPage,
|
|
24
25
|
PropSidebarItemLink,
|
|
25
26
|
PropVersionDocs,
|
|
26
27
|
DocMetadata,
|
|
@@ -142,6 +143,7 @@ export function toVersionMetadataProp(
|
|
|
142
143
|
label: loadedVersion.label,
|
|
143
144
|
banner: loadedVersion.banner,
|
|
144
145
|
badge: loadedVersion.badge,
|
|
146
|
+
noIndex: loadedVersion.noIndex,
|
|
145
147
|
className: loadedVersion.className,
|
|
146
148
|
isLast: loadedVersion.isLast,
|
|
147
149
|
docsSidebars: toSidebarsProp(loadedVersion),
|
|
@@ -180,3 +182,13 @@ export function toTagDocListProp({
|
|
|
180
182
|
items: toDocListProp(),
|
|
181
183
|
};
|
|
182
184
|
}
|
|
185
|
+
|
|
186
|
+
export function toTagsListTagsProp(
|
|
187
|
+
versionTags: VersionTags,
|
|
188
|
+
): PropTagsListPage['tags'] {
|
|
189
|
+
return Object.values(versionTags).map((tagValue) => ({
|
|
190
|
+
label: tagValue.label,
|
|
191
|
+
permalink: tagValue.permalink,
|
|
192
|
+
count: tagValue.docIds.length,
|
|
193
|
+
}));
|
|
194
|
+
}
|
package/src/routes.ts
CHANGED
|
@@ -5,30 +5,32 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import _ from 'lodash';
|
|
8
9
|
import logger from '@docusaurus/logger';
|
|
9
|
-
import {docuHash, createSlugger} from '@docusaurus/utils';
|
|
10
|
-
import {
|
|
10
|
+
import {docuHash, createSlugger, normalizeUrl} from '@docusaurus/utils';
|
|
11
|
+
import {
|
|
12
|
+
toTagDocListProp,
|
|
13
|
+
toTagsListTagsProp,
|
|
14
|
+
toVersionMetadataProp,
|
|
15
|
+
} from './props';
|
|
16
|
+
import {getVersionTags} from './tags';
|
|
11
17
|
import type {PluginContentLoadedActions, RouteConfig} from '@docusaurus/types';
|
|
12
|
-
import type {FullVersion} from './types';
|
|
18
|
+
import type {FullVersion, VersionTag} from './types';
|
|
13
19
|
import type {
|
|
14
20
|
CategoryGeneratedIndexMetadata,
|
|
15
|
-
|
|
21
|
+
PluginOptions,
|
|
22
|
+
PropTagsListPage,
|
|
16
23
|
} from '@docusaurus/plugin-content-docs';
|
|
17
24
|
|
|
18
|
-
|
|
25
|
+
async function buildVersionCategoryGeneratedIndexRoutes({
|
|
19
26
|
version,
|
|
20
27
|
actions,
|
|
21
|
-
|
|
28
|
+
options,
|
|
22
29
|
aliasedSource,
|
|
23
|
-
}: {
|
|
24
|
-
version: FullVersion;
|
|
25
|
-
actions: PluginContentLoadedActions;
|
|
26
|
-
docCategoryGeneratedIndexComponent: string;
|
|
27
|
-
aliasedSource: (str: string) => string;
|
|
28
|
-
}): Promise<RouteConfig[]> {
|
|
30
|
+
}: BuildVersionRoutesParam): Promise<RouteConfig[]> {
|
|
29
31
|
const slugs = createSlugger();
|
|
30
32
|
|
|
31
|
-
async function
|
|
33
|
+
async function buildCategoryGeneratedIndexRoute(
|
|
32
34
|
categoryGeneratedIndex: CategoryGeneratedIndexMetadata,
|
|
33
35
|
): Promise<RouteConfig> {
|
|
34
36
|
const {sidebar, ...prop} = categoryGeneratedIndex;
|
|
@@ -44,7 +46,7 @@ export async function createCategoryGeneratedIndexRoutes({
|
|
|
44
46
|
|
|
45
47
|
return {
|
|
46
48
|
path: categoryGeneratedIndex.permalink,
|
|
47
|
-
component: docCategoryGeneratedIndexComponent,
|
|
49
|
+
component: options.docCategoryGeneratedIndexComponent,
|
|
48
50
|
exact: true,
|
|
49
51
|
modules: {
|
|
50
52
|
categoryGeneratedIndex: aliasedSource(propData),
|
|
@@ -56,21 +58,17 @@ export async function createCategoryGeneratedIndexRoutes({
|
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
return Promise.all(
|
|
59
|
-
version.categoryGeneratedIndices.map(
|
|
61
|
+
version.categoryGeneratedIndices.map(buildCategoryGeneratedIndexRoute),
|
|
60
62
|
);
|
|
61
63
|
}
|
|
62
64
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
async function buildVersionDocRoutes({
|
|
66
|
+
version,
|
|
65
67
|
actions,
|
|
66
|
-
|
|
67
|
-
}: {
|
|
68
|
-
docs: DocMetadata[];
|
|
69
|
-
actions: PluginContentLoadedActions;
|
|
70
|
-
docItemComponent: string;
|
|
71
|
-
}): Promise<RouteConfig[]> {
|
|
68
|
+
options,
|
|
69
|
+
}: BuildVersionRoutesParam): Promise<RouteConfig[]> {
|
|
72
70
|
return Promise.all(
|
|
73
|
-
docs.map(async (metadataItem) => {
|
|
71
|
+
version.docs.map(async (metadataItem) => {
|
|
74
72
|
await actions.createData(
|
|
75
73
|
// Note that this created data path must be in sync with
|
|
76
74
|
// metadataPath provided to mdx-loader.
|
|
@@ -80,12 +78,12 @@ export async function createDocRoutes({
|
|
|
80
78
|
|
|
81
79
|
const docRoute: RouteConfig = {
|
|
82
80
|
path: metadataItem.permalink,
|
|
83
|
-
component: docItemComponent,
|
|
81
|
+
component: options.docItemComponent,
|
|
84
82
|
exact: true,
|
|
85
83
|
modules: {
|
|
86
84
|
content: metadataItem.source,
|
|
87
85
|
},
|
|
88
|
-
// Because the parent (
|
|
86
|
+
// Because the parent (DocRoot) comp need to access it easily
|
|
89
87
|
// This permits to render the sidebar once without unmount/remount when
|
|
90
88
|
// navigating (and preserve sidebar state)
|
|
91
89
|
...(metadataItem.sidebar && {
|
|
@@ -98,62 +96,160 @@ export async function createDocRoutes({
|
|
|
98
96
|
);
|
|
99
97
|
}
|
|
100
98
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
docCategoryGeneratedIndexComponent: string;
|
|
115
|
-
pluginId: string;
|
|
116
|
-
aliasedSource: (str: string) => string;
|
|
117
|
-
}): Promise<void> {
|
|
118
|
-
async function doCreateVersionRoutes(): Promise<void> {
|
|
119
|
-
const versionMetadata = toVersionMetadataProp(pluginId, version);
|
|
120
|
-
const versionMetadataPropPath = await actions.createData(
|
|
121
|
-
`${docuHash(`version-${version.versionName}-metadata-prop`)}.json`,
|
|
122
|
-
JSON.stringify(versionMetadata, null, 2),
|
|
123
|
-
);
|
|
99
|
+
async function buildVersionSidebarRoute(param: BuildVersionRoutesParam) {
|
|
100
|
+
const [docRoutes, categoryGeneratedIndexRoutes] = await Promise.all([
|
|
101
|
+
buildVersionDocRoutes(param),
|
|
102
|
+
buildVersionCategoryGeneratedIndexRoutes(param),
|
|
103
|
+
]);
|
|
104
|
+
const subRoutes = [...docRoutes, ...categoryGeneratedIndexRoutes];
|
|
105
|
+
return {
|
|
106
|
+
path: param.version.path,
|
|
107
|
+
exact: false,
|
|
108
|
+
component: param.options.docRootComponent,
|
|
109
|
+
routes: subRoutes,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
124
112
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
actions,
|
|
131
|
-
docCategoryGeneratedIndexComponent,
|
|
132
|
-
aliasedSource,
|
|
133
|
-
}),
|
|
134
|
-
]);
|
|
113
|
+
async function buildVersionTagsRoutes(
|
|
114
|
+
param: BuildVersionRoutesParam,
|
|
115
|
+
): Promise<RouteConfig[]> {
|
|
116
|
+
const {version, options, actions, aliasedSource} = param;
|
|
117
|
+
const versionTags = getVersionTags(version.docs);
|
|
135
118
|
|
|
136
|
-
|
|
137
|
-
|
|
119
|
+
async function buildTagsListRoute(): Promise<RouteConfig | null> {
|
|
120
|
+
// Don't create a tags list page if there's no tag
|
|
121
|
+
if (Object.keys(versionTags).length === 0) {
|
|
122
|
+
return null;
|
|
138
123
|
}
|
|
124
|
+
const tagsProp: PropTagsListPage['tags'] = toTagsListTagsProp(versionTags);
|
|
125
|
+
const tagsPropPath = await actions.createData(
|
|
126
|
+
`${docuHash(`tags-list-${version.versionName}-prop`)}.json`,
|
|
127
|
+
JSON.stringify(tagsProp, null, 2),
|
|
128
|
+
);
|
|
129
|
+
return {
|
|
130
|
+
path: version.tagsPath,
|
|
131
|
+
exact: true,
|
|
132
|
+
component: options.docTagsListComponent,
|
|
133
|
+
modules: {
|
|
134
|
+
tags: aliasedSource(tagsPropPath),
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async function buildTagDocListRoute(tag: VersionTag): Promise<RouteConfig> {
|
|
140
|
+
const tagProps = toTagDocListProp({
|
|
141
|
+
allTagsPath: version.tagsPath,
|
|
142
|
+
tag,
|
|
143
|
+
docs: version.docs,
|
|
144
|
+
});
|
|
145
|
+
const tagPropPath = await actions.createData(
|
|
146
|
+
`${docuHash(`tag-${tag.permalink}`)}.json`,
|
|
147
|
+
JSON.stringify(tagProps, null, 2),
|
|
148
|
+
);
|
|
149
|
+
return {
|
|
150
|
+
path: tag.permalink,
|
|
151
|
+
component: options.docTagDocListComponent,
|
|
152
|
+
exact: true,
|
|
153
|
+
modules: {
|
|
154
|
+
tag: aliasedSource(tagPropPath),
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const [tagsListRoute, allTagsDocListRoutes] = await Promise.all([
|
|
160
|
+
buildTagsListRoute(),
|
|
161
|
+
Promise.all(Object.values(versionTags).map(buildTagDocListRoute)),
|
|
162
|
+
]);
|
|
163
|
+
|
|
164
|
+
return _.compact([tagsListRoute, ...allTagsDocListRoutes]);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
type BuildVersionRoutesParam = Omit<BuildAllRoutesParam, 'versions'> & {
|
|
168
|
+
version: FullVersion;
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
async function buildVersionRoutes(
|
|
172
|
+
param: BuildVersionRoutesParam,
|
|
173
|
+
): Promise<RouteConfig> {
|
|
174
|
+
const {version, actions, options, aliasedSource} = param;
|
|
139
175
|
|
|
140
|
-
|
|
176
|
+
async function buildVersionSubRoutes() {
|
|
177
|
+
const [sidebarRoute, tagsRoutes] = await Promise.all([
|
|
178
|
+
buildVersionSidebarRoute(param),
|
|
179
|
+
buildVersionTagsRoutes(param),
|
|
180
|
+
]);
|
|
181
|
+
|
|
182
|
+
return [sidebarRoute, ...tagsRoutes];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async function doBuildVersionRoutes(): Promise<RouteConfig> {
|
|
186
|
+
const versionProp = toVersionMetadataProp(options.id, version);
|
|
187
|
+
const versionPropPath = await actions.createData(
|
|
188
|
+
`${docuHash(`version-${version.versionName}-metadata-prop`)}.json`,
|
|
189
|
+
JSON.stringify(versionProp, null, 2),
|
|
190
|
+
);
|
|
191
|
+
const subRoutes = await buildVersionSubRoutes();
|
|
192
|
+
return {
|
|
141
193
|
path: version.path,
|
|
142
|
-
// Allow matching /docs/* since this is the wrapping route
|
|
143
194
|
exact: false,
|
|
144
|
-
component:
|
|
145
|
-
routes:
|
|
195
|
+
component: options.docVersionRootComponent,
|
|
196
|
+
routes: subRoutes,
|
|
146
197
|
modules: {
|
|
147
|
-
|
|
198
|
+
version: aliasedSource(versionPropPath),
|
|
148
199
|
},
|
|
149
200
|
priority: version.routePriority,
|
|
150
|
-
}
|
|
201
|
+
};
|
|
151
202
|
}
|
|
152
203
|
|
|
153
204
|
try {
|
|
154
|
-
return await
|
|
205
|
+
return await doBuildVersionRoutes();
|
|
155
206
|
} catch (err) {
|
|
156
207
|
logger.error`Can't create version routes for version name=${version.versionName}`;
|
|
157
208
|
throw err;
|
|
158
209
|
}
|
|
159
210
|
}
|
|
211
|
+
|
|
212
|
+
type BuildAllRoutesParam = Omit<CreateAllRoutesParam, 'actions'> & {
|
|
213
|
+
actions: Omit<PluginContentLoadedActions, 'addRoute' | 'setGlobalData'>;
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
// TODO we want this buildAllRoutes function to be easily testable
|
|
217
|
+
// Ideally, we should avoid side effects here (ie not injecting actions)
|
|
218
|
+
export async function buildAllRoutes(
|
|
219
|
+
param: BuildAllRoutesParam,
|
|
220
|
+
): Promise<RouteConfig[]> {
|
|
221
|
+
const subRoutes = await Promise.all(
|
|
222
|
+
param.versions.map((version) =>
|
|
223
|
+
buildVersionRoutes({
|
|
224
|
+
...param,
|
|
225
|
+
version,
|
|
226
|
+
}),
|
|
227
|
+
),
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
// all docs routes are wrapped under a single parent route, this ensures
|
|
231
|
+
// the theme layout never unmounts/remounts when navigating between versions
|
|
232
|
+
return [
|
|
233
|
+
{
|
|
234
|
+
path: normalizeUrl([param.baseUrl, param.options.routeBasePath]),
|
|
235
|
+
exact: false,
|
|
236
|
+
component: param.options.docsRootComponent,
|
|
237
|
+
routes: subRoutes,
|
|
238
|
+
},
|
|
239
|
+
];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
type CreateAllRoutesParam = {
|
|
243
|
+
baseUrl: string;
|
|
244
|
+
versions: FullVersion[];
|
|
245
|
+
options: PluginOptions;
|
|
246
|
+
actions: PluginContentLoadedActions;
|
|
247
|
+
aliasedSource: (str: string) => string;
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
export async function createAllRoutes(
|
|
251
|
+
param: CreateAllRoutesParam,
|
|
252
|
+
): Promise<void> {
|
|
253
|
+
const routes = await buildAllRoutes(param);
|
|
254
|
+
routes.forEach(param.actions.addRoute);
|
|
255
|
+
}
|
package/src/versions/index.ts
CHANGED
|
@@ -14,12 +14,16 @@ import {
|
|
|
14
14
|
getVersionMetadataPaths,
|
|
15
15
|
readVersionNames,
|
|
16
16
|
} from './files';
|
|
17
|
+
import {createSidebarsUtils} from '../sidebars/utils';
|
|
18
|
+
import {getCategoryGeneratedIndexMetadataList} from '../categoryGeneratedIndex';
|
|
19
|
+
import type {FullVersion} from '../types';
|
|
20
|
+
import type {LoadContext} from '@docusaurus/types';
|
|
17
21
|
import type {
|
|
22
|
+
LoadedVersion,
|
|
18
23
|
PluginOptions,
|
|
19
24
|
VersionBanner,
|
|
20
25
|
VersionMetadata,
|
|
21
26
|
} from '@docusaurus/plugin-content-docs';
|
|
22
|
-
import type {LoadContext} from '@docusaurus/types';
|
|
23
27
|
|
|
24
28
|
export type VersionContext = {
|
|
25
29
|
/** The version name to get banner of. */
|
|
@@ -122,6 +126,13 @@ export function getVersionBadge({
|
|
|
122
126
|
return options.versions[versionName]?.badge ?? defaultVersionBadge;
|
|
123
127
|
}
|
|
124
128
|
|
|
129
|
+
export function getVersionNoIndex({
|
|
130
|
+
versionName,
|
|
131
|
+
options,
|
|
132
|
+
}: VersionContext): VersionMetadata['noIndex'] {
|
|
133
|
+
return options.versions[versionName]?.noIndex ?? false;
|
|
134
|
+
}
|
|
135
|
+
|
|
125
136
|
function getVersionClassName({
|
|
126
137
|
versionName,
|
|
127
138
|
options,
|
|
@@ -179,6 +190,7 @@ async function createVersionMetadata(
|
|
|
179
190
|
label: getVersionLabel(context),
|
|
180
191
|
banner: getVersionBanner(context),
|
|
181
192
|
badge: getVersionBadge(context),
|
|
193
|
+
noIndex: getVersionNoIndex(context),
|
|
182
194
|
className: getVersionClassName(context),
|
|
183
195
|
path: routePath,
|
|
184
196
|
tagsPath: normalizeUrl([routePath, options.tagsBasePath]),
|
|
@@ -244,3 +256,15 @@ export async function readVersionsMetadata({
|
|
|
244
256
|
);
|
|
245
257
|
return versionsMetadata;
|
|
246
258
|
}
|
|
259
|
+
|
|
260
|
+
export function toFullVersion(version: LoadedVersion): FullVersion {
|
|
261
|
+
const sidebarsUtils = createSidebarsUtils(version.sidebars);
|
|
262
|
+
return {
|
|
263
|
+
...version,
|
|
264
|
+
sidebarsUtils,
|
|
265
|
+
categoryGeneratedIndices: getCategoryGeneratedIndexMetadataList({
|
|
266
|
+
docs: version.docs,
|
|
267
|
+
sidebarsUtils,
|
|
268
|
+
}),
|
|
269
|
+
};
|
|
270
|
+
}
|