@docusaurus/plugin-content-docs 2.0.0-beta.14 → 2.0.0-beta.15
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/categoryGeneratedIndex.d.ts +2 -2
- package/lib/categoryGeneratedIndex.js +2 -0
- package/lib/cli.d.ts +1 -1
- package/lib/client/docsClientUtils.d.ts +3 -22
- package/lib/client/docsClientUtils.js +5 -1
- package/lib/{theme/hooks/useDocs.d.ts → client/globalDataHooks.d.ts} +1 -2
- package/lib/{theme/hooks/useDocs.js → client/globalDataHooks.js} +2 -1
- package/lib/client/index.d.ts +7 -0
- package/lib/client/index.js +10 -0
- package/lib/docFrontMatter.js +1 -0
- package/lib/docs.d.ts +19 -6
- package/lib/docs.js +37 -17
- package/lib/globalData.d.ts +5 -1
- package/lib/globalData.js +34 -2
- package/lib/index.d.ts +3 -2
- package/lib/index.js +2 -8
- package/lib/lastUpdate.js +2 -2
- package/lib/markdown/index.d.ts +1 -1
- package/lib/markdown/linkify.d.ts +1 -1
- package/lib/numberPrefix.d.ts +1 -1
- package/lib/options.d.ts +1 -1
- package/lib/routes.d.ts +4 -3
- package/lib/routes.js +6 -3
- package/lib/sidebars/generator.js +12 -14
- package/lib/sidebars/index.d.ts +3 -2
- package/lib/sidebars/processor.d.ts +3 -2
- package/lib/sidebars/processor.js +2 -0
- package/lib/sidebars/types.d.ts +8 -3
- package/lib/sidebars/utils.d.ts +12 -4
- package/lib/sidebars/utils.js +48 -3
- package/lib/sidebars/validation.d.ts +1 -1
- package/lib/sidebars/validation.js +4 -0
- package/lib/slug.d.ts +5 -4
- package/lib/slug.js +8 -7
- package/lib/translations.js +1 -1
- package/lib/types.d.ts +7 -78
- package/lib/versions.d.ts +3 -2
- package/lib/versions.js +27 -32
- package/package.json +14 -12
- package/src/categoryGeneratedIndex.ts +5 -3
- package/src/cli.ts +4 -1
- package/src/client/docsClientUtils.ts +22 -35
- package/src/{theme/hooks/useDocs.ts → client/globalDataHooks.ts} +6 -2
- package/src/client/index.ts +8 -0
- package/src/docFrontMatter.ts +2 -1
- package/src/docs.ts +62 -29
- package/src/globalData.ts +49 -3
- package/src/index.ts +9 -15
- package/src/lastUpdate.ts +2 -2
- package/src/markdown/index.ts +1 -1
- package/src/markdown/linkify.ts +1 -1
- package/src/numberPrefix.ts +1 -1
- package/src/options.ts +1 -1
- package/src/plugin-content-docs.d.ts +128 -18
- package/src/routes.ts +19 -5
- package/src/sidebars/generator.ts +25 -20
- package/src/sidebars/index.ts +3 -2
- package/src/sidebars/normalization.ts +2 -1
- package/src/sidebars/processor.ts +8 -7
- package/src/sidebars/types.ts +9 -5
- package/src/sidebars/utils.ts +76 -8
- package/src/sidebars/validation.ts +6 -1
- package/src/slug.ts +15 -11
- package/src/translations.ts +2 -2
- package/src/types.ts +12 -98
- package/src/versions.ts +51 -47
package/src/routes.ts
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {PluginContentLoadedActions, RouteConfig} from '@docusaurus/types';
|
|
8
|
+
import type {PluginContentLoadedActions, RouteConfig} from '@docusaurus/types';
|
|
9
9
|
import {docuHash, createSlugger} from '@docusaurus/utils';
|
|
10
|
-
import {
|
|
10
|
+
import type {
|
|
11
11
|
CategoryGeneratedIndexMetadata,
|
|
12
12
|
DocMetadata,
|
|
13
13
|
LoadedVersion,
|
|
@@ -20,18 +20,29 @@ export async function createCategoryGeneratedIndexRoutes({
|
|
|
20
20
|
version,
|
|
21
21
|
actions,
|
|
22
22
|
docCategoryGeneratedIndexComponent,
|
|
23
|
+
aliasedSource,
|
|
23
24
|
}: {
|
|
24
25
|
version: LoadedVersion;
|
|
25
26
|
actions: PluginContentLoadedActions;
|
|
26
27
|
docCategoryGeneratedIndexComponent: string;
|
|
28
|
+
aliasedSource: (str: string) => string;
|
|
27
29
|
}): Promise<RouteConfig[]> {
|
|
28
30
|
const slugs = createSlugger();
|
|
29
31
|
|
|
30
32
|
async function createCategoryGeneratedIndexRoute(
|
|
31
33
|
categoryGeneratedIndex: CategoryGeneratedIndexMetadata,
|
|
32
34
|
): Promise<RouteConfig> {
|
|
33
|
-
const {
|
|
34
|
-
|
|
35
|
+
const {
|
|
36
|
+
sidebar,
|
|
37
|
+
title,
|
|
38
|
+
description,
|
|
39
|
+
slug,
|
|
40
|
+
permalink,
|
|
41
|
+
previous,
|
|
42
|
+
next,
|
|
43
|
+
image,
|
|
44
|
+
keywords,
|
|
45
|
+
} = categoryGeneratedIndex;
|
|
35
46
|
|
|
36
47
|
const propFileName = slugs.slug(
|
|
37
48
|
`${version.versionPath}-${categoryGeneratedIndex.sidebar}-category-${categoryGeneratedIndex.title}`,
|
|
@@ -42,6 +53,8 @@ export async function createCategoryGeneratedIndexRoutes({
|
|
|
42
53
|
description,
|
|
43
54
|
slug,
|
|
44
55
|
permalink,
|
|
56
|
+
image,
|
|
57
|
+
keywords,
|
|
45
58
|
navigation: {
|
|
46
59
|
previous,
|
|
47
60
|
next,
|
|
@@ -58,7 +71,7 @@ export async function createCategoryGeneratedIndexRoutes({
|
|
|
58
71
|
component: docCategoryGeneratedIndexComponent,
|
|
59
72
|
exact: true,
|
|
60
73
|
modules: {
|
|
61
|
-
categoryGeneratedIndex: propData,
|
|
74
|
+
categoryGeneratedIndex: aliasedSource(propData),
|
|
62
75
|
},
|
|
63
76
|
// Same as doc, this sidebar route attribute permits to associate this subpage to the given sidebar
|
|
64
77
|
...(sidebar && {sidebar}),
|
|
@@ -138,6 +151,7 @@ export async function createVersionRoutes({
|
|
|
138
151
|
version,
|
|
139
152
|
actions,
|
|
140
153
|
docCategoryGeneratedIndexComponent,
|
|
154
|
+
aliasedSource,
|
|
141
155
|
}),
|
|
142
156
|
]);
|
|
143
157
|
|
|
@@ -15,13 +15,17 @@ import type {
|
|
|
15
15
|
SidebarItemCategoryLinkConfig,
|
|
16
16
|
} from './types';
|
|
17
17
|
import {sortBy, last} from 'lodash';
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
addTrailingSlash,
|
|
20
|
+
posixPath,
|
|
21
|
+
findAsyncSequential,
|
|
22
|
+
} from '@docusaurus/utils';
|
|
19
23
|
import logger from '@docusaurus/logger';
|
|
20
24
|
import path from 'path';
|
|
21
25
|
import fs from 'fs-extra';
|
|
22
26
|
import Yaml from 'js-yaml';
|
|
23
27
|
import {validateCategoryMetadataFile} from './validation';
|
|
24
|
-
import {createDocsByIdIndex,
|
|
28
|
+
import {createDocsByIdIndex, toCategoryIndexMatcherParam} from '../docs';
|
|
25
29
|
|
|
26
30
|
const BreadcrumbSeparator = '/';
|
|
27
31
|
// To avoid possible name clashes with a folder of the same name as the ID
|
|
@@ -76,22 +80,21 @@ async function readCategoryMetadataFile(
|
|
|
76
80
|
throw e;
|
|
77
81
|
}
|
|
78
82
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
return null;
|
|
83
|
+
const filePath = await findAsyncSequential(
|
|
84
|
+
['.json', '.yml', '.yaml'].map((ext) =>
|
|
85
|
+
posixPath(
|
|
86
|
+
path.join(categoryDirPath, `${CategoryMetadataFilenameBase}${ext}`),
|
|
87
|
+
),
|
|
88
|
+
),
|
|
89
|
+
fs.pathExists,
|
|
90
|
+
);
|
|
91
|
+
return filePath ? tryReadFile(filePath) : null;
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
// Comment for this feature: https://github.com/facebook/docusaurus/issues/3464#issuecomment-818670449
|
|
93
95
|
export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
|
|
94
96
|
numberPrefixParser,
|
|
97
|
+
isCategoryIndex,
|
|
95
98
|
docs: allDocs,
|
|
96
99
|
options,
|
|
97
100
|
item: {dirName: autogenDir},
|
|
@@ -154,13 +157,12 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
|
|
|
154
157
|
docs.forEach((doc) => {
|
|
155
158
|
const breadcrumb = getRelativeBreadcrumb(doc);
|
|
156
159
|
let currentDir = treeRoot; // We walk down the file's path to generate the fs structure
|
|
157
|
-
|
|
158
|
-
for (const dir of breadcrumb) {
|
|
160
|
+
breadcrumb.forEach((dir) => {
|
|
159
161
|
if (typeof currentDir[dir] === 'undefined') {
|
|
160
162
|
currentDir[dir] = {}; // Create new folder.
|
|
161
163
|
}
|
|
162
164
|
currentDir = currentDir[dir]!; // Go into the subdirectory.
|
|
163
|
-
}
|
|
165
|
+
});
|
|
164
166
|
currentDir[`${docIdPrefix}${doc.id}`] = null; // We've walked through the file path. Register the file in this directory.
|
|
165
167
|
});
|
|
166
168
|
return treeRoot;
|
|
@@ -209,10 +211,13 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
|
|
|
209
211
|
}
|
|
210
212
|
|
|
211
213
|
function findConventionalCategoryDocLink(): SidebarItemDoc | undefined {
|
|
212
|
-
return allItems.find(
|
|
213
|
-
(item)
|
|
214
|
-
|
|
215
|
-
|
|
214
|
+
return allItems.find((item) => {
|
|
215
|
+
if (item.type !== 'doc') {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
const doc = getDoc(item.id);
|
|
219
|
+
return isCategoryIndex(toCategoryIndexMatcherParam(doc));
|
|
220
|
+
}) as SidebarItemDoc | undefined;
|
|
216
221
|
}
|
|
217
222
|
|
|
218
223
|
function getCategoryLinkedDocId(): string | undefined {
|
package/src/sidebars/index.ts
CHANGED
|
@@ -8,12 +8,13 @@
|
|
|
8
8
|
import fs from 'fs-extra';
|
|
9
9
|
import importFresh from 'import-fresh';
|
|
10
10
|
import type {SidebarsConfig, Sidebars, NormalizedSidebars} from './types';
|
|
11
|
-
import type {NormalizeSidebarsParams
|
|
11
|
+
import type {NormalizeSidebarsParams} from '../types';
|
|
12
12
|
import {validateSidebars} from './validation';
|
|
13
13
|
import {normalizeSidebars} from './normalization';
|
|
14
|
-
import {processSidebars, SidebarProcessorParams} from './processor';
|
|
14
|
+
import {processSidebars, type SidebarProcessorParams} from './processor';
|
|
15
15
|
import path from 'path';
|
|
16
16
|
import {createSlugger} from '@docusaurus/utils';
|
|
17
|
+
import type {PluginOptions} from '@docusaurus/plugin-content-docs';
|
|
17
18
|
|
|
18
19
|
export const DefaultSidebars: SidebarsConfig = {
|
|
19
20
|
defaultSidebar: [
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type {NormalizeSidebarsParams
|
|
8
|
+
import type {NormalizeSidebarsParams} from '../types';
|
|
9
9
|
import type {
|
|
10
10
|
NormalizedSidebarItem,
|
|
11
11
|
NormalizedSidebar,
|
|
@@ -21,6 +21,7 @@ import type {
|
|
|
21
21
|
import {isCategoriesShorthand} from './utils';
|
|
22
22
|
import {mapValues} from 'lodash';
|
|
23
23
|
import {normalizeUrl} from '@docusaurus/utils';
|
|
24
|
+
import type {SidebarOptions} from '@docusaurus/plugin-content-docs';
|
|
24
25
|
|
|
25
26
|
function normalizeCategoryLink(
|
|
26
27
|
category: SidebarItemCategoryConfig,
|
|
@@ -5,12 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type {
|
|
9
|
-
NumberPrefixParser,
|
|
10
|
-
DocMetadataBase,
|
|
11
|
-
VersionMetadata,
|
|
12
|
-
SidebarOptions,
|
|
13
|
-
} from '../types';
|
|
8
|
+
import type {DocMetadataBase, VersionMetadata} from '../types';
|
|
14
9
|
import type {
|
|
15
10
|
Sidebars,
|
|
16
11
|
Sidebar,
|
|
@@ -30,7 +25,12 @@ import {DefaultSidebarItemsGenerator} from './generator';
|
|
|
30
25
|
import {mapValues, memoize, pick} from 'lodash';
|
|
31
26
|
import combinePromises from 'combine-promises';
|
|
32
27
|
import {normalizeItem} from './normalization';
|
|
33
|
-
import {
|
|
28
|
+
import {isCategoryIndex} from '../docs';
|
|
29
|
+
import type {Slugger} from '@docusaurus/utils';
|
|
30
|
+
import type {
|
|
31
|
+
NumberPrefixParser,
|
|
32
|
+
SidebarOptions,
|
|
33
|
+
} from '@docusaurus/plugin-content-docs';
|
|
34
34
|
|
|
35
35
|
export type SidebarProcessorParams = {
|
|
36
36
|
sidebarItemsGenerator: SidebarItemsGeneratorOption;
|
|
@@ -96,6 +96,7 @@ async function processSidebar(
|
|
|
96
96
|
item,
|
|
97
97
|
numberPrefixParser,
|
|
98
98
|
defaultSidebarItemsGenerator: DefaultSidebarItemsGenerator,
|
|
99
|
+
isCategoryIndex,
|
|
99
100
|
...getSidebarItemsGeneratorDocsAndVersion(),
|
|
100
101
|
options: sidebarOptions,
|
|
101
102
|
});
|
package/src/sidebars/types.ts
CHANGED
|
@@ -5,14 +5,13 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type {Optional} from 'utility-types';
|
|
8
|
+
import type {Optional, Required} from 'utility-types';
|
|
9
|
+
import type {DocMetadataBase, VersionMetadata} from '../types';
|
|
9
10
|
import type {
|
|
10
|
-
DocMetadataBase,
|
|
11
|
-
VersionMetadata,
|
|
12
11
|
NumberPrefixParser,
|
|
13
12
|
SidebarOptions,
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
CategoryIndexMatcher,
|
|
14
|
+
} from '@docusaurus/plugin-content-docs';
|
|
16
15
|
|
|
17
16
|
// Makes all properties visible when hovering over the type
|
|
18
17
|
type Expand<T extends Record<string, unknown>> = {[P in keyof T]: T[P]};
|
|
@@ -53,6 +52,8 @@ export type SidebarItemCategoryLinkGeneratedIndexConfig = {
|
|
|
53
52
|
slug?: string;
|
|
54
53
|
title?: string;
|
|
55
54
|
description?: string;
|
|
55
|
+
image?: string;
|
|
56
|
+
keywords?: string | readonly string[];
|
|
56
57
|
};
|
|
57
58
|
export type SidebarItemCategoryLinkGeneratedIndex = {
|
|
58
59
|
type: 'generated-index';
|
|
@@ -60,6 +61,8 @@ export type SidebarItemCategoryLinkGeneratedIndex = {
|
|
|
60
61
|
permalink: string;
|
|
61
62
|
title?: string;
|
|
62
63
|
description?: string;
|
|
64
|
+
image?: string;
|
|
65
|
+
keywords?: string | readonly string[];
|
|
63
66
|
};
|
|
64
67
|
|
|
65
68
|
export type SidebarItemCategoryLinkConfig =
|
|
@@ -193,6 +196,7 @@ export type SidebarItemsGeneratorArgs = {
|
|
|
193
196
|
version: SidebarItemsGeneratorVersion;
|
|
194
197
|
docs: SidebarItemsGeneratorDoc[];
|
|
195
198
|
numberPrefixParser: NumberPrefixParser;
|
|
199
|
+
isCategoryIndex: CategoryIndexMatcher;
|
|
196
200
|
options: SidebarOptions;
|
|
197
201
|
};
|
|
198
202
|
export type SidebarItemsGenerator = (
|
package/src/sidebars/utils.ts
CHANGED
|
@@ -15,17 +15,15 @@ import type {
|
|
|
15
15
|
SidebarItemType,
|
|
16
16
|
SidebarCategoriesShorthand,
|
|
17
17
|
SidebarItemConfig,
|
|
18
|
-
} from './types';
|
|
19
|
-
|
|
20
|
-
import {mapValues, difference, uniq} from 'lodash';
|
|
21
|
-
import {getElementsAround, toMessageRelativeFilePath} from '@docusaurus/utils';
|
|
22
|
-
import {DocMetadataBase, DocNavLink} from '../types';
|
|
23
|
-
import {
|
|
24
18
|
SidebarItemCategoryWithGeneratedIndex,
|
|
25
19
|
SidebarItemCategoryWithLink,
|
|
26
20
|
SidebarNavigationItem,
|
|
27
21
|
} from './types';
|
|
28
22
|
|
|
23
|
+
import {mapValues, difference, uniq} from 'lodash';
|
|
24
|
+
import {getElementsAround, toMessageRelativeFilePath} from '@docusaurus/utils';
|
|
25
|
+
import type {DocMetadataBase, DocNavLink} from '../types';
|
|
26
|
+
|
|
29
27
|
export function isCategoriesShorthand(
|
|
30
28
|
item: SidebarItemConfig,
|
|
31
29
|
): item is SidebarCategoriesShorthand {
|
|
@@ -133,11 +131,24 @@ export type SidebarsUtils = {
|
|
|
133
131
|
getDocNavigation: (
|
|
134
132
|
unversionedId: string,
|
|
135
133
|
versionedId: string,
|
|
134
|
+
displayedSidebar: string | null | undefined,
|
|
136
135
|
) => SidebarNavigation;
|
|
137
136
|
getCategoryGeneratedIndexList: () => SidebarItemCategoryWithGeneratedIndex[];
|
|
138
137
|
getCategoryGeneratedIndexNavigation: (
|
|
139
138
|
categoryGeneratedIndexPermalink: string,
|
|
140
139
|
) => SidebarNavigation;
|
|
140
|
+
getFirstLink: (sidebarId: string) =>
|
|
141
|
+
| {
|
|
142
|
+
type: 'doc';
|
|
143
|
+
id: string;
|
|
144
|
+
label: string;
|
|
145
|
+
}
|
|
146
|
+
| {
|
|
147
|
+
type: 'generated-index';
|
|
148
|
+
slug: string;
|
|
149
|
+
label: string;
|
|
150
|
+
}
|
|
151
|
+
| undefined;
|
|
141
152
|
|
|
142
153
|
checkSidebarsDocIds: (validDocIds: string[], sidebarFilePath: string) => void;
|
|
143
154
|
};
|
|
@@ -172,16 +183,25 @@ export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils {
|
|
|
172
183
|
function getDocNavigation(
|
|
173
184
|
unversionedId: string,
|
|
174
185
|
versionedId: string,
|
|
186
|
+
displayedSidebar: string | null | undefined,
|
|
175
187
|
): SidebarNavigation {
|
|
176
188
|
// TODO legacy id retro-compatibility!
|
|
177
189
|
let docId = unversionedId;
|
|
178
|
-
let sidebarName =
|
|
179
|
-
|
|
190
|
+
let sidebarName =
|
|
191
|
+
displayedSidebar === undefined
|
|
192
|
+
? getSidebarNameByDocId(docId)
|
|
193
|
+
: displayedSidebar;
|
|
194
|
+
if (sidebarName === undefined) {
|
|
180
195
|
docId = versionedId;
|
|
181
196
|
sidebarName = getSidebarNameByDocId(docId);
|
|
182
197
|
}
|
|
183
198
|
|
|
184
199
|
if (sidebarName) {
|
|
200
|
+
if (!sidebarNameToNavigationItems[sidebarName]) {
|
|
201
|
+
throw new Error(
|
|
202
|
+
`Doc with ID ${docId} wants to display sidebar ${sidebarName} but a sidebar with this name doesn't exist`,
|
|
203
|
+
);
|
|
204
|
+
}
|
|
185
205
|
const navigationItems = sidebarNameToNavigationItems[sidebarName];
|
|
186
206
|
const currentItemIndex = navigationItems.findIndex((item) => {
|
|
187
207
|
if (item.type === 'doc') {
|
|
@@ -192,6 +212,9 @@ export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils {
|
|
|
192
212
|
}
|
|
193
213
|
return false;
|
|
194
214
|
});
|
|
215
|
+
if (currentItemIndex === -1) {
|
|
216
|
+
return {sidebarName, next: undefined, previous: undefined};
|
|
217
|
+
}
|
|
195
218
|
|
|
196
219
|
const {previous, next} = getElementsAround(
|
|
197
220
|
navigationItems,
|
|
@@ -266,6 +289,50 @@ Available document ids are:
|
|
|
266
289
|
}
|
|
267
290
|
}
|
|
268
291
|
|
|
292
|
+
function getFirstLink(sidebar: Sidebar):
|
|
293
|
+
| {
|
|
294
|
+
type: 'doc';
|
|
295
|
+
id: string;
|
|
296
|
+
label: string;
|
|
297
|
+
}
|
|
298
|
+
| {
|
|
299
|
+
type: 'generated-index';
|
|
300
|
+
slug: string;
|
|
301
|
+
label: string;
|
|
302
|
+
}
|
|
303
|
+
| undefined {
|
|
304
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
305
|
+
for (const item of sidebar) {
|
|
306
|
+
if (item.type === 'doc') {
|
|
307
|
+
return {
|
|
308
|
+
type: 'doc',
|
|
309
|
+
id: item.id,
|
|
310
|
+
label: item.label ?? item.id,
|
|
311
|
+
};
|
|
312
|
+
} else if (item.type === 'category') {
|
|
313
|
+
if (item.link?.type === 'doc') {
|
|
314
|
+
return {
|
|
315
|
+
type: 'doc',
|
|
316
|
+
id: item.link.id,
|
|
317
|
+
label: item.label,
|
|
318
|
+
};
|
|
319
|
+
} else if (item.link?.type === 'generated-index') {
|
|
320
|
+
return {
|
|
321
|
+
type: 'generated-index',
|
|
322
|
+
slug: item.link.slug,
|
|
323
|
+
label: item.label,
|
|
324
|
+
};
|
|
325
|
+
} else {
|
|
326
|
+
const firstSubItem = getFirstLink(item.items);
|
|
327
|
+
if (firstSubItem) {
|
|
328
|
+
return firstSubItem;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return undefined;
|
|
334
|
+
}
|
|
335
|
+
|
|
269
336
|
return {
|
|
270
337
|
sidebars,
|
|
271
338
|
getFirstDocIdOfFirstSidebar,
|
|
@@ -274,6 +341,7 @@ Available document ids are:
|
|
|
274
341
|
getCategoryGeneratedIndexList,
|
|
275
342
|
getCategoryGeneratedIndexNavigation,
|
|
276
343
|
checkSidebarsDocIds,
|
|
344
|
+
getFirstLink: (id) => getFirstLink(sidebars[id]),
|
|
277
345
|
};
|
|
278
346
|
}
|
|
279
347
|
|
|
@@ -20,7 +20,10 @@ import type {
|
|
|
20
20
|
SidebarItemCategoryLinkGeneratedIndex,
|
|
21
21
|
} from './types';
|
|
22
22
|
import {isCategoriesShorthand} from './utils';
|
|
23
|
-
import {CategoryMetadataFile} from './generator';
|
|
23
|
+
import type {CategoryMetadataFile} from './generator';
|
|
24
|
+
|
|
25
|
+
// NOTE: we don't add any default values during validation on purpose!
|
|
26
|
+
// Config types are exposed to users for typechecking and we use the same type in normalization
|
|
24
27
|
|
|
25
28
|
const sidebarItemBaseSchema = Joi.object<SidebarItemBase>({
|
|
26
29
|
className: Joi.string(),
|
|
@@ -70,6 +73,8 @@ const sidebarItemCategoryLinkSchema = Joi.object<SidebarItemCategoryLink>()
|
|
|
70
73
|
// permalink: Joi.string().optional(), // No, this one is not in the user config, only in the normalized version
|
|
71
74
|
title: Joi.string().optional(),
|
|
72
75
|
description: Joi.string().optional(),
|
|
76
|
+
image: Joi.string().optional(),
|
|
77
|
+
keywords: [Joi.string(), Joi.array().items(Joi.string())],
|
|
73
78
|
}),
|
|
74
79
|
},
|
|
75
80
|
{
|
package/src/slug.ts
CHANGED
|
@@ -15,20 +15,21 @@ import {
|
|
|
15
15
|
DefaultNumberPrefixParser,
|
|
16
16
|
stripPathNumberPrefixes,
|
|
17
17
|
} from './numberPrefix';
|
|
18
|
-
import type {DocMetadataBase
|
|
19
|
-
import {
|
|
18
|
+
import type {DocMetadataBase} from './types';
|
|
19
|
+
import {isCategoryIndex, toCategoryIndexMatcherParam} from './docs';
|
|
20
|
+
import type {NumberPrefixParser} from '@docusaurus/plugin-content-docs';
|
|
20
21
|
|
|
21
22
|
export default function getSlug({
|
|
22
23
|
baseID,
|
|
23
|
-
|
|
24
|
+
frontMatterSlug,
|
|
24
25
|
source,
|
|
25
26
|
sourceDirName,
|
|
26
27
|
stripDirNumberPrefixes = true,
|
|
27
28
|
numberPrefixParser = DefaultNumberPrefixParser,
|
|
28
29
|
}: {
|
|
29
30
|
baseID: string;
|
|
30
|
-
|
|
31
|
-
source: DocMetadataBase['
|
|
31
|
+
frontMatterSlug?: string;
|
|
32
|
+
source: DocMetadataBase['source'];
|
|
32
33
|
sourceDirName: DocMetadataBase['sourceDirName'];
|
|
33
34
|
stripDirNumberPrefixes?: boolean;
|
|
34
35
|
numberPrefixParser?: NumberPrefixParser;
|
|
@@ -45,14 +46,17 @@ export default function getSlug({
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
function computeSlug(): string {
|
|
48
|
-
if (
|
|
49
|
-
return
|
|
49
|
+
if (frontMatterSlug?.startsWith('/')) {
|
|
50
|
+
return frontMatterSlug;
|
|
50
51
|
} else {
|
|
51
52
|
const dirNameSlug = getDirNameSlug();
|
|
52
|
-
if (
|
|
53
|
+
if (
|
|
54
|
+
!frontMatterSlug &&
|
|
55
|
+
isCategoryIndex(toCategoryIndexMatcherParam({source, sourceDirName}))
|
|
56
|
+
) {
|
|
53
57
|
return dirNameSlug;
|
|
54
58
|
}
|
|
55
|
-
const baseSlug =
|
|
59
|
+
const baseSlug = frontMatterSlug || baseID;
|
|
56
60
|
return resolvePathname(baseSlug, getDirNameSlug());
|
|
57
61
|
}
|
|
58
62
|
}
|
|
@@ -62,8 +66,8 @@ export default function getSlug({
|
|
|
62
66
|
throw new Error(
|
|
63
67
|
`We couldn't compute a valid slug for document with id "${baseID}" in "${sourceDirName}" directory.
|
|
64
68
|
The slug we computed looks invalid: ${slug}.
|
|
65
|
-
Maybe your slug
|
|
66
|
-
By using the slug
|
|
69
|
+
Maybe your slug front matter is incorrect or you use weird chars in the file path?
|
|
70
|
+
By using the slug front matter, you should be able to fix this error, by using the slug of your choice:
|
|
67
71
|
|
|
68
72
|
Example =>
|
|
69
73
|
---
|
package/src/translations.ts
CHANGED
|
@@ -23,10 +23,10 @@ import type {
|
|
|
23
23
|
TranslationFileContent,
|
|
24
24
|
TranslationFile,
|
|
25
25
|
TranslationFiles,
|
|
26
|
+
TranslationMessage,
|
|
26
27
|
} from '@docusaurus/types';
|
|
27
28
|
import {mergeTranslations} from '@docusaurus/utils';
|
|
28
29
|
import {CURRENT_VERSION_NAME} from './constants';
|
|
29
|
-
import {TranslationMessage} from '@docusaurus/types';
|
|
30
30
|
|
|
31
31
|
function getVersionFileName(versionName: string): string {
|
|
32
32
|
if (versionName === CURRENT_VERSION_NAME) {
|
|
@@ -57,7 +57,7 @@ function getNormalizedSidebarName({
|
|
|
57
57
|
|
|
58
58
|
/*
|
|
59
59
|
// Do we need to translate doc metadata?
|
|
60
|
-
// It seems translating
|
|
60
|
+
// It seems translating front matter labels is good enough
|
|
61
61
|
function getDocTranslations(doc: DocMetadata): TranslationFileContent {
|
|
62
62
|
return {
|
|
63
63
|
[`${doc.unversionedId}.title`]: {
|
package/src/types.ts
CHANGED
|
@@ -7,13 +7,16 @@
|
|
|
7
7
|
|
|
8
8
|
/// <reference types="@docusaurus/module-type-aliases" />
|
|
9
9
|
|
|
10
|
-
import type {
|
|
10
|
+
import type {Sidebars} from './sidebars/types';
|
|
11
11
|
import type {Tag, FrontMatterTag, Slugger} from '@docusaurus/utils';
|
|
12
12
|
import type {
|
|
13
13
|
BrokenMarkdownLink as IBrokenMarkdownLink,
|
|
14
14
|
ContentPaths,
|
|
15
15
|
} from '@docusaurus/utils/lib/markdownLinks';
|
|
16
|
-
import type {
|
|
16
|
+
import type {
|
|
17
|
+
VersionBanner,
|
|
18
|
+
SidebarOptions,
|
|
19
|
+
} from '@docusaurus/plugin-content-docs';
|
|
17
20
|
|
|
18
21
|
export type DocFile = {
|
|
19
22
|
contentPath: string; // /!\ may be localized
|
|
@@ -23,10 +26,8 @@ export type DocFile = {
|
|
|
23
26
|
lastUpdate: LastUpdateData;
|
|
24
27
|
};
|
|
25
28
|
|
|
26
|
-
export type VersionName = string;
|
|
27
|
-
|
|
28
29
|
export type VersionMetadata = ContentPaths & {
|
|
29
|
-
versionName:
|
|
30
|
+
versionName: string; // 1.0.0
|
|
30
31
|
versionLabel: string; // Version 1.0.0
|
|
31
32
|
versionPath: string; // /baseUrl/docs/1.0.0
|
|
32
33
|
tagsPath: string;
|
|
@@ -40,76 +41,11 @@ export type VersionMetadata = ContentPaths & {
|
|
|
40
41
|
routePriority: number | undefined; // -1 for the latest docs
|
|
41
42
|
};
|
|
42
43
|
|
|
43
|
-
export type EditUrlFunction = (editUrlParams: {
|
|
44
|
-
version: string;
|
|
45
|
-
versionDocsDirPath: string;
|
|
46
|
-
docPath: string;
|
|
47
|
-
permalink: string;
|
|
48
|
-
locale: string;
|
|
49
|
-
}) => string | undefined;
|
|
50
|
-
|
|
51
|
-
export type MetadataOptions = {
|
|
52
|
-
routeBasePath: string;
|
|
53
|
-
editUrl?: string | EditUrlFunction;
|
|
54
|
-
editCurrentVersion: boolean;
|
|
55
|
-
editLocalizedFiles: boolean;
|
|
56
|
-
showLastUpdateTime?: boolean;
|
|
57
|
-
showLastUpdateAuthor?: boolean;
|
|
58
|
-
numberPrefixParser: NumberPrefixParser;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export type PathOptions = {
|
|
62
|
-
path: string;
|
|
63
|
-
sidebarPath?: string | false | undefined;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
// TODO support custom version banner? {type: "error", content: "html content"}
|
|
67
|
-
export type VersionBanner = 'unreleased' | 'unmaintained';
|
|
68
|
-
|
|
69
|
-
export type VersionOptions = {
|
|
70
|
-
path?: string;
|
|
71
|
-
label?: string;
|
|
72
|
-
banner?: 'none' | VersionBanner;
|
|
73
|
-
badge?: boolean;
|
|
74
|
-
className?: string;
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export type VersionsOptions = {
|
|
78
|
-
lastVersion?: string;
|
|
79
|
-
versions: Record<string, VersionOptions>;
|
|
80
|
-
onlyIncludeVersions?: string[];
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
export type SidebarOptions = {
|
|
84
|
-
sidebarCollapsible: boolean;
|
|
85
|
-
sidebarCollapsed: boolean;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
44
|
export type NormalizeSidebarsParams = SidebarOptions & {
|
|
89
45
|
version: VersionMetadata;
|
|
90
46
|
categoryLabelSlugger: Slugger;
|
|
91
47
|
};
|
|
92
48
|
|
|
93
|
-
export type PluginOptions = MetadataOptions &
|
|
94
|
-
PathOptions &
|
|
95
|
-
VersionsOptions &
|
|
96
|
-
RemarkAndRehypePluginOptions &
|
|
97
|
-
SidebarOptions & {
|
|
98
|
-
id: string;
|
|
99
|
-
include: string[];
|
|
100
|
-
exclude: string[];
|
|
101
|
-
docLayoutComponent: string;
|
|
102
|
-
docItemComponent: string;
|
|
103
|
-
docTagDocListComponent: string;
|
|
104
|
-
docTagsListComponent: string;
|
|
105
|
-
docCategoryGeneratedIndexComponent: string;
|
|
106
|
-
admonitions: Record<string, unknown>;
|
|
107
|
-
disableVersioning: boolean;
|
|
108
|
-
includeCurrentVersion: boolean;
|
|
109
|
-
sidebarItemsGenerator: SidebarItemsGeneratorOption;
|
|
110
|
-
tagsBasePath: string;
|
|
111
|
-
};
|
|
112
|
-
|
|
113
49
|
export type LastUpdateData = {
|
|
114
50
|
lastUpdatedAt?: number;
|
|
115
51
|
formattedLastUpdatedAt?: string;
|
|
@@ -130,6 +66,7 @@ export type DocFrontMatter = {
|
|
|
130
66
|
sidebar_label?: string;
|
|
131
67
|
sidebar_position?: number;
|
|
132
68
|
sidebar_class_name?: string;
|
|
69
|
+
displayed_sidebar?: string | null;
|
|
133
70
|
pagination_label?: string;
|
|
134
71
|
custom_edit_url?: string | null;
|
|
135
72
|
parse_number_prefixes?: boolean;
|
|
@@ -142,11 +79,11 @@ export type DocFrontMatter = {
|
|
|
142
79
|
export type DocMetadataBase = LastUpdateData & {
|
|
143
80
|
id: string; // TODO legacy versioned id => try to remove
|
|
144
81
|
unversionedId: string; // TODO new unversioned id => try to rename to "id"
|
|
145
|
-
version:
|
|
82
|
+
version: string;
|
|
146
83
|
title: string;
|
|
147
84
|
description: string;
|
|
148
|
-
source: string; // @site aliased source => "@site/docs/folder/subFolder/subSubFolder/myDoc.md"
|
|
149
|
-
sourceDirName: string; // relative to the versioned docs folder (can be ".") => "folder/subFolder/subSubFolder"
|
|
85
|
+
source: string; // @site aliased posix source => "@site/docs/folder/subFolder/subSubFolder/myDoc.md"
|
|
86
|
+
sourceDirName: string; // posix path relative to the versioned docs folder (can be ".") => "folder/subFolder/subSubFolder"
|
|
150
87
|
slug: string;
|
|
151
88
|
permalink: string;
|
|
152
89
|
sidebarPosition?: number;
|
|
@@ -174,6 +111,8 @@ export type CategoryGeneratedIndexMetadata = {
|
|
|
174
111
|
sidebar: string;
|
|
175
112
|
previous?: DocNavLink;
|
|
176
113
|
next?: DocNavLink;
|
|
114
|
+
image?: string;
|
|
115
|
+
keywords?: string | readonly string[];
|
|
177
116
|
};
|
|
178
117
|
|
|
179
118
|
export type SourceToPermalink = {
|
|
@@ -201,26 +140,6 @@ export type LoadedContent = {
|
|
|
201
140
|
loadedVersions: LoadedVersion[];
|
|
202
141
|
};
|
|
203
142
|
|
|
204
|
-
export type GlobalDoc = {
|
|
205
|
-
id: string;
|
|
206
|
-
path: string;
|
|
207
|
-
sidebar: string | undefined;
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
export type GlobalVersion = {
|
|
211
|
-
name: VersionName;
|
|
212
|
-
label: string;
|
|
213
|
-
isLast: boolean;
|
|
214
|
-
path: string;
|
|
215
|
-
mainDocId: string; // home doc (if docs homepage configured), or first doc
|
|
216
|
-
docs: GlobalDoc[];
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
export type GlobalPluginData = {
|
|
220
|
-
path: string;
|
|
221
|
-
versions: GlobalVersion[];
|
|
222
|
-
};
|
|
223
|
-
|
|
224
143
|
export type BrokenMarkdownLink = IBrokenMarkdownLink<VersionMetadata>;
|
|
225
144
|
|
|
226
145
|
export type DocsMarkdownOption = {
|
|
@@ -229,8 +148,3 @@ export type DocsMarkdownOption = {
|
|
|
229
148
|
sourceToPermalink: SourceToPermalink;
|
|
230
149
|
onBrokenMarkdownLink: (brokenMarkdownLink: BrokenMarkdownLink) => void;
|
|
231
150
|
};
|
|
232
|
-
|
|
233
|
-
export type NumberPrefixParser = (filename: string) => {
|
|
234
|
-
filename: string;
|
|
235
|
-
numberPrefix?: number;
|
|
236
|
-
};
|