@docusaurus/plugin-content-docs 2.0.0-beta.8e9b829d9 → 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 +1 -1
- package/lib/cli.js +18 -23
- package/lib/client/docsClientUtils.d.ts +0 -3
- package/lib/client/docsClientUtils.js +10 -7
- package/lib/docFrontMatter.js +6 -2
- package/lib/docs.d.ts +3 -1
- package/lib/docs.js +76 -25
- package/lib/index.js +70 -77
- package/lib/lastUpdate.js +4 -4
- 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.js +12 -4
- package/lib/props.d.ts +7 -2
- package/lib/props.js +26 -3
- package/lib/{sidebarItemsGenerator.d.ts → sidebars/generator.d.ts} +2 -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 +21 -21
- package/lib/translations.d.ts +1 -1
- package/lib/translations.js +13 -13
- package/lib/types.d.ts +29 -61
- package/lib/versions.d.ts +1 -1
- package/lib/versions.js +40 -20
- package/package.json +15 -14
- 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__/__snapshots__/cli.test.ts.snap +28 -0
- package/src/__tests__/__snapshots__/docs.test.ts.snap +140 -0
- package/src/__tests__/__snapshots__/index.test.ts.snap +426 -25
- package/src/__tests__/docFrontMatter.test.ts +160 -45
- package/src/__tests__/docs.test.ts +167 -21
- package/src/__tests__/index.test.ts +53 -27
- package/src/__tests__/options.test.ts +4 -1
- package/src/__tests__/props.test.ts +62 -0
- package/src/__tests__/versions.test.ts +68 -63
- package/src/cli.ts +23 -30
- package/src/client/docsClientUtils.ts +1 -12
- package/src/docFrontMatter.ts +7 -2
- package/src/docs.ts +88 -9
- package/src/index.ts +77 -91
- package/src/markdown/index.ts +8 -12
- package/src/numberPrefix.ts +4 -2
- package/src/options.ts +13 -1
- package/src/plugin-content-docs.d.ts +107 -32
- package/src/props.ts +41 -5
- 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} +6 -6
- package/src/{__tests__/sidebarItemsGenerator.test.ts → sidebars/__tests__/generator.test.ts} +2 -2
- 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/translations.ts +26 -36
- package/src/types.ts +35 -101
- package/src/versions.ts +51 -21
- package/lib/sidebarItemsGenerator.js +0 -215
- package/lib/sidebars.d.ts +0 -45
- package/lib/sidebars.js +0 -354
- package/src/__tests__/sidebars.test.ts +0 -746
- package/src/sidebarItemsGenerator.ts +0 -315
- package/src/sidebars.ts +0 -589
package/src/sidebars.ts
DELETED
|
@@ -1,589 +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
|
-
|
|
8
|
-
import fs from 'fs-extra';
|
|
9
|
-
import importFresh from 'import-fresh';
|
|
10
|
-
import {
|
|
11
|
-
Sidebars,
|
|
12
|
-
SidebarItem,
|
|
13
|
-
SidebarItemBase,
|
|
14
|
-
SidebarItemLink,
|
|
15
|
-
SidebarItemDoc,
|
|
16
|
-
Sidebar,
|
|
17
|
-
SidebarItemCategory,
|
|
18
|
-
SidebarItemType,
|
|
19
|
-
UnprocessedSidebarItem,
|
|
20
|
-
UnprocessedSidebars,
|
|
21
|
-
UnprocessedSidebar,
|
|
22
|
-
DocMetadataBase,
|
|
23
|
-
VersionMetadata,
|
|
24
|
-
SidebarItemsGeneratorDoc,
|
|
25
|
-
SidebarItemsGeneratorVersion,
|
|
26
|
-
NumberPrefixParser,
|
|
27
|
-
SidebarItemsGeneratorOption,
|
|
28
|
-
SidebarOptions,
|
|
29
|
-
PluginOptions,
|
|
30
|
-
} from './types';
|
|
31
|
-
import {mapValues, flatten, flatMap, difference, pick, memoize} from 'lodash';
|
|
32
|
-
import {getElementsAround, toMessageRelativeFilePath} from '@docusaurus/utils';
|
|
33
|
-
import combinePromises from 'combine-promises';
|
|
34
|
-
import {DefaultSidebarItemsGenerator} from './sidebarItemsGenerator';
|
|
35
|
-
import path from 'path';
|
|
36
|
-
|
|
37
|
-
type SidebarItemCategoryJSON = SidebarItemBase & {
|
|
38
|
-
type: 'category';
|
|
39
|
-
label: string;
|
|
40
|
-
items: SidebarItemJSON[];
|
|
41
|
-
collapsed?: boolean;
|
|
42
|
-
collapsible?: boolean;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
type SidebarItemAutogeneratedJSON = SidebarItemBase & {
|
|
46
|
-
type: 'autogenerated';
|
|
47
|
-
dirName: string;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
type SidebarItemJSON =
|
|
51
|
-
| string
|
|
52
|
-
| SidebarCategoryShorthandJSON
|
|
53
|
-
| SidebarItemDoc
|
|
54
|
-
| SidebarItemLink
|
|
55
|
-
| SidebarItemCategoryJSON
|
|
56
|
-
| SidebarItemAutogeneratedJSON
|
|
57
|
-
| {
|
|
58
|
-
type: string;
|
|
59
|
-
[key: string]: unknown;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
type SidebarCategoryShorthandJSON = {
|
|
63
|
-
[sidebarCategory: string]: SidebarItemJSON[];
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
type SidebarJSON = SidebarCategoryShorthandJSON | SidebarItemJSON[];
|
|
67
|
-
|
|
68
|
-
// Sidebar given by user that is not normalized yet. e.g: sidebars.json
|
|
69
|
-
type SidebarsJSON = {
|
|
70
|
-
[sidebarId: string]: SidebarJSON;
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
function isCategoryShorthand(
|
|
74
|
-
item: SidebarItemJSON,
|
|
75
|
-
): item is SidebarCategoryShorthandJSON {
|
|
76
|
-
return typeof item !== 'string' && !item.type;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Convert {category1: [item1,item2]} shorthand syntax to long-form syntax
|
|
81
|
-
*/
|
|
82
|
-
function normalizeCategoryShorthand(
|
|
83
|
-
sidebar: SidebarCategoryShorthandJSON,
|
|
84
|
-
options: SidebarOptions,
|
|
85
|
-
): SidebarItemCategoryJSON[] {
|
|
86
|
-
return Object.entries(sidebar).map(([label, items]) => ({
|
|
87
|
-
type: 'category',
|
|
88
|
-
collapsed: options.sidebarCollapsed,
|
|
89
|
-
collapsible: options.sidebarCollapsible,
|
|
90
|
-
label,
|
|
91
|
-
items,
|
|
92
|
-
}));
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Check that item contains only allowed keys.
|
|
97
|
-
*/
|
|
98
|
-
function assertItem<K extends string>(
|
|
99
|
-
item: Record<string, unknown>,
|
|
100
|
-
keys: K[],
|
|
101
|
-
): asserts item is Record<K, unknown> {
|
|
102
|
-
const unknownKeys = Object.keys(item).filter(
|
|
103
|
-
// @ts-expect-error: key is always string
|
|
104
|
-
(key) => !keys.includes(key as string) && key !== 'type',
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
if (unknownKeys.length) {
|
|
108
|
-
throw new Error(
|
|
109
|
-
`Unknown sidebar item keys: ${unknownKeys}. Item: ${JSON.stringify(
|
|
110
|
-
item,
|
|
111
|
-
)}`,
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function assertIsCategory(
|
|
117
|
-
item: Record<string, unknown>,
|
|
118
|
-
): asserts item is SidebarItemCategoryJSON {
|
|
119
|
-
assertItem(item, [
|
|
120
|
-
'items',
|
|
121
|
-
'label',
|
|
122
|
-
'collapsed',
|
|
123
|
-
'collapsible',
|
|
124
|
-
'customProps',
|
|
125
|
-
]);
|
|
126
|
-
if (typeof item.label !== 'string') {
|
|
127
|
-
throw new Error(
|
|
128
|
-
`Error loading ${JSON.stringify(item)}: "label" must be a string.`,
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
if (!Array.isArray(item.items)) {
|
|
132
|
-
throw new Error(
|
|
133
|
-
`Error loading ${JSON.stringify(item)}: "items" must be an array.`,
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
// "collapsed" is an optional property
|
|
137
|
-
if (
|
|
138
|
-
typeof item.collapsed !== 'undefined' &&
|
|
139
|
-
typeof item.collapsed !== 'boolean'
|
|
140
|
-
) {
|
|
141
|
-
throw new Error(
|
|
142
|
-
`Error loading ${JSON.stringify(item)}: "collapsed" must be a boolean.`,
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
if (
|
|
146
|
-
typeof item.collapsible !== 'undefined' &&
|
|
147
|
-
typeof item.collapsible !== 'boolean'
|
|
148
|
-
) {
|
|
149
|
-
throw new Error(
|
|
150
|
-
`Error loading ${JSON.stringify(item)}: "collapsible" must be a boolean.`,
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
function assertIsAutogenerated(
|
|
156
|
-
item: Record<string, unknown>,
|
|
157
|
-
): asserts item is SidebarItemAutogeneratedJSON {
|
|
158
|
-
assertItem(item, ['dirName', 'customProps']);
|
|
159
|
-
if (typeof item.dirName !== 'string') {
|
|
160
|
-
throw new Error(
|
|
161
|
-
`Error loading ${JSON.stringify(item)}: "dirName" must be a string.`,
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
if (item.dirName.startsWith('/') || item.dirName.endsWith('/')) {
|
|
165
|
-
throw new Error(
|
|
166
|
-
`Error loading ${JSON.stringify(
|
|
167
|
-
item,
|
|
168
|
-
)}: "dirName" must be a dir path relative to the docs folder root, and should not start or end with slash`,
|
|
169
|
-
);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
function assertIsDoc(
|
|
174
|
-
item: Record<string, unknown>,
|
|
175
|
-
): asserts item is SidebarItemDoc {
|
|
176
|
-
assertItem(item, ['id', 'label', 'customProps']);
|
|
177
|
-
if (typeof item.id !== 'string') {
|
|
178
|
-
throw new Error(
|
|
179
|
-
`Error loading ${JSON.stringify(item)}: "id" must be a string.`,
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
if (item.label && typeof item.label !== 'string') {
|
|
184
|
-
throw new Error(
|
|
185
|
-
`Error loading ${JSON.stringify(item)}: "label" must be a string.`,
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function assertIsLink(
|
|
191
|
-
item: Record<string, unknown>,
|
|
192
|
-
): asserts item is SidebarItemLink {
|
|
193
|
-
assertItem(item, ['href', 'label', 'customProps']);
|
|
194
|
-
if (typeof item.href !== 'string') {
|
|
195
|
-
throw new Error(
|
|
196
|
-
`Error loading ${JSON.stringify(item)}: "href" must be a string.`,
|
|
197
|
-
);
|
|
198
|
-
}
|
|
199
|
-
if (typeof item.label !== 'string') {
|
|
200
|
-
throw new Error(
|
|
201
|
-
`Error loading ${JSON.stringify(item)}: "label" must be a string.`,
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Normalizes recursively item and all its children. Ensures that at the end
|
|
208
|
-
* each item will be an object with the corresponding type.
|
|
209
|
-
*/
|
|
210
|
-
function normalizeItem(
|
|
211
|
-
item: SidebarItemJSON,
|
|
212
|
-
options: SidebarOptions,
|
|
213
|
-
): UnprocessedSidebarItem[] {
|
|
214
|
-
if (typeof item === 'string') {
|
|
215
|
-
return [
|
|
216
|
-
{
|
|
217
|
-
type: 'doc',
|
|
218
|
-
id: item,
|
|
219
|
-
},
|
|
220
|
-
];
|
|
221
|
-
}
|
|
222
|
-
if (isCategoryShorthand(item)) {
|
|
223
|
-
return flatMap(normalizeCategoryShorthand(item, options), (subitem) =>
|
|
224
|
-
normalizeItem(subitem, options),
|
|
225
|
-
);
|
|
226
|
-
}
|
|
227
|
-
switch (item.type) {
|
|
228
|
-
case 'category':
|
|
229
|
-
assertIsCategory(item);
|
|
230
|
-
return [
|
|
231
|
-
{
|
|
232
|
-
...item,
|
|
233
|
-
items: flatMap(item.items, (subItem) =>
|
|
234
|
-
normalizeItem(subItem, options),
|
|
235
|
-
),
|
|
236
|
-
collapsible: item.collapsible ?? options.sidebarCollapsible,
|
|
237
|
-
collapsed: item.collapsed ?? options.sidebarCollapsed,
|
|
238
|
-
},
|
|
239
|
-
];
|
|
240
|
-
case 'autogenerated':
|
|
241
|
-
assertIsAutogenerated(item);
|
|
242
|
-
return [item];
|
|
243
|
-
case 'link':
|
|
244
|
-
assertIsLink(item);
|
|
245
|
-
return [item];
|
|
246
|
-
case 'ref':
|
|
247
|
-
case 'doc':
|
|
248
|
-
assertIsDoc(item);
|
|
249
|
-
return [item];
|
|
250
|
-
default: {
|
|
251
|
-
const extraMigrationError =
|
|
252
|
-
item.type === 'subcategory'
|
|
253
|
-
? 'Docusaurus v2: "subcategory" has been renamed as "category".'
|
|
254
|
-
: '';
|
|
255
|
-
throw new Error(
|
|
256
|
-
`Unknown sidebar item type "${
|
|
257
|
-
item.type
|
|
258
|
-
}". Sidebar item is ${JSON.stringify(item)}.\n${extraMigrationError}`,
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
function normalizeSidebar(
|
|
265
|
-
sidebar: SidebarJSON,
|
|
266
|
-
options: SidebarOptions,
|
|
267
|
-
): UnprocessedSidebar {
|
|
268
|
-
const normalizedSidebar: SidebarItemJSON[] = Array.isArray(sidebar)
|
|
269
|
-
? sidebar
|
|
270
|
-
: normalizeCategoryShorthand(sidebar, options);
|
|
271
|
-
|
|
272
|
-
return flatMap(normalizedSidebar, (subitem) =>
|
|
273
|
-
normalizeItem(subitem, options),
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
function normalizeSidebars(
|
|
278
|
-
sidebars: SidebarsJSON,
|
|
279
|
-
options: SidebarOptions,
|
|
280
|
-
): UnprocessedSidebars {
|
|
281
|
-
return mapValues(sidebars, (subitem) => normalizeSidebar(subitem, options));
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
export const DefaultSidebars: UnprocessedSidebars = {
|
|
285
|
-
defaultSidebar: [
|
|
286
|
-
{
|
|
287
|
-
type: 'autogenerated',
|
|
288
|
-
dirName: '.',
|
|
289
|
-
},
|
|
290
|
-
],
|
|
291
|
-
};
|
|
292
|
-
|
|
293
|
-
export const DisabledSidebars: UnprocessedSidebars = {};
|
|
294
|
-
|
|
295
|
-
// If a path is provided, make it absolute
|
|
296
|
-
// use this before loadSidebars()
|
|
297
|
-
export function resolveSidebarPathOption(
|
|
298
|
-
siteDir: string,
|
|
299
|
-
sidebarPathOption: PluginOptions['sidebarPath'],
|
|
300
|
-
): PluginOptions['sidebarPath'] {
|
|
301
|
-
return sidebarPathOption
|
|
302
|
-
? path.resolve(siteDir, sidebarPathOption)
|
|
303
|
-
: sidebarPathOption;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
// TODO refactor: make async
|
|
307
|
-
// Note: sidebarFilePath must be absolute, use resolveSidebarPathOption
|
|
308
|
-
export function loadSidebars(
|
|
309
|
-
sidebarFilePath: string | false | undefined,
|
|
310
|
-
options: SidebarOptions,
|
|
311
|
-
): UnprocessedSidebars {
|
|
312
|
-
// false => no sidebars
|
|
313
|
-
if (sidebarFilePath === false) {
|
|
314
|
-
return DisabledSidebars;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// undefined => defaults to autogenerated sidebars
|
|
318
|
-
if (typeof sidebarFilePath === 'undefined') {
|
|
319
|
-
return DefaultSidebars;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// unexisting sidebars file: no sidebars
|
|
323
|
-
// Note: this edge case can happen on versioned docs, not current version
|
|
324
|
-
// We avoid creating empty versioned sidebars file with the CLI
|
|
325
|
-
if (!fs.existsSync(sidebarFilePath)) {
|
|
326
|
-
return DisabledSidebars;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// We don't want sidebars to be cached because of hot reloading.
|
|
330
|
-
const sidebarJson = importFresh(sidebarFilePath) as SidebarsJSON;
|
|
331
|
-
|
|
332
|
-
return normalizeSidebars(sidebarJson, options);
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
export function toSidebarItemsGeneratorDoc(
|
|
336
|
-
doc: DocMetadataBase,
|
|
337
|
-
): SidebarItemsGeneratorDoc {
|
|
338
|
-
return pick(doc, [
|
|
339
|
-
'id',
|
|
340
|
-
'frontMatter',
|
|
341
|
-
'source',
|
|
342
|
-
'sourceDirName',
|
|
343
|
-
'sidebarPosition',
|
|
344
|
-
]);
|
|
345
|
-
}
|
|
346
|
-
export function toSidebarItemsGeneratorVersion(
|
|
347
|
-
version: VersionMetadata,
|
|
348
|
-
): SidebarItemsGeneratorVersion {
|
|
349
|
-
return pick(version, ['versionName', 'contentPath']);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
export function fixSidebarItemInconsistencies(item: SidebarItem): SidebarItem {
|
|
353
|
-
function fixCategoryInconsistencies(
|
|
354
|
-
category: SidebarItemCategory,
|
|
355
|
-
): SidebarItemCategory {
|
|
356
|
-
// A non-collapsible category can't be collapsed!
|
|
357
|
-
if (!category.collapsible && category.collapsed) {
|
|
358
|
-
return {
|
|
359
|
-
...category,
|
|
360
|
-
collapsed: false,
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
return category;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
if (item.type === 'category') {
|
|
367
|
-
return {
|
|
368
|
-
...fixCategoryInconsistencies(item),
|
|
369
|
-
items: item.items.map(fixSidebarItemInconsistencies),
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
return item;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
// Handle the generation of autogenerated sidebar items and other post-processing checks
|
|
376
|
-
export async function processSidebar({
|
|
377
|
-
sidebarItemsGenerator,
|
|
378
|
-
numberPrefixParser,
|
|
379
|
-
unprocessedSidebar,
|
|
380
|
-
docs,
|
|
381
|
-
version,
|
|
382
|
-
options,
|
|
383
|
-
}: {
|
|
384
|
-
sidebarItemsGenerator: SidebarItemsGeneratorOption;
|
|
385
|
-
numberPrefixParser: NumberPrefixParser;
|
|
386
|
-
unprocessedSidebar: UnprocessedSidebar;
|
|
387
|
-
docs: DocMetadataBase[];
|
|
388
|
-
version: VersionMetadata;
|
|
389
|
-
options: SidebarOptions;
|
|
390
|
-
}): Promise<Sidebar> {
|
|
391
|
-
// Just a minor lazy transformation optimization
|
|
392
|
-
const getSidebarItemsGeneratorDocsAndVersion = memoize(() => ({
|
|
393
|
-
docs: docs.map(toSidebarItemsGeneratorDoc),
|
|
394
|
-
version: toSidebarItemsGeneratorVersion(version),
|
|
395
|
-
}));
|
|
396
|
-
|
|
397
|
-
async function handleAutoGeneratedItems(
|
|
398
|
-
item: UnprocessedSidebarItem,
|
|
399
|
-
): Promise<SidebarItem[]> {
|
|
400
|
-
if (item.type === 'category') {
|
|
401
|
-
return [
|
|
402
|
-
{
|
|
403
|
-
...item,
|
|
404
|
-
items: (
|
|
405
|
-
await Promise.all(item.items.map(handleAutoGeneratedItems))
|
|
406
|
-
).flat(),
|
|
407
|
-
},
|
|
408
|
-
];
|
|
409
|
-
}
|
|
410
|
-
if (item.type === 'autogenerated') {
|
|
411
|
-
return sidebarItemsGenerator({
|
|
412
|
-
item,
|
|
413
|
-
numberPrefixParser,
|
|
414
|
-
defaultSidebarItemsGenerator: DefaultSidebarItemsGenerator,
|
|
415
|
-
...getSidebarItemsGeneratorDocsAndVersion(),
|
|
416
|
-
options,
|
|
417
|
-
});
|
|
418
|
-
}
|
|
419
|
-
return [item];
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
const processedSidebar = (
|
|
423
|
-
await Promise.all(unprocessedSidebar.map(handleAutoGeneratedItems))
|
|
424
|
-
).flat();
|
|
425
|
-
|
|
426
|
-
return processedSidebar.map(fixSidebarItemInconsistencies);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
export async function processSidebars({
|
|
430
|
-
sidebarItemsGenerator,
|
|
431
|
-
numberPrefixParser,
|
|
432
|
-
unprocessedSidebars,
|
|
433
|
-
docs,
|
|
434
|
-
version,
|
|
435
|
-
options,
|
|
436
|
-
}: {
|
|
437
|
-
sidebarItemsGenerator: SidebarItemsGeneratorOption;
|
|
438
|
-
numberPrefixParser: NumberPrefixParser;
|
|
439
|
-
unprocessedSidebars: UnprocessedSidebars;
|
|
440
|
-
docs: DocMetadataBase[];
|
|
441
|
-
version: VersionMetadata;
|
|
442
|
-
options: SidebarOptions;
|
|
443
|
-
}): Promise<Sidebars> {
|
|
444
|
-
return combinePromises(
|
|
445
|
-
mapValues(unprocessedSidebars, (unprocessedSidebar) =>
|
|
446
|
-
processSidebar({
|
|
447
|
-
sidebarItemsGenerator,
|
|
448
|
-
numberPrefixParser,
|
|
449
|
-
unprocessedSidebar,
|
|
450
|
-
docs,
|
|
451
|
-
version,
|
|
452
|
-
options,
|
|
453
|
-
}),
|
|
454
|
-
),
|
|
455
|
-
);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
function collectSidebarItemsOfType<
|
|
459
|
-
Type extends SidebarItemType,
|
|
460
|
-
Item extends SidebarItem & {type: SidebarItemType}
|
|
461
|
-
>(type: Type, sidebar: Sidebar): Item[] {
|
|
462
|
-
function collectRecursive(item: SidebarItem): Item[] {
|
|
463
|
-
const currentItemsCollected: Item[] =
|
|
464
|
-
item.type === type ? [item as Item] : [];
|
|
465
|
-
|
|
466
|
-
const childItemsCollected: Item[] =
|
|
467
|
-
item.type === 'category' ? flatten(item.items.map(collectRecursive)) : [];
|
|
468
|
-
|
|
469
|
-
return [...currentItemsCollected, ...childItemsCollected];
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
return flatten(sidebar.map(collectRecursive));
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
export function collectSidebarDocItems(sidebar: Sidebar): SidebarItemDoc[] {
|
|
476
|
-
return collectSidebarItemsOfType('doc', sidebar);
|
|
477
|
-
}
|
|
478
|
-
export function collectSidebarCategories(
|
|
479
|
-
sidebar: Sidebar,
|
|
480
|
-
): SidebarItemCategory[] {
|
|
481
|
-
return collectSidebarItemsOfType('category', sidebar);
|
|
482
|
-
}
|
|
483
|
-
export function collectSidebarLinks(sidebar: Sidebar): SidebarItemLink[] {
|
|
484
|
-
return collectSidebarItemsOfType('link', sidebar);
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
export function transformSidebarItems(
|
|
488
|
-
sidebar: Sidebar,
|
|
489
|
-
updateFn: (item: SidebarItem) => SidebarItem,
|
|
490
|
-
): Sidebar {
|
|
491
|
-
function transformRecursive(item: SidebarItem): SidebarItem {
|
|
492
|
-
if (item.type === 'category') {
|
|
493
|
-
return updateFn({
|
|
494
|
-
...item,
|
|
495
|
-
items: item.items.map(transformRecursive),
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
return updateFn(item);
|
|
499
|
-
}
|
|
500
|
-
return sidebar.map(transformRecursive);
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
export function collectSidebarsDocIds(
|
|
504
|
-
sidebars: Sidebars,
|
|
505
|
-
): Record<string, string[]> {
|
|
506
|
-
return mapValues(sidebars, (sidebar) => {
|
|
507
|
-
return collectSidebarDocItems(sidebar).map((docItem) => docItem.id);
|
|
508
|
-
});
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
export function createSidebarsUtils(
|
|
512
|
-
sidebars: Sidebars,
|
|
513
|
-
): {
|
|
514
|
-
getFirstDocIdOfFirstSidebar: () => string | undefined;
|
|
515
|
-
getSidebarNameByDocId: (docId: string) => string | undefined;
|
|
516
|
-
getDocNavigation: (
|
|
517
|
-
docId: string,
|
|
518
|
-
) => {
|
|
519
|
-
sidebarName: string | undefined;
|
|
520
|
-
previousId: string | undefined;
|
|
521
|
-
nextId: string | undefined;
|
|
522
|
-
};
|
|
523
|
-
checkSidebarsDocIds: (validDocIds: string[], sidebarFilePath: string) => void;
|
|
524
|
-
} {
|
|
525
|
-
const sidebarNameToDocIds = collectSidebarsDocIds(sidebars);
|
|
526
|
-
|
|
527
|
-
function getFirstDocIdOfFirstSidebar(): string | undefined {
|
|
528
|
-
return Object.values(sidebarNameToDocIds)[0]?.[0];
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
function getSidebarNameByDocId(docId: string): string | undefined {
|
|
532
|
-
// TODO lookup speed can be optimized
|
|
533
|
-
const entry = Object.entries(
|
|
534
|
-
sidebarNameToDocIds,
|
|
535
|
-
).find(([_sidebarName, docIds]) => docIds.includes(docId));
|
|
536
|
-
|
|
537
|
-
return entry?.[0];
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
function getDocNavigation(
|
|
541
|
-
docId: string,
|
|
542
|
-
): {
|
|
543
|
-
sidebarName: string | undefined;
|
|
544
|
-
previousId: string | undefined;
|
|
545
|
-
nextId: string | undefined;
|
|
546
|
-
} {
|
|
547
|
-
const sidebarName = getSidebarNameByDocId(docId);
|
|
548
|
-
if (sidebarName) {
|
|
549
|
-
const docIds = sidebarNameToDocIds[sidebarName];
|
|
550
|
-
const currentIndex = docIds.indexOf(docId);
|
|
551
|
-
const {previous, next} = getElementsAround(docIds, currentIndex);
|
|
552
|
-
return {
|
|
553
|
-
sidebarName,
|
|
554
|
-
previousId: previous,
|
|
555
|
-
nextId: next,
|
|
556
|
-
};
|
|
557
|
-
} else {
|
|
558
|
-
return {
|
|
559
|
-
sidebarName: undefined,
|
|
560
|
-
previousId: undefined,
|
|
561
|
-
nextId: undefined,
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
function checkSidebarsDocIds(validDocIds: string[], sidebarFilePath: string) {
|
|
567
|
-
const allSidebarDocIds = flatten(Object.values(sidebarNameToDocIds));
|
|
568
|
-
const invalidSidebarDocIds = difference(allSidebarDocIds, validDocIds);
|
|
569
|
-
if (invalidSidebarDocIds.length > 0) {
|
|
570
|
-
throw new Error(
|
|
571
|
-
`Invalid sidebar file at "${toMessageRelativeFilePath(
|
|
572
|
-
sidebarFilePath,
|
|
573
|
-
)}".
|
|
574
|
-
These sidebar document ids do not exist:
|
|
575
|
-
- ${invalidSidebarDocIds.sort().join('\n- ')}
|
|
576
|
-
|
|
577
|
-
Available document ids are:
|
|
578
|
-
- ${validDocIds.sort().join('\n- ')}`,
|
|
579
|
-
);
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
return {
|
|
584
|
-
getFirstDocIdOfFirstSidebar,
|
|
585
|
-
getSidebarNameByDocId,
|
|
586
|
-
getDocNavigation,
|
|
587
|
-
checkSidebarsDocIds,
|
|
588
|
-
};
|
|
589
|
-
}
|