@docusaurus/plugin-content-docs 2.4.1 → 3.0.0-beta.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/client/index.d.ts +9 -8
- package/lib/docs.d.ts +5 -4
- package/lib/docs.js +26 -44
- package/lib/frontMatter.js +3 -2
- package/lib/globalData.js +6 -3
- package/lib/index.js +30 -75
- package/lib/options.js +7 -6
- package/lib/props.d.ts +8 -2
- package/lib/props.js +37 -13
- package/lib/routes.d.ts +12 -19
- package/lib/routes.js +107 -35
- package/lib/sidebars/generator.js +2 -1
- package/lib/sidebars/postProcessor.d.ts +1 -1
- package/lib/sidebars/postProcessor.js +1 -2
- package/lib/sidebars/processor.js +0 -1
- package/lib/sidebars/types.d.ts +49 -47
- package/lib/sidebars/utils.d.ts +17 -5
- package/lib/sidebars/utils.js +78 -14
- package/lib/tags.js +12 -5
- package/lib/translations.js +2 -21
- package/lib/types.d.ts +8 -7
- package/lib/versions/index.d.ts +4 -2
- package/lib/versions/index.js +15 -1
- package/package.json +15 -15
- package/src/client/index.ts +2 -1
- package/src/docs.ts +36 -73
- package/src/frontMatter.ts +4 -2
- package/src/globalData.ts +8 -6
- package/src/index.ts +35 -105
- package/src/options.ts +10 -6
- package/src/plugin-content-docs.d.ts +47 -14
- package/src/props.ts +61 -18
- package/src/routes.ts +164 -68
- package/src/sidebars/generator.ts +6 -1
- package/src/sidebars/postProcessor.ts +1 -2
- package/src/sidebars/processor.ts +0 -1
- package/src/sidebars/types.ts +7 -1
- package/src/sidebars/utils.ts +151 -24
- package/src/tags.ts +13 -6
- package/src/translations.ts +4 -28
- package/src/types.ts +1 -0
- package/src/versions/index.ts +17 -1
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
|
+
}
|
|
@@ -138,7 +138,11 @@ Available doc IDs:
|
|
|
138
138
|
): WithPosition<SidebarItemDoc> {
|
|
139
139
|
const {
|
|
140
140
|
sidebarPosition: position,
|
|
141
|
-
frontMatter: {
|
|
141
|
+
frontMatter: {
|
|
142
|
+
sidebar_label: label,
|
|
143
|
+
sidebar_class_name: className,
|
|
144
|
+
sidebar_custom_props: customProps,
|
|
145
|
+
},
|
|
142
146
|
} = getDoc(id);
|
|
143
147
|
return {
|
|
144
148
|
type: 'doc',
|
|
@@ -149,6 +153,7 @@ Available doc IDs:
|
|
|
149
153
|
// sidebar
|
|
150
154
|
...(label !== undefined && {label}),
|
|
151
155
|
...(className !== undefined && {className}),
|
|
156
|
+
...(customProps !== undefined && {customProps}),
|
|
152
157
|
};
|
|
153
158
|
}
|
|
154
159
|
function createCategoryItem(
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
import _ from 'lodash';
|
|
9
9
|
import {normalizeUrl} from '@docusaurus/utils';
|
|
10
|
-
import {getDocIds} from '../docs';
|
|
11
10
|
import type {
|
|
12
11
|
SidebarItem,
|
|
13
12
|
Sidebars,
|
|
@@ -102,7 +101,7 @@ export function postProcessSidebars(
|
|
|
102
101
|
sidebars: ProcessedSidebars,
|
|
103
102
|
params: SidebarProcessorParams,
|
|
104
103
|
): Sidebars {
|
|
105
|
-
const draftIds = new Set(params.drafts.
|
|
104
|
+
const draftIds = new Set(params.drafts.map((d) => d.id));
|
|
106
105
|
|
|
107
106
|
return _.mapValues(sidebars, (sidebar) =>
|
|
108
107
|
sidebar
|
package/src/sidebars/types.ts
CHANGED
|
@@ -185,11 +185,18 @@ export type PropSidebarItemCategory = Expand<
|
|
|
185
185
|
SidebarItemCategoryBase & {
|
|
186
186
|
items: PropSidebarItem[];
|
|
187
187
|
href?: string;
|
|
188
|
+
|
|
189
|
+
// Weird name => it would have been more convenient to have link.unlisted
|
|
190
|
+
// Note it is the category link that is unlisted, not the category itself
|
|
191
|
+
// We want to prevent users from clicking on an unlisted category link
|
|
192
|
+
// We can't use "href: undefined" otherwise sidebar item is not highlighted
|
|
193
|
+
linkUnlisted?: boolean;
|
|
188
194
|
}
|
|
189
195
|
>;
|
|
190
196
|
|
|
191
197
|
export type PropSidebarItemLink = SidebarItemLink & {
|
|
192
198
|
docId?: string;
|
|
199
|
+
unlisted?: boolean;
|
|
193
200
|
};
|
|
194
201
|
|
|
195
202
|
export type PropSidebarItemHtml = SidebarItemHtml;
|
|
@@ -228,7 +235,6 @@ export type CategoryMetadataFile = {
|
|
|
228
235
|
export type SidebarItemsGeneratorDoc = Pick<
|
|
229
236
|
DocMetadataBase,
|
|
230
237
|
| 'id'
|
|
231
|
-
| 'unversionedId'
|
|
232
238
|
| 'title'
|
|
233
239
|
| 'frontMatter'
|
|
234
240
|
| 'source'
|
package/src/sidebars/utils.ts
CHANGED
|
@@ -23,6 +23,7 @@ import type {
|
|
|
23
23
|
import type {
|
|
24
24
|
DocMetadataBase,
|
|
25
25
|
PropNavigationLink,
|
|
26
|
+
VersionMetadata,
|
|
26
27
|
} from '@docusaurus/plugin-content-docs';
|
|
27
28
|
|
|
28
29
|
export function isCategoriesShorthand(
|
|
@@ -135,11 +136,11 @@ export type SidebarsUtils = {
|
|
|
135
136
|
sidebars: Sidebars;
|
|
136
137
|
getFirstDocIdOfFirstSidebar: () => string | undefined;
|
|
137
138
|
getSidebarNameByDocId: (docId: string) => string | undefined;
|
|
138
|
-
getDocNavigation: (
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
) => SidebarNavigation;
|
|
139
|
+
getDocNavigation: (params: {
|
|
140
|
+
docId: string;
|
|
141
|
+
displayedSidebar: string | null | undefined;
|
|
142
|
+
unlistedIds: Set<string>;
|
|
143
|
+
}) => SidebarNavigation;
|
|
143
144
|
getCategoryGeneratedIndexList: () => SidebarItemCategoryWithGeneratedIndex[];
|
|
144
145
|
getCategoryGeneratedIndexNavigation: (
|
|
145
146
|
categoryGeneratedIndexPermalink: string,
|
|
@@ -162,7 +163,22 @@ export type SidebarsUtils = {
|
|
|
162
163
|
}
|
|
163
164
|
| undefined;
|
|
164
165
|
|
|
165
|
-
|
|
166
|
+
checkLegacyVersionedSidebarNames: ({
|
|
167
|
+
versionMetadata,
|
|
168
|
+
}: {
|
|
169
|
+
sidebarFilePath: string;
|
|
170
|
+
versionMetadata: VersionMetadata;
|
|
171
|
+
}) => void;
|
|
172
|
+
|
|
173
|
+
checkSidebarsDocIds: ({
|
|
174
|
+
allDocIds,
|
|
175
|
+
sidebarFilePath,
|
|
176
|
+
versionMetadata,
|
|
177
|
+
}: {
|
|
178
|
+
allDocIds: string[];
|
|
179
|
+
sidebarFilePath: string;
|
|
180
|
+
versionMetadata: VersionMetadata;
|
|
181
|
+
}) => void;
|
|
166
182
|
};
|
|
167
183
|
|
|
168
184
|
export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils {
|
|
@@ -192,31 +208,45 @@ export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils {
|
|
|
192
208
|
};
|
|
193
209
|
}
|
|
194
210
|
|
|
195
|
-
function getDocNavigation(
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
211
|
+
function getDocNavigation({
|
|
212
|
+
docId,
|
|
213
|
+
displayedSidebar,
|
|
214
|
+
unlistedIds,
|
|
215
|
+
}: {
|
|
216
|
+
docId: string;
|
|
217
|
+
displayedSidebar: string | null | undefined;
|
|
218
|
+
unlistedIds: Set<string>;
|
|
219
|
+
}): SidebarNavigation {
|
|
220
|
+
const sidebarName =
|
|
203
221
|
displayedSidebar === undefined
|
|
204
222
|
? getSidebarNameByDocId(docId)
|
|
205
223
|
: displayedSidebar;
|
|
206
|
-
if (sidebarName === undefined) {
|
|
207
|
-
docId = versionedId;
|
|
208
|
-
sidebarName = getSidebarNameByDocId(docId);
|
|
209
|
-
}
|
|
210
224
|
|
|
211
225
|
if (!sidebarName) {
|
|
212
226
|
return emptySidebarNavigation();
|
|
213
227
|
}
|
|
214
|
-
|
|
228
|
+
let navigationItems = sidebarNameToNavigationItems[sidebarName];
|
|
215
229
|
if (!navigationItems) {
|
|
216
230
|
throw new Error(
|
|
217
231
|
`Doc with ID ${docId} wants to display sidebar ${sidebarName} but a sidebar with this name doesn't exist`,
|
|
218
232
|
);
|
|
219
233
|
}
|
|
234
|
+
|
|
235
|
+
// Filter unlisted items from navigation
|
|
236
|
+
navigationItems = navigationItems.filter((item) => {
|
|
237
|
+
if (item.type === 'doc' && unlistedIds.has(item.id)) {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
if (
|
|
241
|
+
item.type === 'category' &&
|
|
242
|
+
item.link.type === 'doc' &&
|
|
243
|
+
unlistedIds.has(item.link.id)
|
|
244
|
+
) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
return true;
|
|
248
|
+
});
|
|
249
|
+
|
|
220
250
|
const currentItemIndex = navigationItems.findIndex((item) => {
|
|
221
251
|
if (item.type === 'doc') {
|
|
222
252
|
return item.id === docId;
|
|
@@ -280,19 +310,115 @@ export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils {
|
|
|
280
310
|
};
|
|
281
311
|
}
|
|
282
312
|
|
|
283
|
-
|
|
313
|
+
// TODO remove in Docusaurus v4
|
|
314
|
+
function getLegacyVersionedPrefix(versionMetadata: VersionMetadata): string {
|
|
315
|
+
return `version-${versionMetadata.versionName}/`;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// In early v2, sidebar names used to be versioned
|
|
319
|
+
// example: "version-2.0.0-alpha.66/my-sidebar-name"
|
|
320
|
+
// In v3 it's not the case anymore and we throw an error to explain
|
|
321
|
+
// TODO remove in Docusaurus v4
|
|
322
|
+
function checkLegacyVersionedSidebarNames({
|
|
323
|
+
versionMetadata,
|
|
324
|
+
sidebarFilePath,
|
|
325
|
+
}: {
|
|
326
|
+
versionMetadata: VersionMetadata;
|
|
327
|
+
sidebarFilePath: string;
|
|
328
|
+
}): void {
|
|
329
|
+
const illegalPrefix = getLegacyVersionedPrefix(versionMetadata);
|
|
330
|
+
const legacySidebarNames = Object.keys(sidebars).filter((sidebarName) =>
|
|
331
|
+
sidebarName.startsWith(illegalPrefix),
|
|
332
|
+
);
|
|
333
|
+
if (legacySidebarNames.length > 0) {
|
|
334
|
+
throw new Error(
|
|
335
|
+
`Invalid sidebar file at "${toMessageRelativeFilePath(
|
|
336
|
+
sidebarFilePath,
|
|
337
|
+
)}".
|
|
338
|
+
These legacy versioned sidebar names are not supported anymore in Docusaurus v3:
|
|
339
|
+
- ${legacySidebarNames.sort().join('\n- ')}
|
|
340
|
+
|
|
341
|
+
The sidebar names you should now use are:
|
|
342
|
+
- ${legacySidebarNames
|
|
343
|
+
.sort()
|
|
344
|
+
.map((legacyName) => legacyName.split('/').splice(1).join('/'))
|
|
345
|
+
.join('\n- ')}
|
|
346
|
+
|
|
347
|
+
Please remove the "${illegalPrefix}" prefix from your versioned sidebar file.
|
|
348
|
+
This breaking change is documented on Docusaurus v3 release notes: https://docusaurus.io/blog/releases/3.0
|
|
349
|
+
`,
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// throw a better error message for Docusaurus v3 breaking change
|
|
355
|
+
// TODO this can be removed in Docusaurus v4
|
|
356
|
+
function handleLegacyVersionedDocIds({
|
|
357
|
+
invalidDocIds,
|
|
358
|
+
sidebarFilePath,
|
|
359
|
+
versionMetadata,
|
|
360
|
+
}: {
|
|
361
|
+
invalidDocIds: string[];
|
|
362
|
+
sidebarFilePath: string;
|
|
363
|
+
versionMetadata: VersionMetadata;
|
|
364
|
+
}) {
|
|
365
|
+
const illegalPrefix = getLegacyVersionedPrefix(versionMetadata);
|
|
366
|
+
|
|
367
|
+
// In older v2.0 alpha/betas, versioned docs had a legacy versioned prefix
|
|
368
|
+
// Example: "version-1.4/my-doc-id"
|
|
369
|
+
//
|
|
370
|
+
const legacyVersionedDocIds = invalidDocIds.filter((docId) =>
|
|
371
|
+
docId.startsWith(illegalPrefix),
|
|
372
|
+
);
|
|
373
|
+
if (legacyVersionedDocIds.length > 0) {
|
|
374
|
+
throw new Error(
|
|
375
|
+
`Invalid sidebar file at "${toMessageRelativeFilePath(
|
|
376
|
+
sidebarFilePath,
|
|
377
|
+
)}".
|
|
378
|
+
These legacy versioned document ids are not supported anymore in Docusaurus v3:
|
|
379
|
+
- ${legacyVersionedDocIds.sort().join('\n- ')}
|
|
380
|
+
|
|
381
|
+
The document ids you should now use are:
|
|
382
|
+
- ${legacyVersionedDocIds
|
|
383
|
+
.sort()
|
|
384
|
+
.map((legacyId) => legacyId.split('/').splice(1).join('/'))
|
|
385
|
+
.join('\n- ')}
|
|
386
|
+
|
|
387
|
+
Please remove the "${illegalPrefix}" prefix from your versioned sidebar file.
|
|
388
|
+
This breaking change is documented on Docusaurus v3 release notes: https://docusaurus.io/blog/releases/3.0
|
|
389
|
+
`,
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function checkSidebarsDocIds({
|
|
395
|
+
allDocIds,
|
|
396
|
+
sidebarFilePath,
|
|
397
|
+
versionMetadata,
|
|
398
|
+
}: {
|
|
399
|
+
allDocIds: string[];
|
|
400
|
+
sidebarFilePath: string;
|
|
401
|
+
versionMetadata: VersionMetadata;
|
|
402
|
+
}) {
|
|
284
403
|
const allSidebarDocIds = Object.values(sidebarNameToDocIds).flat();
|
|
285
|
-
const
|
|
286
|
-
|
|
404
|
+
const invalidDocIds = _.difference(allSidebarDocIds, allDocIds);
|
|
405
|
+
|
|
406
|
+
if (invalidDocIds.length > 0) {
|
|
407
|
+
handleLegacyVersionedDocIds({
|
|
408
|
+
invalidDocIds,
|
|
409
|
+
sidebarFilePath,
|
|
410
|
+
versionMetadata,
|
|
411
|
+
});
|
|
287
412
|
throw new Error(
|
|
288
413
|
`Invalid sidebar file at "${toMessageRelativeFilePath(
|
|
289
414
|
sidebarFilePath,
|
|
290
415
|
)}".
|
|
291
416
|
These sidebar document ids do not exist:
|
|
292
|
-
- ${
|
|
417
|
+
- ${invalidDocIds.sort().join('\n- ')}
|
|
293
418
|
|
|
294
419
|
Available document ids are:
|
|
295
|
-
- ${_.uniq(
|
|
420
|
+
- ${_.uniq(allDocIds).sort().join('\n- ')}
|
|
421
|
+
`,
|
|
296
422
|
);
|
|
297
423
|
}
|
|
298
424
|
}
|
|
@@ -346,6 +472,7 @@ Available document ids are:
|
|
|
346
472
|
getDocNavigation,
|
|
347
473
|
getCategoryGeneratedIndexList,
|
|
348
474
|
getCategoryGeneratedIndexNavigation,
|
|
475
|
+
checkLegacyVersionedSidebarNames,
|
|
349
476
|
checkSidebarsDocIds,
|
|
350
477
|
getFirstLink: (id) => getFirstLink(sidebars[id]!),
|
|
351
478
|
};
|
package/src/tags.ts
CHANGED
|
@@ -6,15 +6,22 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import _ from 'lodash';
|
|
9
|
-
import {groupTaggedItems} from '@docusaurus/utils';
|
|
9
|
+
import {getTagVisibility, groupTaggedItems} from '@docusaurus/utils';
|
|
10
10
|
import type {VersionTags} from './types';
|
|
11
11
|
import type {DocMetadata} from '@docusaurus/plugin-content-docs';
|
|
12
12
|
|
|
13
13
|
export function getVersionTags(docs: DocMetadata[]): VersionTags {
|
|
14
14
|
const groups = groupTaggedItems(docs, (doc) => doc.tags);
|
|
15
|
-
return _.mapValues(groups, (
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
return _.mapValues(groups, ({tag, items: tagDocs}) => {
|
|
16
|
+
const tagVisibility = getTagVisibility({
|
|
17
|
+
items: tagDocs,
|
|
18
|
+
isUnlisted: (item) => item.unlisted,
|
|
19
|
+
});
|
|
20
|
+
return {
|
|
21
|
+
label: tag.label,
|
|
22
|
+
docIds: tagVisibility.listedItems.map((item) => item.id),
|
|
23
|
+
permalink: tag.permalink,
|
|
24
|
+
unlisted: tagVisibility.unlisted,
|
|
25
|
+
};
|
|
26
|
+
});
|
|
20
27
|
}
|
package/src/translations.ts
CHANGED
|
@@ -40,23 +40,6 @@ function getVersionFileName(versionName: string): string {
|
|
|
40
40
|
return `version-${versionName}`;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
// TODO legacy, the sidebar name is like "version-2.0.0-alpha.66/docs"
|
|
44
|
-
// input: "version-2.0.0-alpha.66/docs"
|
|
45
|
-
// output: "docs"
|
|
46
|
-
function getNormalizedSidebarName({
|
|
47
|
-
versionName,
|
|
48
|
-
sidebarName,
|
|
49
|
-
}: {
|
|
50
|
-
versionName: string;
|
|
51
|
-
sidebarName: string;
|
|
52
|
-
}): string {
|
|
53
|
-
if (versionName === CURRENT_VERSION_NAME || !sidebarName.includes('/')) {
|
|
54
|
-
return sidebarName;
|
|
55
|
-
}
|
|
56
|
-
const [, ...rest] = sidebarName.split('/');
|
|
57
|
-
return rest.join('/');
|
|
58
|
-
}
|
|
59
|
-
|
|
60
43
|
function getSidebarTranslationFileContent(
|
|
61
44
|
sidebar: Sidebar,
|
|
62
45
|
sidebarName: string,
|
|
@@ -199,13 +182,9 @@ function getSidebarsTranslations(
|
|
|
199
182
|
version: LoadedVersion,
|
|
200
183
|
): TranslationFileContent {
|
|
201
184
|
return mergeTranslations(
|
|
202
|
-
Object.entries(version.sidebars).map(([sidebarName, sidebar]) =>
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
versionName: version.versionName,
|
|
206
|
-
});
|
|
207
|
-
return getSidebarTranslationFileContent(sidebar, normalizedSidebarName);
|
|
208
|
-
}),
|
|
185
|
+
Object.entries(version.sidebars).map(([sidebarName, sidebar]) =>
|
|
186
|
+
getSidebarTranslationFileContent(sidebar, sidebarName),
|
|
187
|
+
),
|
|
209
188
|
);
|
|
210
189
|
}
|
|
211
190
|
function translateSidebars(
|
|
@@ -215,10 +194,7 @@ function translateSidebars(
|
|
|
215
194
|
return _.mapValues(version.sidebars, (sidebar, sidebarName) =>
|
|
216
195
|
translateSidebar({
|
|
217
196
|
sidebar,
|
|
218
|
-
sidebarName
|
|
219
|
-
sidebarName,
|
|
220
|
-
versionName: version.versionName,
|
|
221
|
-
}),
|
|
197
|
+
sidebarName,
|
|
222
198
|
sidebarsTranslations,
|
|
223
199
|
}),
|
|
224
200
|
);
|