@docusaurus/plugin-content-docs 0.0.0-4547 → 0.0.0-4551
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/cli.js +2 -1
- package/lib/client/index.d.ts +13 -1
- package/lib/client/index.js +66 -1
- package/lib/{server/index.d.ts → server-export.d.ts} +2 -2
- package/lib/{server/index.js → server-export.js} +7 -4
- package/lib/sidebars/generator.js +6 -7
- package/lib/sidebars/index.d.ts +3 -6
- package/lib/sidebars/index.js +8 -18
- package/lib/sidebars/normalization.d.ts +2 -3
- package/lib/sidebars/normalization.js +14 -32
- package/lib/sidebars/postProcessor.d.ts +8 -0
- package/lib/sidebars/postProcessor.js +71 -0
- package/lib/sidebars/processor.d.ts +2 -14
- package/lib/sidebars/processor.js +17 -55
- package/lib/sidebars/types.d.ts +24 -6
- package/lib/sidebars/utils.js +0 -1
- package/lib/sidebars/validation.d.ts +2 -2
- package/lib/sidebars/validation.js +12 -27
- package/lib/types.d.ts +2 -6
- package/package.json +10 -10
- package/src/cli.ts +3 -2
- package/src/client/index.ts +97 -1
- package/src/{server/index.ts → server-export.ts} +7 -2
- package/src/sidebars/README.md +9 -0
- package/src/sidebars/generator.ts +25 -22
- package/src/sidebars/index.ts +15 -31
- package/src/sidebars/normalization.ts +18 -46
- package/src/sidebars/postProcessor.ts +94 -0
- package/src/sidebars/processor.ts +26 -90
- package/src/sidebars/types.ts +32 -8
- package/src/sidebars/utils.ts +0 -1
- package/src/sidebars/validation.ts +38 -50
- package/src/types.ts +2 -10
- package/lib/client/globalDataHooks.d.ts +0 -19
- package/lib/client/globalDataHooks.js +0 -77
- package/src/client/globalDataHooks.ts +0 -108
|
@@ -0,0 +1,94 @@
|
|
|
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 {normalizeUrl} from '@docusaurus/utils';
|
|
9
|
+
import type {
|
|
10
|
+
SidebarItem,
|
|
11
|
+
Sidebars,
|
|
12
|
+
SidebarProcessorParams,
|
|
13
|
+
ProcessedSidebarItemCategory,
|
|
14
|
+
ProcessedSidebarItem,
|
|
15
|
+
ProcessedSidebars,
|
|
16
|
+
SidebarItemCategoryLink,
|
|
17
|
+
} from './types';
|
|
18
|
+
import {mapValues} from 'lodash';
|
|
19
|
+
|
|
20
|
+
function normalizeCategoryLink(
|
|
21
|
+
category: ProcessedSidebarItemCategory,
|
|
22
|
+
params: SidebarProcessorParams,
|
|
23
|
+
): SidebarItemCategoryLink | undefined {
|
|
24
|
+
if (category.link?.type === 'generated-index') {
|
|
25
|
+
// default slug logic can be improved
|
|
26
|
+
const getDefaultSlug = () =>
|
|
27
|
+
`/category/${params.categoryLabelSlugger.slug(category.label)}`;
|
|
28
|
+
const slug = category.link.slug ?? getDefaultSlug();
|
|
29
|
+
const permalink = normalizeUrl([params.version.versionPath, slug]);
|
|
30
|
+
return {
|
|
31
|
+
...category.link,
|
|
32
|
+
slug,
|
|
33
|
+
permalink,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return category.link;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function postProcessSidebarItem(
|
|
40
|
+
item: ProcessedSidebarItem,
|
|
41
|
+
params: SidebarProcessorParams,
|
|
42
|
+
): SidebarItem {
|
|
43
|
+
if (item.type === 'category') {
|
|
44
|
+
const category = {
|
|
45
|
+
...item,
|
|
46
|
+
collapsed: item.collapsed ?? params.sidebarOptions.sidebarCollapsed,
|
|
47
|
+
collapsible: item.collapsible ?? params.sidebarOptions.sidebarCollapsible,
|
|
48
|
+
link: normalizeCategoryLink(item, params),
|
|
49
|
+
items: item.items.map((subItem) =>
|
|
50
|
+
postProcessSidebarItem(subItem, params),
|
|
51
|
+
),
|
|
52
|
+
};
|
|
53
|
+
// If the current category doesn't have subitems, we render a normal link
|
|
54
|
+
// instead.
|
|
55
|
+
if (category.items.length === 0) {
|
|
56
|
+
if (!category.link) {
|
|
57
|
+
throw new Error(
|
|
58
|
+
`Sidebar category ${item.label} has neither any subitem nor a link. This makes this item not able to link to anything.`,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
switch (category.link.type) {
|
|
62
|
+
case 'doc':
|
|
63
|
+
return {
|
|
64
|
+
type: 'doc',
|
|
65
|
+
label: category.label,
|
|
66
|
+
id: category.link.id,
|
|
67
|
+
};
|
|
68
|
+
case 'generated-index':
|
|
69
|
+
return {
|
|
70
|
+
type: 'link',
|
|
71
|
+
label: category.label,
|
|
72
|
+
href: category.link.permalink,
|
|
73
|
+
};
|
|
74
|
+
default:
|
|
75
|
+
throw new Error('Unexpected sidebar category link type');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// A non-collapsible category can't be collapsed!
|
|
79
|
+
if (category.collapsible === false) {
|
|
80
|
+
category.collapsed = false;
|
|
81
|
+
}
|
|
82
|
+
return category;
|
|
83
|
+
}
|
|
84
|
+
return item;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function postProcessSidebars(
|
|
88
|
+
sidebars: ProcessedSidebars,
|
|
89
|
+
params: SidebarProcessorParams,
|
|
90
|
+
): Sidebars {
|
|
91
|
+
return mapValues(sidebars, (sidebar) =>
|
|
92
|
+
sidebar.map((item) => postProcessSidebarItem(item, params)),
|
|
93
|
+
);
|
|
94
|
+
}
|
|
@@ -7,41 +7,23 @@
|
|
|
7
7
|
|
|
8
8
|
import type {DocMetadataBase, VersionMetadata} from '../types';
|
|
9
9
|
import type {
|
|
10
|
-
Sidebars,
|
|
11
|
-
Sidebar,
|
|
12
|
-
SidebarItem,
|
|
13
10
|
NormalizedSidebarItem,
|
|
14
11
|
NormalizedSidebar,
|
|
15
12
|
NormalizedSidebars,
|
|
16
|
-
SidebarItemsGeneratorOption,
|
|
17
13
|
SidebarItemsGeneratorDoc,
|
|
18
14
|
SidebarItemsGeneratorVersion,
|
|
19
|
-
NormalizedSidebarItemCategory,
|
|
20
|
-
SidebarItemCategory,
|
|
21
15
|
SidebarItemAutogenerated,
|
|
16
|
+
ProcessedSidebarItem,
|
|
17
|
+
ProcessedSidebar,
|
|
18
|
+
ProcessedSidebars,
|
|
19
|
+
SidebarProcessorParams,
|
|
22
20
|
CategoryMetadataFile,
|
|
23
21
|
} from './types';
|
|
24
|
-
import {transformSidebarItems} from './utils';
|
|
25
22
|
import {DefaultSidebarItemsGenerator} from './generator';
|
|
23
|
+
import {validateSidebars} from './validation';
|
|
26
24
|
import {mapValues, memoize, pick} from 'lodash';
|
|
27
25
|
import combinePromises from 'combine-promises';
|
|
28
|
-
import {normalizeItem} from './normalization';
|
|
29
26
|
import {isCategoryIndex} from '../docs';
|
|
30
|
-
import type {Slugger} from '@docusaurus/utils';
|
|
31
|
-
import type {
|
|
32
|
-
NumberPrefixParser,
|
|
33
|
-
SidebarOptions,
|
|
34
|
-
} from '@docusaurus/plugin-content-docs';
|
|
35
|
-
|
|
36
|
-
export type SidebarProcessorParams = {
|
|
37
|
-
sidebarItemsGenerator: SidebarItemsGeneratorOption;
|
|
38
|
-
numberPrefixParser: NumberPrefixParser;
|
|
39
|
-
docs: DocMetadataBase[];
|
|
40
|
-
version: VersionMetadata;
|
|
41
|
-
categoryLabelSlugger: Slugger;
|
|
42
|
-
sidebarOptions: SidebarOptions;
|
|
43
|
-
categoriesMetadata: Record<string, CategoryMetadataFile>;
|
|
44
|
-
};
|
|
45
27
|
|
|
46
28
|
function toSidebarItemsGeneratorDoc(
|
|
47
29
|
doc: DocMetadataBase,
|
|
@@ -66,15 +48,15 @@ function toSidebarItemsGeneratorVersion(
|
|
|
66
48
|
// post-processing checks
|
|
67
49
|
async function processSidebar(
|
|
68
50
|
unprocessedSidebar: NormalizedSidebar,
|
|
51
|
+
categoriesMetadata: Record<string, CategoryMetadataFile>,
|
|
69
52
|
params: SidebarProcessorParams,
|
|
70
|
-
): Promise<
|
|
53
|
+
): Promise<ProcessedSidebar> {
|
|
71
54
|
const {
|
|
72
55
|
sidebarItemsGenerator,
|
|
73
56
|
numberPrefixParser,
|
|
74
57
|
docs,
|
|
75
58
|
version,
|
|
76
59
|
sidebarOptions,
|
|
77
|
-
categoriesMetadata,
|
|
78
60
|
} = params;
|
|
79
61
|
|
|
80
62
|
// Just a minor lazy transformation optimization
|
|
@@ -83,20 +65,9 @@ async function processSidebar(
|
|
|
83
65
|
version: toSidebarItemsGeneratorVersion(version),
|
|
84
66
|
}));
|
|
85
67
|
|
|
86
|
-
async function processCategoryItem(
|
|
87
|
-
item: NormalizedSidebarItemCategory,
|
|
88
|
-
): Promise<SidebarItemCategory> {
|
|
89
|
-
return {
|
|
90
|
-
...item,
|
|
91
|
-
items: (await Promise.all(item.items.map(processItem))).flat(),
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
68
|
async function processAutoGeneratedItem(
|
|
96
69
|
item: SidebarItemAutogenerated,
|
|
97
|
-
): Promise<
|
|
98
|
-
// TODO the returned type can't be trusted in practice (generator can be
|
|
99
|
-
// user-provided)
|
|
70
|
+
): Promise<ProcessedSidebarItem[]> {
|
|
100
71
|
const generatedItems = await sidebarItemsGenerator({
|
|
101
72
|
item,
|
|
102
73
|
numberPrefixParser,
|
|
@@ -106,50 +77,23 @@ async function processSidebar(
|
|
|
106
77
|
options: sidebarOptions,
|
|
107
78
|
categoriesMetadata,
|
|
108
79
|
});
|
|
109
|
-
// TODO validate generated items: user can generate bad items
|
|
110
|
-
|
|
111
|
-
const generatedItemsNormalized = generatedItems.flatMap((generatedItem) =>
|
|
112
|
-
normalizeItem(generatedItem, {...params, ...sidebarOptions}),
|
|
113
|
-
);
|
|
114
|
-
|
|
115
80
|
// Process again... weird but sidebar item generated might generate some
|
|
116
81
|
// auto-generated items?
|
|
117
|
-
|
|
82
|
+
// TODO repeatedly process & unwrap autogenerated items until there are no
|
|
83
|
+
// more autogenerated items, or when loop count (e.g. 10) is reached
|
|
84
|
+
return processItems(generatedItems);
|
|
118
85
|
}
|
|
119
86
|
|
|
120
87
|
async function processItem(
|
|
121
88
|
item: NormalizedSidebarItem,
|
|
122
|
-
): Promise<
|
|
89
|
+
): Promise<ProcessedSidebarItem[]> {
|
|
123
90
|
if (item.type === 'category') {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
switch (item.link.type) {
|
|
132
|
-
case 'doc':
|
|
133
|
-
return [
|
|
134
|
-
{
|
|
135
|
-
type: 'doc',
|
|
136
|
-
label: item.label,
|
|
137
|
-
id: item.link.id,
|
|
138
|
-
},
|
|
139
|
-
];
|
|
140
|
-
case 'generated-index':
|
|
141
|
-
return [
|
|
142
|
-
{
|
|
143
|
-
type: 'link',
|
|
144
|
-
label: item.label,
|
|
145
|
-
href: item.link.permalink,
|
|
146
|
-
},
|
|
147
|
-
];
|
|
148
|
-
default:
|
|
149
|
-
throw new Error('Unexpected sidebar category link type');
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return [await processCategoryItem(item)];
|
|
91
|
+
return [
|
|
92
|
+
{
|
|
93
|
+
...item,
|
|
94
|
+
items: (await Promise.all(item.items.map(processItem))).flat(),
|
|
95
|
+
},
|
|
96
|
+
];
|
|
153
97
|
}
|
|
154
98
|
if (item.type === 'autogenerated') {
|
|
155
99
|
return processAutoGeneratedItem(item);
|
|
@@ -159,32 +103,24 @@ async function processSidebar(
|
|
|
159
103
|
|
|
160
104
|
async function processItems(
|
|
161
105
|
items: NormalizedSidebarItem[],
|
|
162
|
-
): Promise<
|
|
106
|
+
): Promise<ProcessedSidebarItem[]> {
|
|
163
107
|
return (await Promise.all(items.map(processItem))).flat();
|
|
164
108
|
}
|
|
165
109
|
|
|
166
110
|
const processedSidebar = await processItems(unprocessedSidebar);
|
|
167
|
-
|
|
168
|
-
const fixSidebarItemInconsistencies = (item: SidebarItem): SidebarItem => {
|
|
169
|
-
// A non-collapsible category can't be collapsed!
|
|
170
|
-
if (item.type === 'category' && !item.collapsible && item.collapsed) {
|
|
171
|
-
return {
|
|
172
|
-
...item,
|
|
173
|
-
collapsed: false,
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
return item;
|
|
177
|
-
};
|
|
178
|
-
return transformSidebarItems(processedSidebar, fixSidebarItemInconsistencies);
|
|
111
|
+
return processedSidebar;
|
|
179
112
|
}
|
|
180
113
|
|
|
181
114
|
export async function processSidebars(
|
|
182
115
|
unprocessedSidebars: NormalizedSidebars,
|
|
116
|
+
categoriesMetadata: Record<string, CategoryMetadataFile>,
|
|
183
117
|
params: SidebarProcessorParams,
|
|
184
|
-
): Promise<
|
|
185
|
-
|
|
118
|
+
): Promise<ProcessedSidebars> {
|
|
119
|
+
const processedSidebars = await combinePromises(
|
|
186
120
|
mapValues(unprocessedSidebars, (unprocessedSidebar) =>
|
|
187
|
-
processSidebar(unprocessedSidebar, params),
|
|
121
|
+
processSidebar(unprocessedSidebar, categoriesMetadata, params),
|
|
188
122
|
),
|
|
189
123
|
);
|
|
124
|
+
validateSidebars(processedSidebars);
|
|
125
|
+
return processedSidebars;
|
|
190
126
|
}
|
package/src/sidebars/types.ts
CHANGED
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
SidebarOptions,
|
|
13
13
|
CategoryIndexMatcher,
|
|
14
14
|
} from '@docusaurus/plugin-content-docs';
|
|
15
|
+
import type {Slugger} from '@docusaurus/utils';
|
|
15
16
|
|
|
16
17
|
// Makes all properties visible when hovering over the type
|
|
17
18
|
type Expand<T extends Record<string, unknown>> = {[P in keyof T]: T[P]};
|
|
@@ -82,13 +83,13 @@ export type SidebarItemCategoryLink =
|
|
|
82
83
|
// The user-given configuration in sidebars.js, before normalization
|
|
83
84
|
export type SidebarItemCategoryConfig = Expand<
|
|
84
85
|
Optional<SidebarItemCategoryBase, 'collapsed' | 'collapsible'> & {
|
|
85
|
-
items: SidebarItemConfig[];
|
|
86
|
+
items: SidebarCategoriesShorthand | SidebarItemConfig[];
|
|
86
87
|
link?: SidebarItemCategoryLinkConfig;
|
|
87
88
|
}
|
|
88
89
|
>;
|
|
89
90
|
|
|
90
91
|
export type SidebarCategoriesShorthand = {
|
|
91
|
-
[sidebarCategory: string]: SidebarItemConfig[];
|
|
92
|
+
[sidebarCategory: string]: SidebarCategoriesShorthand | SidebarItemConfig[];
|
|
92
93
|
};
|
|
93
94
|
|
|
94
95
|
export type SidebarItemConfig =
|
|
@@ -107,9 +108,9 @@ export type SidebarsConfig = {
|
|
|
107
108
|
|
|
108
109
|
// Normalized but still has 'autogenerated', which will be handled in processing
|
|
109
110
|
export type NormalizedSidebarItemCategory = Expand<
|
|
110
|
-
SidebarItemCategoryBase & {
|
|
111
|
+
Optional<SidebarItemCategoryBase, 'collapsed' | 'collapsible'> & {
|
|
111
112
|
items: NormalizedSidebarItem[];
|
|
112
|
-
link?:
|
|
113
|
+
link?: SidebarItemCategoryLinkConfig;
|
|
113
114
|
}
|
|
114
115
|
>;
|
|
115
116
|
|
|
@@ -125,6 +126,22 @@ export type NormalizedSidebars = {
|
|
|
125
126
|
[sidebarId: string]: NormalizedSidebar;
|
|
126
127
|
};
|
|
127
128
|
|
|
129
|
+
export type ProcessedSidebarItemCategory = Expand<
|
|
130
|
+
Optional<SidebarItemCategoryBase, 'collapsed' | 'collapsible'> & {
|
|
131
|
+
items: ProcessedSidebarItem[];
|
|
132
|
+
link?: SidebarItemCategoryLinkConfig;
|
|
133
|
+
}
|
|
134
|
+
>;
|
|
135
|
+
export type ProcessedSidebarItem =
|
|
136
|
+
| SidebarItemDoc
|
|
137
|
+
| SidebarItemHtml
|
|
138
|
+
| SidebarItemLink
|
|
139
|
+
| ProcessedSidebarItemCategory;
|
|
140
|
+
export type ProcessedSidebar = ProcessedSidebarItem[];
|
|
141
|
+
export type ProcessedSidebars = {
|
|
142
|
+
[sidebarId: string]: ProcessedSidebar;
|
|
143
|
+
};
|
|
144
|
+
|
|
128
145
|
export type SidebarItemCategory = Expand<
|
|
129
146
|
SidebarItemCategoryBase & {
|
|
130
147
|
items: SidebarItem[];
|
|
@@ -230,9 +247,7 @@ export type SidebarItemsGeneratorArgs = {
|
|
|
230
247
|
};
|
|
231
248
|
export type SidebarItemsGenerator = (
|
|
232
249
|
generatorArgs: SidebarItemsGeneratorArgs,
|
|
233
|
-
) =>
|
|
234
|
-
Promise<SidebarItem[]>;
|
|
235
|
-
// Promise<SidebarItemConfig[]>;
|
|
250
|
+
) => Promise<NormalizedSidebar>;
|
|
236
251
|
|
|
237
252
|
// Also inject the default generator to conveniently wrap/enhance/sort the
|
|
238
253
|
// default sidebar gen logic
|
|
@@ -242,4 +257,13 @@ export type SidebarItemsGeneratorOptionArgs = {
|
|
|
242
257
|
} & SidebarItemsGeneratorArgs;
|
|
243
258
|
export type SidebarItemsGeneratorOption = (
|
|
244
259
|
generatorArgs: SidebarItemsGeneratorOptionArgs,
|
|
245
|
-
) => Promise<
|
|
260
|
+
) => Promise<NormalizedSidebarItem[]>;
|
|
261
|
+
|
|
262
|
+
export type SidebarProcessorParams = {
|
|
263
|
+
sidebarItemsGenerator: SidebarItemsGeneratorOption;
|
|
264
|
+
numberPrefixParser: NumberPrefixParser;
|
|
265
|
+
docs: DocMetadataBase[];
|
|
266
|
+
version: VersionMetadata;
|
|
267
|
+
categoryLabelSlugger: Slugger;
|
|
268
|
+
sidebarOptions: SidebarOptions;
|
|
269
|
+
};
|
package/src/sidebars/utils.ts
CHANGED
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
import {Joi, URISchema} from '@docusaurus/utils-validation';
|
|
9
9
|
import type {
|
|
10
10
|
SidebarItemConfig,
|
|
11
|
-
SidebarCategoriesShorthand,
|
|
12
11
|
SidebarItemBase,
|
|
13
12
|
SidebarItemAutogenerated,
|
|
14
13
|
SidebarItemDoc,
|
|
@@ -16,12 +15,13 @@ import type {
|
|
|
16
15
|
SidebarItemLink,
|
|
17
16
|
SidebarItemCategoryConfig,
|
|
18
17
|
SidebarItemCategoryLink,
|
|
19
|
-
SidebarsConfig,
|
|
20
18
|
SidebarItemCategoryLinkDoc,
|
|
21
19
|
SidebarItemCategoryLinkGeneratedIndex,
|
|
20
|
+
NormalizedSidebars,
|
|
21
|
+
NormalizedSidebarItem,
|
|
22
|
+
NormalizedSidebarItemCategory,
|
|
22
23
|
CategoryMetadataFile,
|
|
23
24
|
} from './types';
|
|
24
|
-
import {isCategoriesShorthand} from './utils';
|
|
25
25
|
|
|
26
26
|
// NOTE: we don't add any default values during validation on purpose!
|
|
27
27
|
// Config types are exposed to users for typechecking and we use the same type
|
|
@@ -52,7 +52,7 @@ const sidebarItemDocSchema = sidebarItemBaseSchema.append<SidebarItemDoc>({
|
|
|
52
52
|
const sidebarItemHtmlSchema = sidebarItemBaseSchema.append<SidebarItemHtml>({
|
|
53
53
|
type: 'html',
|
|
54
54
|
value: Joi.string().required(),
|
|
55
|
-
defaultStyle: Joi.boolean()
|
|
55
|
+
defaultStyle: Joi.boolean(),
|
|
56
56
|
});
|
|
57
57
|
|
|
58
58
|
const sidebarItemLinkSchema = sidebarItemBaseSchema.append<SidebarItemLink>({
|
|
@@ -88,14 +88,13 @@ const sidebarItemCategoryLinkSchema = Joi.object<SidebarItemCategoryLink>()
|
|
|
88
88
|
}),
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
|
-
is: Joi.
|
|
91
|
+
is: Joi.required(),
|
|
92
92
|
then: Joi.forbidden().messages({
|
|
93
93
|
'any.unknown': 'Unknown sidebar category link type "{.type}".',
|
|
94
94
|
}),
|
|
95
95
|
},
|
|
96
96
|
],
|
|
97
|
-
})
|
|
98
|
-
.id('sidebarCategoryLinkSchema');
|
|
97
|
+
});
|
|
99
98
|
|
|
100
99
|
const sidebarItemCategorySchema =
|
|
101
100
|
sidebarItemBaseSchema.append<SidebarItemCategoryConfig>({
|
|
@@ -103,10 +102,11 @@ const sidebarItemCategorySchema =
|
|
|
103
102
|
label: Joi.string()
|
|
104
103
|
.required()
|
|
105
104
|
.messages({'any.unknown': '"label" must be a string'}),
|
|
106
|
-
// TODO: Joi doesn't allow mutual recursion. See https://github.com/sideway/joi/issues/2611
|
|
107
105
|
items: Joi.array()
|
|
108
106
|
.required()
|
|
109
|
-
.messages({'any.unknown': '"items" must be an array'}),
|
|
107
|
+
.messages({'any.unknown': '"items" must be an array'}),
|
|
108
|
+
// TODO: Joi doesn't allow mutual recursion. See https://github.com/sideway/joi/issues/2611
|
|
109
|
+
// .items(Joi.link('#sidebarItemSchema')),
|
|
110
110
|
link: sidebarItemCategoryLinkSchema,
|
|
111
111
|
collapsed: Joi.boolean().messages({
|
|
112
112
|
'any.unknown': '"collapsed" must be a boolean',
|
|
@@ -116,56 +116,44 @@ const sidebarItemCategorySchema =
|
|
|
116
116
|
}),
|
|
117
117
|
});
|
|
118
118
|
|
|
119
|
-
const sidebarItemSchema
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
.id('sidebarItemSchema');
|
|
119
|
+
const sidebarItemSchema = Joi.object<SidebarItemConfig>().when('.type', {
|
|
120
|
+
switch: [
|
|
121
|
+
{is: 'link', then: sidebarItemLinkSchema},
|
|
122
|
+
{
|
|
123
|
+
is: Joi.string().valid('doc', 'ref').required(),
|
|
124
|
+
then: sidebarItemDocSchema,
|
|
125
|
+
},
|
|
126
|
+
{is: 'html', then: sidebarItemHtmlSchema},
|
|
127
|
+
{is: 'autogenerated', then: sidebarItemAutogeneratedSchema},
|
|
128
|
+
{is: 'category', then: sidebarItemCategorySchema},
|
|
129
|
+
{
|
|
130
|
+
is: Joi.any().required(),
|
|
131
|
+
then: Joi.forbidden().messages({
|
|
132
|
+
'any.unknown': 'Unknown sidebar item type "{.type}".',
|
|
133
|
+
}),
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
});
|
|
137
|
+
// .id('sidebarItemSchema');
|
|
139
138
|
|
|
140
|
-
function validateSidebarItem(
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
139
|
+
function validateSidebarItem(
|
|
140
|
+
item: unknown,
|
|
141
|
+
): asserts item is NormalizedSidebarItem {
|
|
144
142
|
// TODO: remove once with proper Joi support
|
|
145
143
|
// Because we can't use Joi to validate nested items (see above), we do it
|
|
146
144
|
// manually
|
|
147
|
-
|
|
148
|
-
Object.values(item as SidebarCategoriesShorthand).forEach((category) =>
|
|
149
|
-
category.forEach(validateSidebarItem),
|
|
150
|
-
);
|
|
151
|
-
} else {
|
|
152
|
-
Joi.assert(item, sidebarItemSchema);
|
|
145
|
+
Joi.assert(item, sidebarItemSchema);
|
|
153
146
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
147
|
+
if ((item as NormalizedSidebarItemCategory).type === 'category') {
|
|
148
|
+
(item as NormalizedSidebarItemCategory).items.forEach(validateSidebarItem);
|
|
157
149
|
}
|
|
158
150
|
}
|
|
159
151
|
|
|
160
152
|
export function validateSidebars(
|
|
161
|
-
sidebars: unknown
|
|
162
|
-
): asserts sidebars is
|
|
163
|
-
Object.values(sidebars as
|
|
164
|
-
|
|
165
|
-
sidebar.forEach(validateSidebarItem);
|
|
166
|
-
} else {
|
|
167
|
-
validateSidebarItem(sidebar);
|
|
168
|
-
}
|
|
153
|
+
sidebars: Record<string, unknown>,
|
|
154
|
+
): asserts sidebars is NormalizedSidebars {
|
|
155
|
+
Object.values(sidebars as NormalizedSidebars).forEach((sidebar) => {
|
|
156
|
+
sidebar.forEach(validateSidebarItem);
|
|
169
157
|
});
|
|
170
158
|
}
|
|
171
159
|
|
package/src/types.ts
CHANGED
|
@@ -8,15 +8,12 @@
|
|
|
8
8
|
/// <reference types="@docusaurus/module-type-aliases" />
|
|
9
9
|
|
|
10
10
|
import type {Sidebars} from './sidebars/types';
|
|
11
|
-
import type {Tag, FrontMatterTag
|
|
11
|
+
import type {Tag, FrontMatterTag} 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 {
|
|
17
|
-
VersionBanner,
|
|
18
|
-
SidebarOptions,
|
|
19
|
-
} from '@docusaurus/plugin-content-docs';
|
|
16
|
+
import type {VersionBanner} from '@docusaurus/plugin-content-docs';
|
|
20
17
|
|
|
21
18
|
export type DocFile = {
|
|
22
19
|
contentPath: string; // /!\ may be localized
|
|
@@ -41,11 +38,6 @@ export type VersionMetadata = ContentPaths & {
|
|
|
41
38
|
routePriority: number | undefined; // -1 for the latest docs
|
|
42
39
|
};
|
|
43
40
|
|
|
44
|
-
export type NormalizeSidebarsParams = SidebarOptions & {
|
|
45
|
-
version: VersionMetadata;
|
|
46
|
-
categoryLabelSlugger: Slugger;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
41
|
export type LastUpdateData = {
|
|
50
42
|
lastUpdatedAt?: number;
|
|
51
43
|
formattedLastUpdatedAt?: string;
|
|
@@ -1,19 +0,0 @@
|
|
|
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
|
-
import type { GlobalPluginData, GlobalVersion, ActivePlugin, ActiveDocContext, DocVersionSuggestions, GetActivePluginOptions } from '@docusaurus/plugin-content-docs/client';
|
|
8
|
-
export declare const useAllDocsData: () => Record<string, GlobalPluginData>;
|
|
9
|
-
export declare const useDocsData: (pluginId: string | undefined) => GlobalPluginData;
|
|
10
|
-
export declare const useActivePlugin: (options?: GetActivePluginOptions) => ActivePlugin | undefined;
|
|
11
|
-
export declare const useActivePluginAndVersion: (options?: GetActivePluginOptions) => {
|
|
12
|
-
activePlugin: ActivePlugin;
|
|
13
|
-
activeVersion: GlobalVersion | undefined;
|
|
14
|
-
} | undefined;
|
|
15
|
-
export declare const useVersions: (pluginId: string | undefined) => GlobalVersion[];
|
|
16
|
-
export declare const useLatestVersion: (pluginId: string | undefined) => GlobalVersion;
|
|
17
|
-
export declare const useActiveVersion: (pluginId: string | undefined) => GlobalVersion | undefined;
|
|
18
|
-
export declare const useActiveDocContext: (pluginId: string | undefined) => ActiveDocContext;
|
|
19
|
-
export declare const useDocVersionSuggestions: (pluginId: string | undefined) => DocVersionSuggestions;
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
4
|
-
*
|
|
5
|
-
* This source code is licensed under the MIT license found in the
|
|
6
|
-
* LICENSE file in the root directory of this source tree.
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.useDocVersionSuggestions = exports.useActiveDocContext = exports.useActiveVersion = exports.useLatestVersion = exports.useVersions = exports.useActivePluginAndVersion = exports.useActivePlugin = exports.useDocsData = exports.useAllDocsData = void 0;
|
|
10
|
-
const tslib_1 = require("tslib");
|
|
11
|
-
const router_1 = require("@docusaurus/router");
|
|
12
|
-
const useGlobalData_1 = (0, tslib_1.__importStar)(require("@docusaurus/useGlobalData"));
|
|
13
|
-
const docsClientUtils_1 = require("./docsClientUtils");
|
|
14
|
-
// Important to use a constant object to avoid React useEffect executions etc.
|
|
15
|
-
// see https://github.com/facebook/docusaurus/issues/5089
|
|
16
|
-
const StableEmptyObject = {};
|
|
17
|
-
// Not using useAllPluginInstancesData() because in blog-only mode, docs hooks
|
|
18
|
-
// are still used by the theme. We need a fail-safe fallback when the docs
|
|
19
|
-
// plugin is not in use
|
|
20
|
-
const useAllDocsData = () => { var _a;
|
|
21
|
-
// useAllPluginInstancesData('docusaurus-plugin-content-docs');
|
|
22
|
-
return (_a = (0, useGlobalData_1.default)()['docusaurus-plugin-content-docs']) !== null && _a !== void 0 ? _a : StableEmptyObject; };
|
|
23
|
-
exports.useAllDocsData = useAllDocsData;
|
|
24
|
-
const useDocsData = (pluginId) => (0, useGlobalData_1.usePluginData)('docusaurus-plugin-content-docs', pluginId);
|
|
25
|
-
exports.useDocsData = useDocsData;
|
|
26
|
-
// TODO this feature should be provided by docusaurus core
|
|
27
|
-
const useActivePlugin = (options = {}) => {
|
|
28
|
-
const data = (0, exports.useAllDocsData)();
|
|
29
|
-
const { pathname } = (0, router_1.useLocation)();
|
|
30
|
-
return (0, docsClientUtils_1.getActivePlugin)(data, pathname, options);
|
|
31
|
-
};
|
|
32
|
-
exports.useActivePlugin = useActivePlugin;
|
|
33
|
-
const useActivePluginAndVersion = (options = {}) => {
|
|
34
|
-
const activePlugin = (0, exports.useActivePlugin)(options);
|
|
35
|
-
const { pathname } = (0, router_1.useLocation)();
|
|
36
|
-
if (activePlugin) {
|
|
37
|
-
const activeVersion = (0, docsClientUtils_1.getActiveVersion)(activePlugin.pluginData, pathname);
|
|
38
|
-
return {
|
|
39
|
-
activePlugin,
|
|
40
|
-
activeVersion,
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
return undefined;
|
|
44
|
-
};
|
|
45
|
-
exports.useActivePluginAndVersion = useActivePluginAndVersion;
|
|
46
|
-
// versions are returned ordered (most recent first)
|
|
47
|
-
const useVersions = (pluginId) => {
|
|
48
|
-
const data = (0, exports.useDocsData)(pluginId);
|
|
49
|
-
return data.versions;
|
|
50
|
-
};
|
|
51
|
-
exports.useVersions = useVersions;
|
|
52
|
-
const useLatestVersion = (pluginId) => {
|
|
53
|
-
const data = (0, exports.useDocsData)(pluginId);
|
|
54
|
-
return (0, docsClientUtils_1.getLatestVersion)(data);
|
|
55
|
-
};
|
|
56
|
-
exports.useLatestVersion = useLatestVersion;
|
|
57
|
-
// Note: return undefined on doc-unrelated pages,
|
|
58
|
-
// because there's no version currently considered as active
|
|
59
|
-
const useActiveVersion = (pluginId) => {
|
|
60
|
-
const data = (0, exports.useDocsData)(pluginId);
|
|
61
|
-
const { pathname } = (0, router_1.useLocation)();
|
|
62
|
-
return (0, docsClientUtils_1.getActiveVersion)(data, pathname);
|
|
63
|
-
};
|
|
64
|
-
exports.useActiveVersion = useActiveVersion;
|
|
65
|
-
const useActiveDocContext = (pluginId) => {
|
|
66
|
-
const data = (0, exports.useDocsData)(pluginId);
|
|
67
|
-
const { pathname } = (0, router_1.useLocation)();
|
|
68
|
-
return (0, docsClientUtils_1.getActiveDocContext)(data, pathname);
|
|
69
|
-
};
|
|
70
|
-
exports.useActiveDocContext = useActiveDocContext;
|
|
71
|
-
// Useful to say "hey, you are not on the latest docs version, please switch"
|
|
72
|
-
const useDocVersionSuggestions = (pluginId) => {
|
|
73
|
-
const data = (0, exports.useDocsData)(pluginId);
|
|
74
|
-
const { pathname } = (0, router_1.useLocation)();
|
|
75
|
-
return (0, docsClientUtils_1.getDocVersionSuggestions)(data, pathname);
|
|
76
|
-
};
|
|
77
|
-
exports.useDocVersionSuggestions = useDocVersionSuggestions;
|