@docusaurus/plugin-content-docs 0.0.0-4238 → 0.0.0-4243
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/.tsbuildinfo +1 -1
- package/lib/categoryGeneratedIndex.d.ts +12 -0
- package/lib/categoryGeneratedIndex.js +37 -0
- package/lib/cli.js +5 -23
- package/lib/docs.d.ts +22 -2
- package/lib/docs.js +71 -29
- package/lib/index.js +34 -62
- package/lib/options.js +2 -0
- package/lib/props.js +35 -6
- package/lib/routes.d.ts +27 -0
- package/lib/routes.js +105 -0
- package/lib/sidebars/generator.d.ts +2 -1
- package/lib/sidebars/generator.js +55 -13
- package/lib/sidebars/index.d.ts +5 -4
- package/lib/sidebars/index.js +18 -9
- package/lib/sidebars/normalization.d.ts +8 -3
- package/lib/sidebars/normalization.js +36 -17
- package/lib/sidebars/processor.d.ts +5 -3
- package/lib/sidebars/processor.js +33 -18
- package/lib/sidebars/types.d.ts +43 -2
- package/lib/sidebars/utils.d.ts +18 -6
- package/lib/sidebars/utils.js +149 -24
- package/lib/sidebars/validation.d.ts +2 -0
- package/lib/sidebars/validation.js +44 -8
- package/lib/slug.d.ts +4 -3
- package/lib/slug.js +26 -14
- package/lib/translations.js +51 -7
- package/lib/types.d.ts +18 -3
- package/package.json +8 -8
- package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.1-sidebars.json +2 -2
- package/src/__tests__/__snapshots__/cli.test.ts.snap +48 -106
- package/src/__tests__/__snapshots__/index.test.ts.snap +279 -28
- package/src/__tests__/__snapshots__/translations.test.ts.snap +45 -0
- package/src/__tests__/docs.test.ts +122 -7
- package/src/__tests__/index.test.ts +27 -1
- package/src/__tests__/options.test.ts +2 -0
- package/src/__tests__/slug.test.ts +127 -20
- package/src/__tests__/translations.test.ts +7 -0
- package/src/categoryGeneratedIndex.ts +57 -0
- package/src/cli.ts +5 -35
- package/src/docs.ts +103 -45
- package/src/index.ts +55 -93
- package/src/options.ts +4 -0
- package/src/plugin-content-docs.d.ts +71 -8
- package/src/props.ts +48 -9
- package/src/routes.ts +173 -0
- package/src/sidebars/__tests__/__snapshots__/index.test.ts.snap +21 -6
- package/src/sidebars/__tests__/generator.test.ts +105 -1
- package/src/sidebars/__tests__/index.test.ts +26 -24
- package/src/sidebars/__tests__/processor.test.ts +110 -19
- package/src/sidebars/__tests__/utils.test.ts +320 -20
- package/src/sidebars/__tests__/validation.test.ts +105 -0
- package/src/sidebars/generator.ts +82 -19
- package/src/sidebars/index.ts +23 -13
- package/src/sidebars/normalization.ts +47 -23
- package/src/sidebars/processor.ts +57 -27
- package/src/sidebars/types.ts +64 -3
- package/src/sidebars/utils.ts +217 -42
- package/src/sidebars/validation.ts +52 -8
- package/src/slug.ts +32 -17
- package/src/translations.ts +74 -8
- package/src/types.ts +22 -5
|
@@ -8,6 +8,14 @@ Array [
|
|
|
8
8
|
"description": "The label for category Getting started in sidebar docs",
|
|
9
9
|
"message": "Getting started",
|
|
10
10
|
},
|
|
11
|
+
"sidebar.docs.category.Getting started.link.generated-index.description": Object {
|
|
12
|
+
"description": "The generated-index page description for category Getting started in sidebar docs",
|
|
13
|
+
"message": "Getting started index description",
|
|
14
|
+
},
|
|
15
|
+
"sidebar.docs.category.Getting started.link.generated-index.title": Object {
|
|
16
|
+
"description": "The generated-index page title for category Getting started in sidebar docs",
|
|
17
|
+
"message": "Getting started index title",
|
|
18
|
+
},
|
|
11
19
|
"sidebar.docs.link.Link label": Object {
|
|
12
20
|
"description": "The label for link Link label in sidebar docs, linking to https://facebook.com",
|
|
13
21
|
"message": "Link label",
|
|
@@ -25,6 +33,14 @@ Array [
|
|
|
25
33
|
"description": "The label for category Getting started in sidebar docs",
|
|
26
34
|
"message": "Getting started",
|
|
27
35
|
},
|
|
36
|
+
"sidebar.docs.category.Getting started.link.generated-index.description": Object {
|
|
37
|
+
"description": "The generated-index page description for category Getting started in sidebar docs",
|
|
38
|
+
"message": "Getting started index description",
|
|
39
|
+
},
|
|
40
|
+
"sidebar.docs.category.Getting started.link.generated-index.title": Object {
|
|
41
|
+
"description": "The generated-index page title for category Getting started in sidebar docs",
|
|
42
|
+
"message": "Getting started index title",
|
|
43
|
+
},
|
|
28
44
|
"sidebar.docs.link.Link label": Object {
|
|
29
45
|
"description": "The label for link Link label in sidebar docs, linking to https://facebook.com",
|
|
30
46
|
"message": "Link label",
|
|
@@ -42,6 +58,14 @@ Array [
|
|
|
42
58
|
"description": "The label for category Getting started in sidebar docs",
|
|
43
59
|
"message": "Getting started",
|
|
44
60
|
},
|
|
61
|
+
"sidebar.docs.category.Getting started.link.generated-index.description": Object {
|
|
62
|
+
"description": "The generated-index page description for category Getting started in sidebar docs",
|
|
63
|
+
"message": "Getting started index description",
|
|
64
|
+
},
|
|
65
|
+
"sidebar.docs.category.Getting started.link.generated-index.title": Object {
|
|
66
|
+
"description": "The generated-index page title for category Getting started in sidebar docs",
|
|
67
|
+
"message": "Getting started index title",
|
|
68
|
+
},
|
|
45
69
|
"sidebar.docs.link.Link label": Object {
|
|
46
70
|
"description": "The label for link Link label in sidebar docs, linking to https://facebook.com",
|
|
47
71
|
"message": "Link label",
|
|
@@ -177,6 +201,13 @@ Object {
|
|
|
177
201
|
},
|
|
178
202
|
],
|
|
179
203
|
"label": "Getting started (translated)",
|
|
204
|
+
"link": Object {
|
|
205
|
+
"description": "Getting started index description (translated)",
|
|
206
|
+
"permalink": "/docs/category/getting-started-index-slug",
|
|
207
|
+
"slug": "/category/getting-started-index-slug",
|
|
208
|
+
"title": "Getting started index title (translated)",
|
|
209
|
+
"type": "generated-index",
|
|
210
|
+
},
|
|
180
211
|
"type": "category",
|
|
181
212
|
},
|
|
182
213
|
Object {
|
|
@@ -317,6 +348,13 @@ Object {
|
|
|
317
348
|
},
|
|
318
349
|
],
|
|
319
350
|
"label": "Getting started (translated)",
|
|
351
|
+
"link": Object {
|
|
352
|
+
"description": "Getting started index description (translated)",
|
|
353
|
+
"permalink": "/docs/category/getting-started-index-slug",
|
|
354
|
+
"slug": "/category/getting-started-index-slug",
|
|
355
|
+
"title": "Getting started index title (translated)",
|
|
356
|
+
"type": "generated-index",
|
|
357
|
+
},
|
|
320
358
|
"type": "category",
|
|
321
359
|
},
|
|
322
360
|
Object {
|
|
@@ -457,6 +495,13 @@ Object {
|
|
|
457
495
|
},
|
|
458
496
|
],
|
|
459
497
|
"label": "Getting started (translated)",
|
|
498
|
+
"link": Object {
|
|
499
|
+
"description": "Getting started index description (translated)",
|
|
500
|
+
"permalink": "/docs/category/getting-started-index-slug",
|
|
501
|
+
"slug": "/category/getting-started-index-slug",
|
|
502
|
+
"title": "Getting started index title (translated)",
|
|
503
|
+
"type": "generated-index",
|
|
504
|
+
},
|
|
460
505
|
"type": "category",
|
|
461
506
|
},
|
|
462
507
|
Object {
|
|
@@ -11,7 +11,8 @@ import {
|
|
|
11
11
|
processDocMetadata,
|
|
12
12
|
readVersionDocs,
|
|
13
13
|
readDocFile,
|
|
14
|
-
|
|
14
|
+
addDocNavigation,
|
|
15
|
+
isConventionalDocIndex,
|
|
15
16
|
} from '../docs';
|
|
16
17
|
import {loadSidebars} from '../sidebars';
|
|
17
18
|
import {readVersionsMetadata} from '../versions';
|
|
@@ -28,7 +29,8 @@ import type {LoadContext} from '@docusaurus/types';
|
|
|
28
29
|
import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants';
|
|
29
30
|
import {DEFAULT_OPTIONS} from '../options';
|
|
30
31
|
import {Optional} from 'utility-types';
|
|
31
|
-
import {posixPath} from '@docusaurus/utils';
|
|
32
|
+
import {createSlugger, posixPath} from '@docusaurus/utils';
|
|
33
|
+
import {createSidebarsUtils} from '../sidebars/utils';
|
|
32
34
|
|
|
33
35
|
const fixtureDir = path.join(__dirname, '__fixtures__');
|
|
34
36
|
|
|
@@ -119,7 +121,7 @@ function createTestUtils({
|
|
|
119
121
|
|
|
120
122
|
async function generateNavigation(
|
|
121
123
|
docFiles: DocFile[],
|
|
122
|
-
): Promise<[DocNavLink, DocNavLink][]> {
|
|
124
|
+
): Promise<[DocNavLink | undefined, DocNavLink | undefined][]> {
|
|
123
125
|
const rawDocs = await Promise.all(
|
|
124
126
|
docFiles.map((docFile) =>
|
|
125
127
|
processDocMetadata({
|
|
@@ -136,16 +138,19 @@ function createTestUtils({
|
|
|
136
138
|
numberPrefixParser: options.numberPrefixParser,
|
|
137
139
|
docs: rawDocs,
|
|
138
140
|
version: versionMetadata,
|
|
139
|
-
|
|
141
|
+
sidebarOptions: {
|
|
140
142
|
sidebarCollapsed: false,
|
|
141
143
|
sidebarCollapsible: true,
|
|
142
144
|
},
|
|
145
|
+
categoryLabelSlugger: createSlugger(),
|
|
143
146
|
});
|
|
144
|
-
|
|
147
|
+
const sidebarsUtils = createSidebarsUtils(sidebars);
|
|
148
|
+
|
|
149
|
+
return addDocNavigation(
|
|
145
150
|
rawDocs,
|
|
146
|
-
|
|
151
|
+
sidebarsUtils,
|
|
147
152
|
versionMetadata.sidebarFilePath as string,
|
|
148
|
-
).
|
|
153
|
+
).map((doc) => [doc.previous, doc.next]);
|
|
149
154
|
}
|
|
150
155
|
|
|
151
156
|
return {processDocFile, testMeta, testSlug, generateNavigation};
|
|
@@ -1022,3 +1027,113 @@ describe('versioned site', () => {
|
|
|
1022
1027
|
});
|
|
1023
1028
|
});
|
|
1024
1029
|
});
|
|
1030
|
+
|
|
1031
|
+
describe('isConventionalDocIndex', () => {
|
|
1032
|
+
test('supports readme', () => {
|
|
1033
|
+
expect(
|
|
1034
|
+
isConventionalDocIndex({
|
|
1035
|
+
sourceDirName: 'doesNotMatter',
|
|
1036
|
+
source: 'readme.md',
|
|
1037
|
+
}),
|
|
1038
|
+
).toEqual(true);
|
|
1039
|
+
expect(
|
|
1040
|
+
isConventionalDocIndex({
|
|
1041
|
+
sourceDirName: 'doesNotMatter',
|
|
1042
|
+
source: 'readme.mdx',
|
|
1043
|
+
}),
|
|
1044
|
+
).toEqual(true);
|
|
1045
|
+
expect(
|
|
1046
|
+
isConventionalDocIndex({
|
|
1047
|
+
sourceDirName: 'doesNotMatter',
|
|
1048
|
+
source: 'README.md',
|
|
1049
|
+
}),
|
|
1050
|
+
).toEqual(true);
|
|
1051
|
+
expect(
|
|
1052
|
+
isConventionalDocIndex({
|
|
1053
|
+
sourceDirName: 'doesNotMatter',
|
|
1054
|
+
source: 'parent/ReAdMe',
|
|
1055
|
+
}),
|
|
1056
|
+
).toEqual(true);
|
|
1057
|
+
});
|
|
1058
|
+
|
|
1059
|
+
test('supports index', () => {
|
|
1060
|
+
expect(
|
|
1061
|
+
isConventionalDocIndex({
|
|
1062
|
+
sourceDirName: 'doesNotMatter',
|
|
1063
|
+
source: 'index.md',
|
|
1064
|
+
}),
|
|
1065
|
+
).toEqual(true);
|
|
1066
|
+
expect(
|
|
1067
|
+
isConventionalDocIndex({
|
|
1068
|
+
sourceDirName: 'doesNotMatter',
|
|
1069
|
+
source: 'index.mdx',
|
|
1070
|
+
}),
|
|
1071
|
+
).toEqual(true);
|
|
1072
|
+
expect(
|
|
1073
|
+
isConventionalDocIndex({
|
|
1074
|
+
sourceDirName: 'doesNotMatter',
|
|
1075
|
+
source: 'INDEX.md',
|
|
1076
|
+
}),
|
|
1077
|
+
).toEqual(true);
|
|
1078
|
+
expect(
|
|
1079
|
+
isConventionalDocIndex({
|
|
1080
|
+
sourceDirName: 'doesNotMatter',
|
|
1081
|
+
source: 'parent/InDeX',
|
|
1082
|
+
}),
|
|
1083
|
+
).toEqual(true);
|
|
1084
|
+
});
|
|
1085
|
+
|
|
1086
|
+
test('supports <categoryName>/<categoryName>.md', () => {
|
|
1087
|
+
expect(
|
|
1088
|
+
isConventionalDocIndex({
|
|
1089
|
+
sourceDirName: 'someCategory',
|
|
1090
|
+
source: 'someCategory',
|
|
1091
|
+
}),
|
|
1092
|
+
).toEqual(true);
|
|
1093
|
+
expect(
|
|
1094
|
+
isConventionalDocIndex({
|
|
1095
|
+
sourceDirName: 'someCategory',
|
|
1096
|
+
source: 'someCategory.md',
|
|
1097
|
+
}),
|
|
1098
|
+
).toEqual(true);
|
|
1099
|
+
expect(
|
|
1100
|
+
isConventionalDocIndex({
|
|
1101
|
+
sourceDirName: 'someCategory',
|
|
1102
|
+
source: 'someCategory.mdx',
|
|
1103
|
+
}),
|
|
1104
|
+
).toEqual(true);
|
|
1105
|
+
expect(
|
|
1106
|
+
isConventionalDocIndex({
|
|
1107
|
+
sourceDirName: 'some_category',
|
|
1108
|
+
source: 'SOME_CATEGORY.md',
|
|
1109
|
+
}),
|
|
1110
|
+
).toEqual(true);
|
|
1111
|
+
expect(
|
|
1112
|
+
isConventionalDocIndex({
|
|
1113
|
+
sourceDirName: 'some_category',
|
|
1114
|
+
source: 'parent/some_category',
|
|
1115
|
+
}),
|
|
1116
|
+
).toEqual(true);
|
|
1117
|
+
});
|
|
1118
|
+
|
|
1119
|
+
test('reject other cases', () => {
|
|
1120
|
+
expect(
|
|
1121
|
+
isConventionalDocIndex({
|
|
1122
|
+
sourceDirName: 'someCategory',
|
|
1123
|
+
source: 'some_Category',
|
|
1124
|
+
}),
|
|
1125
|
+
).toEqual(false);
|
|
1126
|
+
expect(
|
|
1127
|
+
isConventionalDocIndex({
|
|
1128
|
+
sourceDirName: 'doesNotMatter',
|
|
1129
|
+
source: 'read_me',
|
|
1130
|
+
}),
|
|
1131
|
+
).toEqual(false);
|
|
1132
|
+
expect(
|
|
1133
|
+
isConventionalDocIndex({
|
|
1134
|
+
sourceDirName: 'doesNotMatter',
|
|
1135
|
+
source: 'the index',
|
|
1136
|
+
}),
|
|
1137
|
+
).toEqual(false);
|
|
1138
|
+
});
|
|
1139
|
+
});
|
|
@@ -619,6 +619,32 @@ describe('versioned website', () => {
|
|
|
619
619
|
{label: 'barTag 3', permalink: '/docs/next/tags/barTag-3-permalink'},
|
|
620
620
|
],
|
|
621
621
|
});
|
|
622
|
+
expect(getDocById(version101, 'foo/bar')).toEqual({
|
|
623
|
+
...defaultDocMetadata,
|
|
624
|
+
id: 'version-1.0.1/foo/bar',
|
|
625
|
+
unversionedId: 'foo/bar',
|
|
626
|
+
sourceDirName: 'foo',
|
|
627
|
+
isDocsHomePage: false,
|
|
628
|
+
permalink: '/docs/foo/bar',
|
|
629
|
+
slug: '/foo/bar',
|
|
630
|
+
source: path.posix.join(
|
|
631
|
+
'@site',
|
|
632
|
+
posixPath(path.relative(siteDir, version101.contentPath)),
|
|
633
|
+
'foo',
|
|
634
|
+
'bar.md',
|
|
635
|
+
),
|
|
636
|
+
title: 'bar',
|
|
637
|
+
description: 'Bar 1.0.1 !',
|
|
638
|
+
frontMatter: {},
|
|
639
|
+
version: '1.0.1',
|
|
640
|
+
sidebar: 'VersionedSideBarNameDoesNotMatter/docs',
|
|
641
|
+
next: {
|
|
642
|
+
title: 'hello',
|
|
643
|
+
permalink: '/docs/',
|
|
644
|
+
},
|
|
645
|
+
tags: [],
|
|
646
|
+
});
|
|
647
|
+
|
|
622
648
|
expect(getDocById(currentVersion, 'hello')).toEqual({
|
|
623
649
|
...defaultDocMetadata,
|
|
624
650
|
id: 'hello',
|
|
@@ -659,7 +685,7 @@ describe('versioned website', () => {
|
|
|
659
685
|
description: 'Hello 1.0.1 !',
|
|
660
686
|
frontMatter: {},
|
|
661
687
|
version: '1.0.1',
|
|
662
|
-
sidebar: '
|
|
688
|
+
sidebar: 'VersionedSideBarNameDoesNotMatter/docs',
|
|
663
689
|
previous: {
|
|
664
690
|
title: 'bar',
|
|
665
691
|
permalink: '/docs/foo/bar',
|
|
@@ -51,6 +51,8 @@ describe('normalizeDocsPluginOptions', () => {
|
|
|
51
51
|
docItemComponent: '@theme/DocItem',
|
|
52
52
|
docTagDocListComponent: '@theme/DocTagDocListPage',
|
|
53
53
|
docTagsListComponent: '@theme/DocTagsListPage',
|
|
54
|
+
docCategoryGeneratedIndexComponent:
|
|
55
|
+
'@theme/DocCategoryGeneratedIndexPage',
|
|
54
56
|
remarkPlugins: [markdownPluginsObjectStub],
|
|
55
57
|
rehypePlugins: [markdownPluginsFunctionStub],
|
|
56
58
|
beforeDefaultRehypePlugins: [],
|
|
@@ -9,24 +9,92 @@ import getSlug from '../slug';
|
|
|
9
9
|
|
|
10
10
|
describe('getSlug', () => {
|
|
11
11
|
test('should default to dirname/id', () => {
|
|
12
|
-
expect(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
expect(
|
|
13
|
+
getSlug({
|
|
14
|
+
baseID: 'doc',
|
|
15
|
+
source: '@site/docs/dir/doc.md',
|
|
16
|
+
sourceDirName: '/dir',
|
|
17
|
+
}),
|
|
18
|
+
).toEqual('/dir/doc');
|
|
19
|
+
expect(
|
|
20
|
+
getSlug({
|
|
21
|
+
baseID: 'doc',
|
|
22
|
+
source: '@site/docs/dir/subdir/doc.md',
|
|
23
|
+
sourceDirName: '/dir/subdir',
|
|
24
|
+
}),
|
|
25
|
+
).toEqual('/dir/subdir/doc');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('should handle conventional doc indexes', () => {
|
|
29
|
+
expect(
|
|
30
|
+
getSlug({
|
|
31
|
+
baseID: 'doc',
|
|
32
|
+
source: '@site/docs/dir/subdir/index.md',
|
|
33
|
+
sourceDirName: '/dir/subdir',
|
|
34
|
+
}),
|
|
35
|
+
).toEqual('/dir/subdir/');
|
|
36
|
+
expect(
|
|
37
|
+
getSlug({
|
|
38
|
+
baseID: 'doc',
|
|
39
|
+
source: '@site/docs/dir/subdir/inDEx.mdx',
|
|
40
|
+
sourceDirName: '/dir/subdir',
|
|
41
|
+
}),
|
|
42
|
+
).toEqual('/dir/subdir/');
|
|
43
|
+
expect(
|
|
44
|
+
getSlug({
|
|
45
|
+
baseID: 'doc',
|
|
46
|
+
source: '@site/docs/dir/subdir/readme.md',
|
|
47
|
+
sourceDirName: '/dir/subdir',
|
|
48
|
+
}),
|
|
49
|
+
).toEqual('/dir/subdir/');
|
|
50
|
+
expect(
|
|
51
|
+
getSlug({
|
|
52
|
+
baseID: 'doc',
|
|
53
|
+
source: '@site/docs/dir/subdir/reADMe.mdx',
|
|
54
|
+
sourceDirName: '/dir/subdir',
|
|
55
|
+
}),
|
|
56
|
+
).toEqual('/dir/subdir/');
|
|
57
|
+
expect(
|
|
58
|
+
getSlug({
|
|
59
|
+
baseID: 'doc',
|
|
60
|
+
source: '@site/docs/dir/subdir/subdir.md',
|
|
61
|
+
sourceDirName: '/dir/subdir',
|
|
62
|
+
}),
|
|
63
|
+
).toEqual('/dir/subdir/');
|
|
64
|
+
expect(
|
|
65
|
+
getSlug({
|
|
66
|
+
baseID: 'doc',
|
|
67
|
+
source: '@site/docs/dir/subdir/suBDir.mdx',
|
|
68
|
+
sourceDirName: '/dir/subdir',
|
|
69
|
+
}),
|
|
70
|
+
).toEqual('/dir/subdir/');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('should ignore conventional doc index when explicit slug frontmatter is provided', () => {
|
|
74
|
+
expect(
|
|
75
|
+
getSlug({
|
|
76
|
+
baseID: 'doc',
|
|
77
|
+
source: '@site/docs/dir/subdir/index.md',
|
|
78
|
+
sourceDirName: '/dir/subdir',
|
|
79
|
+
frontmatterSlug: '/my/frontMatterSlug',
|
|
80
|
+
}),
|
|
81
|
+
).toEqual('/my/frontMatterSlug');
|
|
16
82
|
});
|
|
17
83
|
|
|
18
84
|
test('can strip dir number prefixes', () => {
|
|
19
85
|
expect(
|
|
20
86
|
getSlug({
|
|
21
87
|
baseID: 'doc',
|
|
22
|
-
|
|
88
|
+
source: '@site/docs/001-dir1/002-dir2/doc.md',
|
|
89
|
+
sourceDirName: '/001-dir1/002-dir2',
|
|
23
90
|
stripDirNumberPrefixes: true,
|
|
24
91
|
}),
|
|
25
92
|
).toEqual('/dir1/dir2/doc');
|
|
26
93
|
expect(
|
|
27
94
|
getSlug({
|
|
28
95
|
baseID: 'doc',
|
|
29
|
-
|
|
96
|
+
source: '@site/docs/001-dir1/002-dir2/doc.md',
|
|
97
|
+
sourceDirName: '/001-dir1/002-dir2',
|
|
30
98
|
stripDirNumberPrefixes: false,
|
|
31
99
|
}),
|
|
32
100
|
).toEqual('/001-dir1/002-dir2/doc');
|
|
@@ -35,26 +103,45 @@ describe('getSlug', () => {
|
|
|
35
103
|
// See https://github.com/facebook/docusaurus/issues/3223
|
|
36
104
|
test('should handle special chars in doc path', () => {
|
|
37
105
|
expect(
|
|
38
|
-
getSlug({
|
|
106
|
+
getSlug({
|
|
107
|
+
baseID: 'my dôc',
|
|
108
|
+
source: '@site/docs/dir with spâce/hey $hello/doc.md',
|
|
109
|
+
sourceDirName: '/dir with spâce/hey $hello',
|
|
110
|
+
}),
|
|
39
111
|
).toEqual('/dir with spâce/hey $hello/my dôc');
|
|
40
112
|
});
|
|
41
113
|
|
|
42
114
|
test('should handle current dir', () => {
|
|
43
|
-
expect(
|
|
44
|
-
|
|
115
|
+
expect(
|
|
116
|
+
getSlug({baseID: 'doc', source: '@site/docs/doc.md', sourceDirName: '.'}),
|
|
117
|
+
).toEqual('/doc');
|
|
118
|
+
expect(
|
|
119
|
+
getSlug({baseID: 'doc', source: '@site/docs/doc.md', sourceDirName: '/'}),
|
|
120
|
+
).toEqual('/doc');
|
|
45
121
|
});
|
|
46
122
|
|
|
47
123
|
test('should resolve absolute slug frontmatter', () => {
|
|
48
124
|
expect(
|
|
49
|
-
getSlug({
|
|
125
|
+
getSlug({
|
|
126
|
+
baseID: 'any',
|
|
127
|
+
source: '@site/docs/doc.md',
|
|
128
|
+
sourceDirName: '.',
|
|
129
|
+
frontmatterSlug: '/abc/def',
|
|
130
|
+
}),
|
|
50
131
|
).toEqual('/abc/def');
|
|
51
132
|
expect(
|
|
52
|
-
getSlug({
|
|
133
|
+
getSlug({
|
|
134
|
+
baseID: 'any',
|
|
135
|
+
source: '@site/docs/any/doc.md',
|
|
136
|
+
sourceDirName: './any',
|
|
137
|
+
frontmatterSlug: '/abc/def',
|
|
138
|
+
}),
|
|
53
139
|
).toEqual('/abc/def');
|
|
54
140
|
expect(
|
|
55
141
|
getSlug({
|
|
56
142
|
baseID: 'any',
|
|
57
|
-
|
|
143
|
+
source: '@site/docs/any/any/doc.md',
|
|
144
|
+
sourceDirName: './any/any',
|
|
58
145
|
frontmatterSlug: '/abc/def',
|
|
59
146
|
}),
|
|
60
147
|
).toEqual('/abc/def');
|
|
@@ -62,46 +149,66 @@ describe('getSlug', () => {
|
|
|
62
149
|
|
|
63
150
|
test('should resolve relative slug frontmatter', () => {
|
|
64
151
|
expect(
|
|
65
|
-
getSlug({
|
|
152
|
+
getSlug({
|
|
153
|
+
baseID: 'any',
|
|
154
|
+
source: '@site/docs/doc.md',
|
|
155
|
+
sourceDirName: '.',
|
|
156
|
+
frontmatterSlug: 'abc/def',
|
|
157
|
+
}),
|
|
66
158
|
).toEqual('/abc/def');
|
|
67
159
|
expect(
|
|
68
|
-
getSlug({
|
|
160
|
+
getSlug({
|
|
161
|
+
baseID: 'any',
|
|
162
|
+
source: '@site/docs/dir/doc.md',
|
|
163
|
+
sourceDirName: '/dir',
|
|
164
|
+
frontmatterSlug: 'abc/def',
|
|
165
|
+
}),
|
|
69
166
|
).toEqual('/dir/abc/def');
|
|
70
167
|
expect(
|
|
71
168
|
getSlug({
|
|
72
169
|
baseID: 'any',
|
|
73
|
-
|
|
170
|
+
source: '@site/docs/unslashedDir/doc.md',
|
|
171
|
+
sourceDirName: 'unslashedDir',
|
|
74
172
|
frontmatterSlug: 'abc/def',
|
|
75
173
|
}),
|
|
76
174
|
).toEqual('/unslashedDir/abc/def');
|
|
77
175
|
expect(
|
|
78
176
|
getSlug({
|
|
79
177
|
baseID: 'any',
|
|
80
|
-
|
|
178
|
+
source: '@site/docs/dir/subdir/doc.md',
|
|
179
|
+
sourceDirName: 'dir/subdir',
|
|
81
180
|
frontmatterSlug: 'abc/def',
|
|
82
181
|
}),
|
|
83
182
|
).toEqual('/dir/subdir/abc/def');
|
|
84
183
|
expect(
|
|
85
|
-
getSlug({
|
|
184
|
+
getSlug({
|
|
185
|
+
baseID: 'any',
|
|
186
|
+
source: '@site/docs/dir/doc.md',
|
|
187
|
+
sourceDirName: '/dir',
|
|
188
|
+
frontmatterSlug: './abc/def',
|
|
189
|
+
}),
|
|
86
190
|
).toEqual('/dir/abc/def');
|
|
87
191
|
expect(
|
|
88
192
|
getSlug({
|
|
89
193
|
baseID: 'any',
|
|
90
|
-
|
|
194
|
+
source: '@site/docs/dir/doc.md',
|
|
195
|
+
sourceDirName: '/dir',
|
|
91
196
|
frontmatterSlug: './abc/../def',
|
|
92
197
|
}),
|
|
93
198
|
).toEqual('/dir/def');
|
|
94
199
|
expect(
|
|
95
200
|
getSlug({
|
|
96
201
|
baseID: 'any',
|
|
97
|
-
|
|
202
|
+
source: '@site/docs/dir/subdir/doc.md',
|
|
203
|
+
sourceDirName: '/dir/subdir',
|
|
98
204
|
frontmatterSlug: '../abc/def',
|
|
99
205
|
}),
|
|
100
206
|
).toEqual('/dir/abc/def');
|
|
101
207
|
expect(
|
|
102
208
|
getSlug({
|
|
103
209
|
baseID: 'any',
|
|
104
|
-
|
|
210
|
+
source: '@site/docs/dir/subdirdoc.md',
|
|
211
|
+
sourceDirName: '/dir/subdir',
|
|
105
212
|
frontmatterSlug: '../../../../../abc/../def',
|
|
106
213
|
}),
|
|
107
214
|
).toEqual('/def');
|
|
@@ -68,6 +68,13 @@ function createSampleVersion(
|
|
|
68
68
|
type: 'category',
|
|
69
69
|
label: 'Getting started',
|
|
70
70
|
collapsed: false,
|
|
71
|
+
link: {
|
|
72
|
+
type: 'generated-index',
|
|
73
|
+
slug: '/category/getting-started-index-slug',
|
|
74
|
+
permalink: '/docs/category/getting-started-index-slug',
|
|
75
|
+
title: 'Getting started index title',
|
|
76
|
+
description: 'Getting started index description',
|
|
77
|
+
},
|
|
71
78
|
items: [
|
|
72
79
|
{
|
|
73
80
|
type: 'doc',
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {CategoryGeneratedIndexMetadata, DocMetadataBase} from './types';
|
|
9
|
+
import {SidebarItemCategoryWithGeneratedIndex} from './sidebars/types';
|
|
10
|
+
import {SidebarsUtils, toNavigationLink} from './sidebars/utils';
|
|
11
|
+
import {createDocsByIdIndex} from './docs';
|
|
12
|
+
|
|
13
|
+
function getCategoryGeneratedIndexMetadata({
|
|
14
|
+
category,
|
|
15
|
+
sidebarsUtils,
|
|
16
|
+
docsById,
|
|
17
|
+
}: {
|
|
18
|
+
category: SidebarItemCategoryWithGeneratedIndex;
|
|
19
|
+
sidebarsUtils: SidebarsUtils;
|
|
20
|
+
docsById: Record<string, DocMetadataBase>;
|
|
21
|
+
}): CategoryGeneratedIndexMetadata {
|
|
22
|
+
const {sidebarName, previous, next} =
|
|
23
|
+
sidebarsUtils.getCategoryGeneratedIndexNavigation(category.link.permalink);
|
|
24
|
+
if (!sidebarName) {
|
|
25
|
+
throw new Error('unexpected');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
title: category.link.title ?? category.label,
|
|
30
|
+
description: category.link.description,
|
|
31
|
+
slug: category.link.slug,
|
|
32
|
+
permalink: category.link.permalink,
|
|
33
|
+
sidebar: sidebarName,
|
|
34
|
+
previous: toNavigationLink(previous, docsById),
|
|
35
|
+
next: toNavigationLink(next, docsById),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function getCategoryGeneratedIndexMetadataList({
|
|
40
|
+
docs,
|
|
41
|
+
sidebarsUtils,
|
|
42
|
+
}: {
|
|
43
|
+
sidebarsUtils: SidebarsUtils;
|
|
44
|
+
docs: DocMetadataBase[];
|
|
45
|
+
}): CategoryGeneratedIndexMetadata[] {
|
|
46
|
+
const docsById = createDocsByIdIndex(docs);
|
|
47
|
+
|
|
48
|
+
const categoryGeneratedIndexItems =
|
|
49
|
+
sidebarsUtils.getCategoryGeneratedIndexList();
|
|
50
|
+
return categoryGeneratedIndexItems.map((category) =>
|
|
51
|
+
getCategoryGeneratedIndexMetadata({
|
|
52
|
+
category,
|
|
53
|
+
sidebarsUtils,
|
|
54
|
+
docsById,
|
|
55
|
+
}),
|
|
56
|
+
);
|
|
57
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -13,9 +13,7 @@ import {
|
|
|
13
13
|
import fs from 'fs-extra';
|
|
14
14
|
import path from 'path';
|
|
15
15
|
import type {PathOptions, SidebarOptions} from './types';
|
|
16
|
-
import {
|
|
17
|
-
import type {SidebarItem, NormalizedSidebars, Sidebar} from './sidebars/types';
|
|
18
|
-
import {loadUnprocessedSidebars, resolveSidebarPathOption} from './sidebars';
|
|
16
|
+
import {loadSidebarsFile, resolveSidebarPathOption} from './sidebars';
|
|
19
17
|
import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants';
|
|
20
18
|
|
|
21
19
|
function createVersionedSidebarFile({
|
|
@@ -23,47 +21,20 @@ function createVersionedSidebarFile({
|
|
|
23
21
|
pluginId,
|
|
24
22
|
sidebarPath,
|
|
25
23
|
version,
|
|
26
|
-
options,
|
|
27
24
|
}: {
|
|
28
25
|
siteDir: string;
|
|
29
26
|
pluginId: string;
|
|
30
27
|
sidebarPath: string | false | undefined;
|
|
31
28
|
version: string;
|
|
32
|
-
options: SidebarOptions;
|
|
33
29
|
}) {
|
|
34
30
|
// Load current sidebar and create a new versioned sidebars file (if needed).
|
|
35
|
-
|
|
31
|
+
// Note: we don't need the sidebars file to be normalized: it's ok to let plugin option changes to impact older, versioned sidebars
|
|
32
|
+
const sidebars = loadSidebarsFile(sidebarPath);
|
|
36
33
|
|
|
37
34
|
// Do not create a useless versioned sidebars file if sidebars file is empty or sidebars are disabled/false)
|
|
38
|
-
const shouldCreateVersionedSidebarFile =
|
|
39
|
-
Object.keys(loadedSidebars).length > 0;
|
|
35
|
+
const shouldCreateVersionedSidebarFile = Object.keys(sidebars).length > 0;
|
|
40
36
|
|
|
41
37
|
if (shouldCreateVersionedSidebarFile) {
|
|
42
|
-
// TODO @slorber: this "version prefix" in versioned sidebars looks like a bad idea to me
|
|
43
|
-
// TODO try to get rid of it
|
|
44
|
-
// Transform id in original sidebar to versioned id.
|
|
45
|
-
const prependVersion = (item: SidebarItem): SidebarItem => {
|
|
46
|
-
if (item.type === 'ref' || item.type === 'doc') {
|
|
47
|
-
return {
|
|
48
|
-
type: item.type,
|
|
49
|
-
id: `version-${version}/${item.id}`,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
return item;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const versionedSidebar = Object.entries(loadedSidebars).reduce(
|
|
56
|
-
(acc: NormalizedSidebars, [sidebarId, sidebar]) => {
|
|
57
|
-
const versionedId = `version-${version}/${sidebarId}`;
|
|
58
|
-
acc[versionedId] = transformSidebarItems(
|
|
59
|
-
sidebar as Sidebar,
|
|
60
|
-
prependVersion,
|
|
61
|
-
);
|
|
62
|
-
return acc;
|
|
63
|
-
},
|
|
64
|
-
{},
|
|
65
|
-
);
|
|
66
|
-
|
|
67
38
|
const versionedSidebarsDir = getVersionedSidebarsDirPath(siteDir, pluginId);
|
|
68
39
|
const newSidebarFile = path.join(
|
|
69
40
|
versionedSidebarsDir,
|
|
@@ -72,7 +43,7 @@ function createVersionedSidebarFile({
|
|
|
72
43
|
fs.ensureDirSync(path.dirname(newSidebarFile));
|
|
73
44
|
fs.writeFileSync(
|
|
74
45
|
newSidebarFile,
|
|
75
|
-
`${JSON.stringify(
|
|
46
|
+
`${JSON.stringify(sidebars, null, 2)}\n`,
|
|
76
47
|
'utf8',
|
|
77
48
|
);
|
|
78
49
|
}
|
|
@@ -155,7 +126,6 @@ export function cliDocsVersionCommand(
|
|
|
155
126
|
pluginId,
|
|
156
127
|
version,
|
|
157
128
|
sidebarPath: resolveSidebarPathOption(siteDir, sidebarPath),
|
|
158
|
-
options,
|
|
159
129
|
});
|
|
160
130
|
|
|
161
131
|
// Update versions.json file.
|