-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
/
processor.ts
139 lines (127 loc) · 4.01 KB
/
processor.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import type {
DocMetadataBase,
VersionMetadata,
} from '@docusaurus/plugin-content-docs';
import type {
NormalizedSidebarItem,
NormalizedSidebar,
NormalizedSidebars,
SidebarItemsGeneratorDoc,
SidebarItemsGeneratorVersion,
SidebarItemAutogenerated,
ProcessedSidebarItem,
ProcessedSidebar,
ProcessedSidebars,
SidebarProcessorParams,
CategoryMetadataFile,
} from './types';
import {DefaultSidebarItemsGenerator} from './generator';
import {validateSidebars} from './validation';
import _ from 'lodash';
import combinePromises from 'combine-promises';
import {getDocIds, isCategoryIndex} from '../docs';
function toSidebarItemsGeneratorDoc(
doc: DocMetadataBase,
): SidebarItemsGeneratorDoc {
return _.pick(doc, [
'id',
'unversionedId',
'title',
'frontMatter',
'source',
'sourceDirName',
'sidebarPosition',
]);
}
function toSidebarItemsGeneratorVersion(
version: VersionMetadata,
): SidebarItemsGeneratorVersion {
return _.pick(version, ['versionName', 'contentPath']);
}
// Handle the generation of autogenerated sidebar items and other
// post-processing checks
async function processSidebar(
unprocessedSidebar: NormalizedSidebar,
categoriesMetadata: {[filePath: string]: CategoryMetadataFile},
params: SidebarProcessorParams,
): Promise<ProcessedSidebar> {
const {sidebarItemsGenerator, numberPrefixParser, docs, drafts, version} =
params;
// Just a minor lazy transformation optimization
const getSidebarItemsGeneratorDocsAndVersion = _.memoize(() => ({
docs: docs.map(toSidebarItemsGeneratorDoc),
version: toSidebarItemsGeneratorVersion(version),
}));
async function processAutoGeneratedItem(
item: SidebarItemAutogenerated,
): Promise<ProcessedSidebarItem[]> {
const generatedItems = await sidebarItemsGenerator({
item,
numberPrefixParser,
defaultSidebarItemsGenerator: DefaultSidebarItemsGenerator,
isCategoryIndex,
...getSidebarItemsGeneratorDocsAndVersion(),
categoriesMetadata,
});
// Process again... weird but sidebar item generated might generate some
// auto-generated items?
// TODO repeatedly process & unwrap autogenerated items until there are no
// more autogenerated items, or when loop count (e.g. 10) is reached
return processItems(generatedItems);
}
const draftIds = new Set(drafts.flatMap(getDocIds));
const isDraftItem = (item: NormalizedSidebarItem): boolean => {
if (item.type === 'doc' || item.type === 'ref') {
return draftIds.has(item.id);
}
// If a category only contains draft items, it should be filtered entirely.
if (item.type === 'category') {
return item.items.every(isDraftItem);
}
return false;
};
async function processItem(
item: NormalizedSidebarItem,
): Promise<ProcessedSidebarItem[]> {
if (item.type === 'category') {
return [
{
...item,
items: await processItems(item.items),
},
];
}
if (item.type === 'autogenerated') {
return processAutoGeneratedItem(item);
}
return [item];
}
async function processItems(
items: NormalizedSidebarItem[],
): Promise<ProcessedSidebarItem[]> {
return (
await Promise.all(items.filter((i) => !isDraftItem(i)).map(processItem))
).flat();
}
const processedSidebar = await processItems(unprocessedSidebar);
return processedSidebar;
}
export async function processSidebars(
unprocessedSidebars: NormalizedSidebars,
categoriesMetadata: {[filePath: string]: CategoryMetadataFile},
params: SidebarProcessorParams,
): Promise<ProcessedSidebars> {
const processedSidebars = await combinePromises(
_.mapValues(unprocessedSidebars, (unprocessedSidebar) =>
processSidebar(unprocessedSidebar, categoriesMetadata, params),
),
);
validateSidebars(processedSidebars);
return processedSidebars;
}