-
Notifications
You must be signed in to change notification settings - Fork 734
/
Copy pathbuildDocsCommon.js
153 lines (130 loc) · 4.74 KB
/
buildDocsCommon.js
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/**
* This script generate markdown pages for each of our components based on the api.json files
*/
const _ = require('lodash');
const childProcess = require('child_process');
const fs = require('fs');
const COMPONENTS_DOCS_DIR = './docs/components';
const SERVICES_DOCS_DIR = './docs/services';
const FOUNDATION_DOCS_DIR = './docs/foundation';
const VALID_COMPONENTS_CATEGORIES = [
'foundation',
'basic',
'assets',
'navigation',
'layout',
'controls',
'status',
'media',
'lists',
'form',
'dateTime',
'overlays',
'charts',
'incubator',
'infra',
// non components categories
'services',
'dev' // development category for components we don't want to render in our docs (used in test.api.json)
];
function buildDocs(apiFolders, componentsPreProcess) {
let components = readComponentsFromApiFiles(apiFolders);
logStatistics(components);
components = componentsPreProcess?.(components) ?? components;
resetDocsDir();
processComponents(components);
}
function readComponentsFromApiFiles(apiFolders) {
let apiFiles = childProcess.execSync(`find ${apiFolders} -name "*api.json"`);
apiFiles = apiFiles.toString().trim().split('\n');
return apiFiles.map(filePath => {
const file = fs.readFileSync(filePath);
const api = JSON.parse(file.toString());
return api;
});
}
function resetDocsDir() {
if (fs.existsSync(COMPONENTS_DOCS_DIR)) {
childProcess.execSync(`rm -rf ${COMPONENTS_DOCS_DIR}`);
}
fs.mkdirSync(COMPONENTS_DOCS_DIR, {recursive: true});
}
function isCompoundComponent(componentName) {
return componentName.includes('.');
}
function processComponents(components) {
/** Break into compound components (TabController.TabPage) and parent components (TabController) */
const compoundComponents = components.filter(c => isCompoundComponent(c.name));
const parentComponents = _.flow(components => _.map(components, c => c.name.split('.')[0]),
_.uniq)(compoundComponents);
components.forEach(component => {
const [componentName, componentParentName] = getComponentNameParts(component.name);
const isParentComponent = parentComponents.includes(componentName);
const isIncubatorComponent = component.category === 'incubator';
if (!VALID_COMPONENTS_CATEGORIES.includes(component.category)) {
console.error(`${componentName} has invalid category "${component.category}"`);
}
/* Markdown Front Matter */
let content = '';
content += '---\n';
if (isParentComponent) {
content += 'sidebar_position: 1\n';
}
const title = component.docs?.hero ? '""' : `${isIncubatorComponent ? 'Incubator.' : ''}${component.name}`;
content += `id: ${component.name}\n`;
content += `title: ${title}\n`;
content += `sidebar_label: ${componentName}\n`;
content += '---\n\n';
content += `import ComponentPage from '@site/src/components/ComponentPage';\n\n`;
const componentObject = JSON.stringify(component);
content += `<ComponentPage component={${componentObject}}/>\n`;
let dirPath;
switch (component.category) {
case 'services': {
dirPath = `${SERVICES_DOCS_DIR}`;
break;
}
case 'foundation': {
dirPath = `${FOUNDATION_DOCS_DIR}`;
break;
}
default: {
const componentParentDir =
componentParentName || isParentComponent ? `/${componentParentName || componentName}` : '';
dirPath = `${COMPONENTS_DOCS_DIR}/${component.category}${componentParentDir}`;
break;
}
}
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, {recursive: true});
}
fs.writeFileSync(`${dirPath}/${component.name.replaceAll(' ', '_')}.md`, content, {encoding: 'utf8'});
});
}
function getComponentNameParts(componentName) {
const parts = componentName.split('.');
if (parts.length === 1) {
return [parts[0], undefined];
} else {
return [parts[1], parts[0]];
}
}
function generateExtendsLink(extendsLink) {
const extendedComponentName = _.last(_.split(extendsLink, '/')); // Incubator/TextField -> TextField
const extendsText = `[${extendedComponentName}](/docs/components/${extendsLink})`;
return extendsText;
}
function logStatistics(components) {
const groupedComponents = _.countBy(components, 'name');
const duplicateComponents = Object.entries(groupedComponents)
.filter(([_, count]) => count > 1)
.map(([name, count]) => `${name} (${count} times)`);
if (duplicateComponents.length > 0) {
console.log('Components with multiple occurrences:\n-', duplicateComponents.join('\n- '));
}
const componentsWithoutSnippet = components.filter(c => !c.snippet).map(c => c.name);
if (componentsWithoutSnippet.length > 0) {
console.log('Components missing snippet:\n-', componentsWithoutSnippet.join('\n- '));
}
}
module.exports = {buildDocs};