@docusaurus/plugin-content-docs 2.0.0-beta.8bda3b2db → 2.0.0-beta.9
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/cli.d.ts +2 -2
- package/lib/cli.js +20 -24
- package/lib/client/docsClientUtils.d.ts +1 -4
- package/lib/client/docsClientUtils.js +12 -16
- package/lib/docFrontMatter.js +7 -3
- package/lib/docs.d.ts +4 -2
- package/lib/docs.js +77 -23
- package/lib/index.js +88 -94
- package/lib/lastUpdate.js +8 -8
- package/lib/markdown/index.d.ts +3 -6
- package/lib/markdown/index.js +3 -3
- package/lib/markdown/linkify.js +2 -2
- package/lib/options.d.ts +1 -1
- package/lib/options.js +39 -11
- package/lib/props.d.ts +7 -2
- package/lib/props.js +27 -4
- package/lib/{sidebarItemsGenerator.d.ts → sidebars/generator.d.ts} +3 -1
- package/lib/sidebars/generator.js +174 -0
- package/lib/sidebars/index.d.ts +14 -0
- package/lib/sidebars/index.js +64 -0
- package/lib/sidebars/normalization.d.ts +9 -0
- package/lib/sidebars/normalization.js +58 -0
- package/lib/sidebars/processor.d.ts +16 -0
- package/lib/sidebars/processor.js +70 -0
- package/lib/sidebars/types.d.ts +87 -0
- package/lib/sidebars/types.js +13 -0
- package/lib/sidebars/utils.d.ts +22 -0
- package/lib/sidebars/utils.js +101 -0
- package/lib/sidebars/validation.d.ts +8 -0
- package/lib/sidebars/validation.js +102 -0
- package/lib/slug.js +4 -4
- package/lib/tags.d.ts +8 -0
- package/lib/tags.js +22 -0
- package/lib/theme/hooks/useDocs.js +24 -21
- package/lib/translations.d.ts +1 -1
- package/lib/translations.js +13 -13
- package/lib/types.d.ts +35 -58
- package/lib/versions.d.ts +1 -1
- package/lib/versions.js +75 -22
- package/package.json +15 -14
- package/src/__tests__/__fixtures__/simple-site/docs/_partials/somePartial.md +3 -0
- package/src/__tests__/__fixtures__/simple-site/docs/_partials/subfolder/somePartial.md +3 -0
- package/src/__tests__/__fixtures__/simple-site/docs/_somePartial.md +3 -0
- package/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md +5 -0
- package/src/__tests__/__fixtures__/simple-site/docs/hello.md +1 -0
- package/src/__tests__/__fixtures__/simple-site/docs/rootAbsoluteSlug.md +2 -0
- package/src/__tests__/__fixtures__/simple-site/docs/rootRelativeSlug.md +2 -0
- package/src/__tests__/__fixtures__/simple-site/docs/rootResolvedSlug.md +2 -0
- package/src/__tests__/__fixtures__/simple-site/docs/rootTryToEscapeSlug.md +2 -0
- package/src/__tests__/__fixtures__/simple-site/sidebars.json +15 -1
- package/src/__tests__/__fixtures__/versioned-site/docs/foo/bar.md +6 -0
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_partials/somePartial.md +3 -0
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_partials/subfolder/somePartial.md +3 -0
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_somePartial.md +3 -0
- package/src/__tests__/__snapshots__/cli.test.ts.snap +33 -0
- package/src/__tests__/__snapshots__/docs.test.ts.snap +140 -0
- package/src/__tests__/__snapshots__/index.test.ts.snap +478 -60
- package/src/__tests__/__snapshots__/translations.test.ts.snap +0 -3
- package/src/__tests__/cli.test.ts +14 -10
- package/src/__tests__/docFrontMatter.test.ts +163 -48
- package/src/__tests__/docs.test.ts +167 -21
- package/src/__tests__/index.test.ts +74 -30
- package/src/__tests__/lastUpdate.test.ts +3 -2
- package/src/__tests__/options.test.ts +46 -3
- package/src/__tests__/props.test.ts +62 -0
- package/src/__tests__/translations.test.ts +0 -1
- package/src/__tests__/versions.test.ts +88 -60
- package/src/cli.ts +27 -30
- package/src/client/__tests__/docsClientUtils.test.ts +4 -5
- package/src/client/docsClientUtils.ts +6 -27
- package/src/docFrontMatter.ts +8 -3
- package/src/docs.ts +92 -9
- package/src/index.ts +114 -121
- package/src/lastUpdate.ts +10 -6
- package/src/markdown/index.ts +8 -12
- package/src/numberPrefix.ts +4 -2
- package/src/options.ts +47 -17
- package/src/plugin-content-docs.d.ts +121 -34
- package/src/props.ts +42 -6
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-shorthand.js +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-items.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-label.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category.js +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed-first-level.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-doc-id-not-string.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-first-level-not-category.js +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-href.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-label.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-unknown-type.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-wrong-field.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars.json +0 -0
- package/src/{__tests__/__snapshots__/sidebars.test.ts.snap → sidebars/__tests__/__snapshots__/index.test.ts.snap} +21 -6
- package/src/{__tests__/sidebarItemsGenerator.test.ts → sidebars/__tests__/generator.test.ts} +29 -7
- package/src/sidebars/__tests__/index.test.ts +202 -0
- package/src/sidebars/__tests__/processor.test.ts +148 -0
- package/src/sidebars/__tests__/utils.test.ts +395 -0
- package/src/sidebars/generator.ts +253 -0
- package/src/sidebars/index.ts +84 -0
- package/src/sidebars/normalization.ts +88 -0
- package/src/sidebars/processor.ts +124 -0
- package/src/sidebars/types.ts +156 -0
- package/src/sidebars/utils.ts +146 -0
- package/src/sidebars/validation.ts +124 -0
- package/src/tags.ts +21 -0
- package/src/theme/hooks/useDocs.ts +5 -1
- package/src/translations.ts +26 -36
- package/src/types.ts +48 -99
- package/src/versions.ts +109 -17
- package/lib/sidebarItemsGenerator.js +0 -211
- package/lib/sidebars.d.ts +0 -43
- package/lib/sidebars.js +0 -319
- package/src/__tests__/sidebars.test.ts +0 -639
- package/src/sidebarItemsGenerator.ts +0 -307
- package/src/sidebars.ts +0 -506
|
@@ -0,0 +1,124 @@
|
|
|
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 {Joi, URISchema} from '@docusaurus/utils-validation';
|
|
9
|
+
import {
|
|
10
|
+
SidebarItemConfig,
|
|
11
|
+
SidebarCategoriesShorthand,
|
|
12
|
+
SidebarItemBase,
|
|
13
|
+
SidebarItemAutogenerated,
|
|
14
|
+
SidebarItemDoc,
|
|
15
|
+
SidebarItemLink,
|
|
16
|
+
SidebarItemCategoryConfig,
|
|
17
|
+
SidebarsConfig,
|
|
18
|
+
isCategoriesShorthand,
|
|
19
|
+
} from './types';
|
|
20
|
+
|
|
21
|
+
const sidebarItemBaseSchema = Joi.object<SidebarItemBase>({
|
|
22
|
+
className: Joi.string(),
|
|
23
|
+
customProps: Joi.object().unknown(),
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const sidebarItemAutogeneratedSchema =
|
|
27
|
+
sidebarItemBaseSchema.append<SidebarItemAutogenerated>({
|
|
28
|
+
type: 'autogenerated',
|
|
29
|
+
dirName: Joi.string()
|
|
30
|
+
.required()
|
|
31
|
+
.pattern(/^[^/](.*[^/])?$/)
|
|
32
|
+
.message(
|
|
33
|
+
'"dirName" must be a dir path relative to the docs folder root, and should not start or end with slash',
|
|
34
|
+
),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const sidebarItemDocSchema = sidebarItemBaseSchema.append<SidebarItemDoc>({
|
|
38
|
+
type: Joi.string().valid('doc', 'ref').required(),
|
|
39
|
+
id: Joi.string().required(),
|
|
40
|
+
label: Joi.string(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const sidebarItemLinkSchema = sidebarItemBaseSchema.append<SidebarItemLink>({
|
|
44
|
+
type: 'link',
|
|
45
|
+
href: URISchema.required(),
|
|
46
|
+
label: Joi.string()
|
|
47
|
+
.required()
|
|
48
|
+
.messages({'any.unknown': '"label" must be a string'}),
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const sidebarItemCategorySchema =
|
|
52
|
+
sidebarItemBaseSchema.append<SidebarItemCategoryConfig>({
|
|
53
|
+
type: 'category',
|
|
54
|
+
label: Joi.string()
|
|
55
|
+
.required()
|
|
56
|
+
.messages({'any.unknown': '"label" must be a string'}),
|
|
57
|
+
// TODO: Joi doesn't allow mutual recursion. See https://github.com/sideway/joi/issues/2611
|
|
58
|
+
items: Joi.array()
|
|
59
|
+
.required()
|
|
60
|
+
.messages({'any.unknown': '"items" must be an array'}), // .items(Joi.link('#sidebarItemSchema')),
|
|
61
|
+
collapsed: Joi.boolean().messages({
|
|
62
|
+
'any.unknown': '"collapsed" must be a boolean',
|
|
63
|
+
}),
|
|
64
|
+
collapsible: Joi.boolean().messages({
|
|
65
|
+
'any.unknown': '"collapsible" must be a boolean',
|
|
66
|
+
}),
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const sidebarItemSchema: Joi.Schema<SidebarItemConfig> = Joi.object()
|
|
70
|
+
.when('.type', {
|
|
71
|
+
switch: [
|
|
72
|
+
{is: 'link', then: sidebarItemLinkSchema},
|
|
73
|
+
{
|
|
74
|
+
is: Joi.string().valid('doc', 'ref').required(),
|
|
75
|
+
then: sidebarItemDocSchema,
|
|
76
|
+
},
|
|
77
|
+
{is: 'autogenerated', then: sidebarItemAutogeneratedSchema},
|
|
78
|
+
{is: 'category', then: sidebarItemCategorySchema},
|
|
79
|
+
{
|
|
80
|
+
is: 'subcategory',
|
|
81
|
+
then: Joi.forbidden().messages({
|
|
82
|
+
'any.unknown':
|
|
83
|
+
'Docusaurus v2: "subcategory" has been renamed as "category".',
|
|
84
|
+
}),
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
is: Joi.string().required(),
|
|
88
|
+
then: Joi.forbidden().messages({
|
|
89
|
+
'any.unknown': 'Unknown sidebar item type "{.type}".',
|
|
90
|
+
}),
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
})
|
|
94
|
+
.id('sidebarItemSchema');
|
|
95
|
+
|
|
96
|
+
function validateSidebarItem(item: unknown): asserts item is SidebarItemConfig {
|
|
97
|
+
if (typeof item === 'string') {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// TODO: remove once with proper Joi support
|
|
101
|
+
// Because we can't use Joi to validate nested items (see above), we do it manually
|
|
102
|
+
if (isCategoriesShorthand(item as SidebarItemConfig)) {
|
|
103
|
+
Object.values(item as SidebarCategoriesShorthand).forEach((category) =>
|
|
104
|
+
category.forEach(validateSidebarItem),
|
|
105
|
+
);
|
|
106
|
+
} else {
|
|
107
|
+
Joi.assert(item, sidebarItemSchema);
|
|
108
|
+
if ((item as SidebarItemCategoryConfig).type === 'category') {
|
|
109
|
+
(item as SidebarItemCategoryConfig).items.forEach(validateSidebarItem);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function validateSidebars(
|
|
115
|
+
sidebars: unknown,
|
|
116
|
+
): asserts sidebars is SidebarsConfig {
|
|
117
|
+
Object.values(sidebars as SidebarsConfig).forEach((sidebar) => {
|
|
118
|
+
if (Array.isArray(sidebar)) {
|
|
119
|
+
sidebar.forEach(validateSidebarItem);
|
|
120
|
+
} else {
|
|
121
|
+
validateSidebarItem(sidebar);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
package/src/tags.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
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 {groupTaggedItems} from '@docusaurus/utils';
|
|
9
|
+
import {VersionTags, DocMetadata} from './types';
|
|
10
|
+
import {mapValues} from 'lodash';
|
|
11
|
+
|
|
12
|
+
export function getVersionTags(docs: DocMetadata[]): VersionTags {
|
|
13
|
+
const groups = groupTaggedItems(docs, (doc) => doc.tags);
|
|
14
|
+
return mapValues(groups, (group) => {
|
|
15
|
+
return {
|
|
16
|
+
name: group.tag.label,
|
|
17
|
+
docIds: group.items.map((item) => item.id),
|
|
18
|
+
permalink: group.tag.permalink,
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
}
|
|
@@ -24,11 +24,15 @@ import {
|
|
|
24
24
|
GetActivePluginOptions,
|
|
25
25
|
} from '../../client/docsClientUtils';
|
|
26
26
|
|
|
27
|
+
// Important to use a constant object to avoid React useEffect executions etc...,
|
|
28
|
+
// see https://github.com/facebook/docusaurus/issues/5089
|
|
29
|
+
const StableEmptyObject = {};
|
|
30
|
+
|
|
27
31
|
// Not using useAllPluginInstancesData() because in blog-only mode, docs hooks are still used by the theme
|
|
28
32
|
// We need a fail-safe fallback when the docs plugin is not in use
|
|
29
33
|
export const useAllDocsData = (): Record<string, GlobalPluginData> =>
|
|
30
34
|
// useAllPluginInstancesData('docusaurus-plugin-content-docs');
|
|
31
|
-
useGlobalData()['docusaurus-plugin-content-docs'] ??
|
|
35
|
+
useGlobalData()['docusaurus-plugin-content-docs'] ?? StableEmptyObject;
|
|
32
36
|
|
|
33
37
|
export const useDocsData = (pluginId: string | undefined): GlobalPluginData =>
|
|
34
38
|
usePluginData('docusaurus-plugin-content-docs', pluginId) as GlobalPluginData;
|
package/src/translations.ts
CHANGED
|
@@ -5,20 +5,15 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
Sidebar,
|
|
11
|
-
LoadedContent,
|
|
12
|
-
Sidebars,
|
|
13
|
-
SidebarItem,
|
|
14
|
-
} from './types';
|
|
8
|
+
import type {LoadedVersion, LoadedContent} from './types';
|
|
9
|
+
import type {Sidebar, Sidebars} from './sidebars/types';
|
|
15
10
|
|
|
16
|
-
import {chain, mapValues,
|
|
11
|
+
import {chain, mapValues, keyBy} from 'lodash';
|
|
17
12
|
import {
|
|
18
13
|
collectSidebarCategories,
|
|
19
14
|
transformSidebarItems,
|
|
20
15
|
collectSidebarLinks,
|
|
21
|
-
} from './sidebars';
|
|
16
|
+
} from './sidebars/utils';
|
|
22
17
|
import {
|
|
23
18
|
TranslationFileContent,
|
|
24
19
|
TranslationFile,
|
|
@@ -131,29 +126,25 @@ function translateSidebar({
|
|
|
131
126
|
sidebarName: string;
|
|
132
127
|
sidebarsTranslations: TranslationFileContent;
|
|
133
128
|
}): Sidebar {
|
|
134
|
-
return transformSidebarItems(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
return item;
|
|
155
|
-
},
|
|
156
|
-
);
|
|
129
|
+
return transformSidebarItems(sidebar, (item) => {
|
|
130
|
+
if (item.type === 'category') {
|
|
131
|
+
return {
|
|
132
|
+
...item,
|
|
133
|
+
label:
|
|
134
|
+
sidebarsTranslations[`sidebar.${sidebarName}.category.${item.label}`]
|
|
135
|
+
?.message ?? item.label,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
if (item.type === 'link') {
|
|
139
|
+
return {
|
|
140
|
+
...item,
|
|
141
|
+
label:
|
|
142
|
+
sidebarsTranslations[`sidebar.${sidebarName}.link.${item.label}`]
|
|
143
|
+
?.message ?? item.label,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return item;
|
|
147
|
+
});
|
|
157
148
|
}
|
|
158
149
|
|
|
159
150
|
function getSidebarsTranslations(
|
|
@@ -193,9 +184,8 @@ function getVersionTranslationFiles(version: LoadedVersion): TranslationFiles {
|
|
|
193
184
|
},
|
|
194
185
|
};
|
|
195
186
|
|
|
196
|
-
const sidebarsTranslations: TranslationFileContent =
|
|
197
|
-
version
|
|
198
|
-
);
|
|
187
|
+
const sidebarsTranslations: TranslationFileContent =
|
|
188
|
+
getSidebarsTranslations(version);
|
|
199
189
|
|
|
200
190
|
// const docsTranslations: TranslationFileContent = getDocsTranslations(version);
|
|
201
191
|
|
|
@@ -227,7 +217,7 @@ function translateVersion(
|
|
|
227
217
|
function getVersionsTranslationFiles(
|
|
228
218
|
versions: LoadedVersion[],
|
|
229
219
|
): TranslationFiles {
|
|
230
|
-
return
|
|
220
|
+
return versions.flatMap(getVersionTranslationFiles);
|
|
231
221
|
}
|
|
232
222
|
function translateVersions(
|
|
233
223
|
versions: LoadedVersion[],
|
package/src/types.ts
CHANGED
|
@@ -5,14 +5,15 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
// eslint-disable-next-line spaced-comment
|
|
9
8
|
/// <reference types="@docusaurus/module-type-aliases" />
|
|
10
9
|
|
|
11
10
|
import type {RemarkAndRehypePluginOptions} from '@docusaurus/mdx-loader';
|
|
12
|
-
import {
|
|
11
|
+
import type {Tag, FrontMatterTag} from '@docusaurus/utils';
|
|
12
|
+
import type {
|
|
13
13
|
BrokenMarkdownLink as IBrokenMarkdownLink,
|
|
14
14
|
ContentPaths,
|
|
15
15
|
} from '@docusaurus/utils/lib/markdownLinks';
|
|
16
|
+
import type {SidebarItemsGeneratorOption, Sidebars} from './sidebars/types';
|
|
16
17
|
|
|
17
18
|
export type DocFile = {
|
|
18
19
|
contentPath: string; // /!\ may be localized
|
|
@@ -28,8 +29,12 @@ export type VersionMetadata = ContentPaths & {
|
|
|
28
29
|
versionName: VersionName; // 1.0.0
|
|
29
30
|
versionLabel: string; // Version 1.0.0
|
|
30
31
|
versionPath: string; // /baseUrl/docs/1.0.0
|
|
32
|
+
tagsPath: string;
|
|
31
33
|
versionEditUrl?: string | undefined;
|
|
32
34
|
versionEditUrlLocalized?: string | undefined;
|
|
35
|
+
versionBanner: VersionBanner | null;
|
|
36
|
+
versionBadge: boolean;
|
|
37
|
+
versionClassName: string;
|
|
33
38
|
isLast: boolean;
|
|
34
39
|
sidebarFilePath: string | false | undefined; // versioned_sidebars/1.0.0.json
|
|
35
40
|
routePriority: number | undefined; // -1 for the latest docs
|
|
@@ -59,9 +64,15 @@ export type PathOptions = {
|
|
|
59
64
|
sidebarPath?: string | false | undefined;
|
|
60
65
|
};
|
|
61
66
|
|
|
67
|
+
// TODO support custom version banner? {type: "error", content: "html content"}
|
|
68
|
+
export type VersionBanner = 'unreleased' | 'unmaintained';
|
|
69
|
+
|
|
62
70
|
export type VersionOptions = {
|
|
63
71
|
path?: string;
|
|
64
72
|
label?: string;
|
|
73
|
+
banner?: 'none' | VersionBanner;
|
|
74
|
+
badge?: boolean;
|
|
75
|
+
className?: string;
|
|
65
76
|
};
|
|
66
77
|
|
|
67
78
|
export type VersionsOptions = {
|
|
@@ -70,111 +81,30 @@ export type VersionsOptions = {
|
|
|
70
81
|
onlyIncludeVersions?: string[];
|
|
71
82
|
};
|
|
72
83
|
|
|
84
|
+
export type SidebarOptions = {
|
|
85
|
+
sidebarCollapsible: boolean;
|
|
86
|
+
sidebarCollapsed: boolean;
|
|
87
|
+
};
|
|
88
|
+
|
|
73
89
|
export type PluginOptions = MetadataOptions &
|
|
74
90
|
PathOptions &
|
|
75
91
|
VersionsOptions &
|
|
76
|
-
RemarkAndRehypePluginOptions &
|
|
92
|
+
RemarkAndRehypePluginOptions &
|
|
93
|
+
SidebarOptions & {
|
|
77
94
|
id: string;
|
|
78
95
|
include: string[];
|
|
96
|
+
exclude: string[];
|
|
79
97
|
docLayoutComponent: string;
|
|
80
98
|
docItemComponent: string;
|
|
99
|
+
docTagDocListComponent: string;
|
|
100
|
+
docTagsListComponent: string;
|
|
81
101
|
admonitions: Record<string, unknown>;
|
|
82
102
|
disableVersioning: boolean;
|
|
83
|
-
excludeNextVersionDocs?: boolean;
|
|
84
103
|
includeCurrentVersion: boolean;
|
|
85
104
|
sidebarItemsGenerator: SidebarItemsGeneratorOption;
|
|
105
|
+
tagsBasePath: string;
|
|
86
106
|
};
|
|
87
107
|
|
|
88
|
-
export type SidebarItemBase = {
|
|
89
|
-
customProps?: Record<string, unknown>;
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
export type SidebarItemDoc = SidebarItemBase & {
|
|
93
|
-
type: 'doc' | 'ref';
|
|
94
|
-
label?: string;
|
|
95
|
-
id: string;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
export type SidebarItemLink = SidebarItemBase & {
|
|
99
|
-
type: 'link';
|
|
100
|
-
href: string;
|
|
101
|
-
label: string;
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
export type SidebarItemCategory = SidebarItemBase & {
|
|
105
|
-
type: 'category';
|
|
106
|
-
label: string;
|
|
107
|
-
items: SidebarItem[];
|
|
108
|
-
collapsed: boolean;
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
export type UnprocessedSidebarItemAutogenerated = {
|
|
112
|
-
type: 'autogenerated';
|
|
113
|
-
dirName: string;
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
export type UnprocessedSidebarItemCategory = SidebarItemBase & {
|
|
117
|
-
type: 'category';
|
|
118
|
-
label: string;
|
|
119
|
-
items: UnprocessedSidebarItem[];
|
|
120
|
-
collapsed: boolean;
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
export type UnprocessedSidebarItem =
|
|
124
|
-
| SidebarItemDoc
|
|
125
|
-
| SidebarItemLink
|
|
126
|
-
| UnprocessedSidebarItemCategory
|
|
127
|
-
| UnprocessedSidebarItemAutogenerated;
|
|
128
|
-
|
|
129
|
-
export type UnprocessedSidebar = UnprocessedSidebarItem[];
|
|
130
|
-
export type UnprocessedSidebars = Record<string, UnprocessedSidebar>;
|
|
131
|
-
|
|
132
|
-
export type SidebarItem =
|
|
133
|
-
| SidebarItemDoc
|
|
134
|
-
| SidebarItemLink
|
|
135
|
-
| SidebarItemCategory;
|
|
136
|
-
|
|
137
|
-
export type Sidebar = SidebarItem[];
|
|
138
|
-
export type SidebarItemType = SidebarItem['type'];
|
|
139
|
-
export type Sidebars = Record<string, Sidebar>;
|
|
140
|
-
|
|
141
|
-
// Reduce API surface for options.sidebarItemsGenerator
|
|
142
|
-
// The user-provided generator fn should receive only a subset of metadatas
|
|
143
|
-
// A change to any of these metadatas can be considered as a breaking change
|
|
144
|
-
export type SidebarItemsGeneratorDoc = Pick<
|
|
145
|
-
DocMetadataBase,
|
|
146
|
-
'id' | 'frontMatter' | 'source' | 'sourceDirName' | 'sidebarPosition'
|
|
147
|
-
>;
|
|
148
|
-
export type SidebarItemsGeneratorVersion = Pick<
|
|
149
|
-
VersionMetadata,
|
|
150
|
-
'versionName' | 'contentPath'
|
|
151
|
-
>;
|
|
152
|
-
|
|
153
|
-
export type SidebarItemsGeneratorArgs = {
|
|
154
|
-
item: UnprocessedSidebarItemAutogenerated;
|
|
155
|
-
version: SidebarItemsGeneratorVersion;
|
|
156
|
-
docs: SidebarItemsGeneratorDoc[];
|
|
157
|
-
numberPrefixParser: NumberPrefixParser;
|
|
158
|
-
};
|
|
159
|
-
export type SidebarItemsGenerator = (
|
|
160
|
-
generatorArgs: SidebarItemsGeneratorArgs,
|
|
161
|
-
) => Promise<SidebarItem[]>;
|
|
162
|
-
|
|
163
|
-
// Also inject the default generator to conveniently wrap/enhance/sort the default sidebar gen logic
|
|
164
|
-
// see https://github.com/facebook/docusaurus/issues/4640#issuecomment-822292320
|
|
165
|
-
export type SidebarItemsGeneratorOptionArgs = {
|
|
166
|
-
defaultSidebarItemsGenerator: SidebarItemsGenerator;
|
|
167
|
-
} & SidebarItemsGeneratorArgs;
|
|
168
|
-
export type SidebarItemsGeneratorOption = (
|
|
169
|
-
generatorArgs: SidebarItemsGeneratorOptionArgs,
|
|
170
|
-
) => Promise<SidebarItem[]>;
|
|
171
|
-
|
|
172
|
-
export type OrderMetadata = {
|
|
173
|
-
previous?: string;
|
|
174
|
-
next?: string;
|
|
175
|
-
sidebar?: string;
|
|
176
|
-
};
|
|
177
|
-
|
|
178
108
|
export type LastUpdateData = {
|
|
179
109
|
lastUpdatedAt?: number;
|
|
180
110
|
formattedLastUpdatedAt?: string;
|
|
@@ -182,8 +112,11 @@ export type LastUpdateData = {
|
|
|
182
112
|
};
|
|
183
113
|
|
|
184
114
|
export type DocFrontMatter = {
|
|
115
|
+
// Front matter uses snake case
|
|
116
|
+
/* eslint-disable camelcase */
|
|
185
117
|
id?: string;
|
|
186
118
|
title?: string;
|
|
119
|
+
tags?: FrontMatterTag[];
|
|
187
120
|
hide_title?: boolean;
|
|
188
121
|
hide_table_of_contents?: boolean;
|
|
189
122
|
keywords?: string[];
|
|
@@ -192,9 +125,15 @@ export type DocFrontMatter = {
|
|
|
192
125
|
slug?: string;
|
|
193
126
|
sidebar_label?: string;
|
|
194
127
|
sidebar_position?: number;
|
|
128
|
+
sidebar_class_name?: string;
|
|
195
129
|
pagination_label?: string;
|
|
196
130
|
custom_edit_url?: string | null;
|
|
197
131
|
parse_number_prefixes?: boolean;
|
|
132
|
+
toc_min_heading_level?: number;
|
|
133
|
+
toc_max_heading_level?: number;
|
|
134
|
+
pagination_next?: string | null;
|
|
135
|
+
pagination_prev?: string | null;
|
|
136
|
+
/* eslint-enable camelcase */
|
|
198
137
|
};
|
|
199
138
|
|
|
200
139
|
export type DocMetadataBase = LastUpdateData & {
|
|
@@ -208,9 +147,9 @@ export type DocMetadataBase = LastUpdateData & {
|
|
|
208
147
|
sourceDirName: string; // relative to the docs folder (can be ".")
|
|
209
148
|
slug: string;
|
|
210
149
|
permalink: string;
|
|
211
|
-
// eslint-disable-next-line camelcase
|
|
212
150
|
sidebarPosition?: number;
|
|
213
151
|
editUrl?: string | null;
|
|
152
|
+
tags: Tag[];
|
|
214
153
|
frontMatter: DocFrontMatter & Record<string, unknown>;
|
|
215
154
|
};
|
|
216
155
|
|
|
@@ -228,12 +167,21 @@ export type DocMetadata = DocMetadataBase & {
|
|
|
228
167
|
export type SourceToPermalink = {
|
|
229
168
|
[source: string]: string;
|
|
230
169
|
};
|
|
170
|
+
|
|
171
|
+
export type VersionTag = {
|
|
172
|
+
name: string; // normalized name/label of the tag
|
|
173
|
+
docIds: string[]; // all doc ids having this tag
|
|
174
|
+
permalink: string; // pathname of the tag
|
|
175
|
+
};
|
|
176
|
+
export type VersionTags = {
|
|
177
|
+
[key: string]: VersionTag;
|
|
178
|
+
};
|
|
179
|
+
|
|
231
180
|
export type LoadedVersion = VersionMetadata & {
|
|
232
181
|
versionPath: string;
|
|
233
182
|
mainDocId: string;
|
|
234
183
|
docs: DocMetadata[];
|
|
235
184
|
sidebars: Sidebars;
|
|
236
|
-
permalinkToSidebar: Record<string, string>;
|
|
237
185
|
};
|
|
238
186
|
|
|
239
187
|
export type LoadedContent = {
|
|
@@ -269,6 +217,7 @@ export type DocsMarkdownOption = {
|
|
|
269
217
|
onBrokenMarkdownLink: (brokenMarkdownLink: BrokenMarkdownLink) => void;
|
|
270
218
|
};
|
|
271
219
|
|
|
272
|
-
export type NumberPrefixParser = (
|
|
273
|
-
filename: string
|
|
274
|
-
|
|
220
|
+
export type NumberPrefixParser = (filename: string) => {
|
|
221
|
+
filename: string;
|
|
222
|
+
numberPrefix?: number;
|
|
223
|
+
};
|
package/src/versions.ts
CHANGED
|
@@ -9,6 +9,7 @@ import path from 'path';
|
|
|
9
9
|
import fs from 'fs-extra';
|
|
10
10
|
import {
|
|
11
11
|
PluginOptions,
|
|
12
|
+
VersionBanner,
|
|
12
13
|
VersionMetadata,
|
|
13
14
|
VersionOptions,
|
|
14
15
|
VersionsOptions,
|
|
@@ -255,14 +256,92 @@ function getVersionEditUrls({
|
|
|
255
256
|
};
|
|
256
257
|
}
|
|
257
258
|
|
|
259
|
+
function getDefaultVersionBanner({
|
|
260
|
+
versionName,
|
|
261
|
+
versionNames,
|
|
262
|
+
lastVersionName,
|
|
263
|
+
}: {
|
|
264
|
+
versionName: string;
|
|
265
|
+
versionNames: string[];
|
|
266
|
+
lastVersionName: string;
|
|
267
|
+
}): VersionBanner | null {
|
|
268
|
+
// Current version: good, no banner
|
|
269
|
+
if (versionName === lastVersionName) {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
// Upcoming versions: unreleased banner
|
|
273
|
+
else if (
|
|
274
|
+
versionNames.indexOf(versionName) < versionNames.indexOf(lastVersionName)
|
|
275
|
+
) {
|
|
276
|
+
return 'unreleased';
|
|
277
|
+
}
|
|
278
|
+
// Older versions: display unmaintained banner
|
|
279
|
+
else {
|
|
280
|
+
return 'unmaintained';
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function getVersionBanner({
|
|
285
|
+
versionName,
|
|
286
|
+
versionNames,
|
|
287
|
+
lastVersionName,
|
|
288
|
+
options,
|
|
289
|
+
}: {
|
|
290
|
+
versionName: string;
|
|
291
|
+
versionNames: string[];
|
|
292
|
+
lastVersionName: string;
|
|
293
|
+
options: Pick<PluginOptions, 'versions'>;
|
|
294
|
+
}): VersionBanner | null {
|
|
295
|
+
const versionBannerOption = options.versions[versionName]?.banner;
|
|
296
|
+
if (versionBannerOption) {
|
|
297
|
+
return versionBannerOption === 'none' ? null : versionBannerOption;
|
|
298
|
+
}
|
|
299
|
+
return getDefaultVersionBanner({
|
|
300
|
+
versionName,
|
|
301
|
+
versionNames,
|
|
302
|
+
lastVersionName,
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function getVersionBadge({
|
|
307
|
+
versionName,
|
|
308
|
+
versionNames,
|
|
309
|
+
options,
|
|
310
|
+
}: {
|
|
311
|
+
versionName: string;
|
|
312
|
+
versionNames: string[];
|
|
313
|
+
options: Pick<PluginOptions, 'versions'>;
|
|
314
|
+
}): boolean {
|
|
315
|
+
const versionBadgeOption = options.versions[versionName]?.badge;
|
|
316
|
+
// If site is not versioned or only one version is included
|
|
317
|
+
// we don't show the version badge by default
|
|
318
|
+
// See https://github.com/facebook/docusaurus/issues/3362
|
|
319
|
+
const versionBadgeDefault = versionNames.length !== 1;
|
|
320
|
+
return versionBadgeOption ?? versionBadgeDefault;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function getVersionClassName({
|
|
324
|
+
versionName,
|
|
325
|
+
options,
|
|
326
|
+
}: {
|
|
327
|
+
versionName: string;
|
|
328
|
+
options: Pick<PluginOptions, 'versions'>;
|
|
329
|
+
}): string {
|
|
330
|
+
const versionClassNameOption = options.versions[versionName]?.className;
|
|
331
|
+
const versionClassNameDefault = `docs-version-${versionName}`;
|
|
332
|
+
return versionClassNameOption ?? versionClassNameDefault;
|
|
333
|
+
}
|
|
334
|
+
|
|
258
335
|
function createVersionMetadata({
|
|
259
336
|
versionName,
|
|
260
|
-
|
|
337
|
+
versionNames,
|
|
338
|
+
lastVersionName,
|
|
261
339
|
context,
|
|
262
340
|
options,
|
|
263
341
|
}: {
|
|
264
342
|
versionName: string;
|
|
265
|
-
|
|
343
|
+
versionNames: string[];
|
|
344
|
+
lastVersionName: string;
|
|
266
345
|
context: Pick<LoadContext, 'siteDir' | 'baseUrl' | 'i18n'>;
|
|
267
346
|
options: Pick<
|
|
268
347
|
PluginOptions,
|
|
@@ -270,29 +349,27 @@ function createVersionMetadata({
|
|
|
270
349
|
| 'path'
|
|
271
350
|
| 'sidebarPath'
|
|
272
351
|
| 'routeBasePath'
|
|
352
|
+
| 'tagsBasePath'
|
|
273
353
|
| 'versions'
|
|
274
354
|
| 'editUrl'
|
|
275
355
|
| 'editCurrentVersion'
|
|
276
356
|
>;
|
|
277
357
|
}): VersionMetadata {
|
|
278
|
-
const {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
} = getVersionMetadataPaths({
|
|
283
|
-
versionName,
|
|
284
|
-
context,
|
|
285
|
-
options,
|
|
286
|
-
});
|
|
358
|
+
const {sidebarFilePath, contentPath, contentPathLocalized} =
|
|
359
|
+
getVersionMetadataPaths({versionName, context, options});
|
|
360
|
+
|
|
361
|
+
const isLast = versionName === lastVersionName;
|
|
287
362
|
|
|
288
363
|
// retro-compatible values
|
|
289
364
|
const defaultVersionLabel =
|
|
290
365
|
versionName === CURRENT_VERSION_NAME ? 'Next' : versionName;
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
: versionName;
|
|
366
|
+
function getDefaultVersionPathPart() {
|
|
367
|
+
if (isLast) {
|
|
368
|
+
return '';
|
|
369
|
+
}
|
|
370
|
+
return versionName === CURRENT_VERSION_NAME ? 'next' : versionName;
|
|
371
|
+
}
|
|
372
|
+
const defaultVersionPathPart = getDefaultVersionPathPart();
|
|
296
373
|
|
|
297
374
|
const versionOptions: VersionOptions = options.versions[versionName] ?? {};
|
|
298
375
|
|
|
@@ -315,12 +392,25 @@ function createVersionMetadata({
|
|
|
315
392
|
// Because /docs/:route` should always be after `/docs/versionName/:route`.
|
|
316
393
|
const routePriority = versionPathPart === '' ? -1 : undefined;
|
|
317
394
|
|
|
395
|
+
// the path that will be used to refer the docs tags
|
|
396
|
+
// example below will be using /docs/tags
|
|
397
|
+
const tagsPath = normalizeUrl([versionPath, options.tagsBasePath]);
|
|
398
|
+
|
|
318
399
|
return {
|
|
319
400
|
versionName,
|
|
320
401
|
versionLabel,
|
|
321
402
|
versionPath,
|
|
403
|
+
tagsPath,
|
|
322
404
|
versionEditUrl: versionEditUrls?.versionEditUrl,
|
|
323
405
|
versionEditUrlLocalized: versionEditUrls?.versionEditUrlLocalized,
|
|
406
|
+
versionBanner: getVersionBanner({
|
|
407
|
+
versionName,
|
|
408
|
+
versionNames,
|
|
409
|
+
lastVersionName,
|
|
410
|
+
options,
|
|
411
|
+
}),
|
|
412
|
+
versionBadge: getVersionBadge({versionName, versionNames, options}),
|
|
413
|
+
versionClassName: getVersionClassName({versionName, options}),
|
|
324
414
|
isLast,
|
|
325
415
|
routePriority,
|
|
326
416
|
sidebarFilePath,
|
|
@@ -465,6 +555,7 @@ export function readVersionsMetadata({
|
|
|
465
555
|
| 'path'
|
|
466
556
|
| 'sidebarPath'
|
|
467
557
|
| 'routeBasePath'
|
|
558
|
+
| 'tagsBasePath'
|
|
468
559
|
| 'includeCurrentVersion'
|
|
469
560
|
| 'disableVersioning'
|
|
470
561
|
| 'lastVersion'
|
|
@@ -486,7 +577,8 @@ export function readVersionsMetadata({
|
|
|
486
577
|
const versionsMetadata = versionNames.map((versionName) =>
|
|
487
578
|
createVersionMetadata({
|
|
488
579
|
versionName,
|
|
489
|
-
|
|
580
|
+
versionNames,
|
|
581
|
+
lastVersionName,
|
|
490
582
|
context,
|
|
491
583
|
options,
|
|
492
584
|
}),
|