-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathgenerate-docs.js
More file actions
executable file
·342 lines (289 loc) · 8.81 KB
/
generate-docs.js
File metadata and controls
executable file
·342 lines (289 loc) · 8.81 KB
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
#!/usr/bin/env node
/**
* Generic documentation generation script for GridStack.js
* Generates both HTML and Markdown documentation for the main library and Angular components
*/
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
// Configuration
const config = {
// Main library paths
mainLib: {
root: '.',
typedocConfig: 'typedoc.json',
typedocHtmlConfig: 'typedoc.html.json',
outputDir: 'doc'
},
// Angular library paths
angular: {
root: 'angular',
typedocConfig: 'typedoc.json',
typedocHtmlConfig: 'typedoc.html.json',
outputDir: 'doc'
},
// Output configuration
output: {
cleanup: true,
verbose: true
}
};
/**
* Execute a command and handle errors
* @param {string} command - Command to execute
* @param {string} cwd - Working directory
* @param {string} description - Description for logging
*/
function execCommand(command, cwd = '.', description = '') {
if (config.output.verbose) {
console.log(`\n📋 ${description || command}`);
console.log(` Working directory: ${cwd}`);
console.log(` Command: ${command}`);
}
try {
const result = execSync(command, {
cwd,
stdio: config.output.verbose ? 'inherit' : 'pipe',
encoding: 'utf8'
});
if (config.output.verbose) {
console.log(`✅ Success`);
}
return result;
} catch (error) {
console.error(`❌ Error executing: ${command}`);
console.error(` Working directory: ${cwd}`);
console.error(` Error: ${error.message}`);
if (error.stdout) {
console.error(` Stdout: ${error.stdout}`);
}
if (error.stderr) {
console.error(` Stderr: ${error.stderr}`);
}
throw error;
}
}
/**
* Check if a file exists
* @param {string} filePath - Path to check
* @returns {boolean}
*/
function fileExists(filePath) {
try {
return fs.statSync(filePath).isFile();
} catch {
return false;
}
}
/**
* Generate documentation for a library
* @param {Object} libConfig - Library configuration
* @param {string} libName - Library name for logging
*/
function generateLibraryDocs(libConfig, libName) {
const { root, typedocConfig, typedocHtmlConfig } = libConfig;
console.log(`\n🔧 Generating documentation for ${libName}...`);
// Check if TypeDoc config files exist
const markdownConfigPath = path.join(root, typedocConfig);
const htmlConfigPath = path.join(root, typedocHtmlConfig);
if (!fileExists(markdownConfigPath)) {
console.warn(`⚠️ Markdown config not found: ${markdownConfigPath}`);
}
if (!fileExists(htmlConfigPath)) {
console.warn(`⚠️ HTML config not found: ${htmlConfigPath}`);
}
// Generate Markdown documentation
if (fileExists(markdownConfigPath)) {
execCommand(
`npx typedoc --options ${typedocConfig}`,
root,
`Generating Markdown docs for ${libName}`
);
// For main library, no _media directory cleanup needed since we generate a single file
// For Angular library, remove _media directory if it exists
if (libName === 'Angular Library') {
const mediaPath = path.join(root, libConfig.outputDir, 'api', '_media');
if (fs.existsSync(mediaPath)) {
execCommand(
`rm -rf ${path.join(libConfig.outputDir, 'api', '_media')}`,
root,
`Removing _media directory for ${libName}`
);
}
}
}
// Generate HTML documentation
if (fileExists(htmlConfigPath)) {
execCommand(
`npx typedoc --options ${typedocHtmlConfig}`,
root,
`Generating HTML docs for ${libName}`
);
// Remove media directory from HTML docs if it exists
const htmlMediaPath = path.join(root, libConfig.outputDir, 'html', 'media');
if (fs.existsSync(htmlMediaPath)) {
execCommand(
`rm -rf ${path.join(libConfig.outputDir, 'html', 'media')}`,
root,
`Removing media directory from HTML docs for ${libName}`
);
}
}
console.log(`✅ ${libName} documentation generated successfully`);
}
/**
* Run post-processing scripts if they exist
*/
function runPostProcessing() {
console.log(`\n🔧 Running post-processing...`);
// Main library post-processing
if (fileExists('scripts/reorder-docs.js')) {
execCommand(
'node scripts/reorder-docs.js',
'.',
'Reordering Markdown documentation'
);
}
if (fileExists('scripts/reorder-html-docs.js')) {
execCommand(
'node scripts/reorder-html-docs.js',
'.',
'Reordering HTML documentation'
);
}
console.log(`✅ Post-processing completed`);
}
/**
* Clean up old documentation if requested
*/
function cleanup() {
if (!config.output.cleanup) return;
console.log(`\n🧹 Cleaning up old documentation...`);
// Clean main library docs (API.md and HTML docs)
const mainDocsPath = path.join(config.mainLib.root, config.mainLib.outputDir);
if (fs.existsSync(mainDocsPath)) {
execCommand(`rm -rf ${mainDocsPath}/classes ${mainDocsPath}/interfaces ${mainDocsPath}/type-aliases ${mainDocsPath}/variables`, '.', 'Cleaning main library markdown docs');
}
// Clean HTML docs
if (fs.existsSync('doc/html')) {
execCommand(`rm -rf doc/html`, '.', 'Cleaning main library HTML docs');
}
// Clean Angular docs
const angularDocsPath = path.join(config.angular.root, config.angular.outputDir);
if (fs.existsSync(angularDocsPath)) {
execCommand(`rm -rf ${angularDocsPath}`, config.angular.root, 'Cleaning Angular library docs');
}
console.log(`✅ Cleanup completed`);
}
/**
* Display help information
*/
function showHelp() {
console.log(`
📚 GridStack Documentation Generator
Usage: node scripts/generate-docs.js [options]
Options:
--main-only Generate only main library documentation
--angular-only Generate only Angular library documentation
--no-cleanup Skip cleanup of existing documentation
--quiet Reduce output verbosity
--help, -h Show this help message
Examples:
node scripts/generate-docs.js # Generate all documentation
node scripts/generate-docs.js --main-only # Main library only
node scripts/generate-docs.js --angular-only # Angular library only
node scripts/generate-docs.js --no-cleanup # Keep existing docs
Environment:
NODE_ENV Set to 'development' for verbose output
`);
}
/**
* Parse command line arguments
*/
function parseArgs() {
const args = process.argv.slice(2);
const options = {
mainOnly: false,
angularOnly: false,
cleanup: true,
verbose: process.env.NODE_ENV === 'development'
};
for (const arg of args) {
switch (arg) {
case '--main-only':
options.mainOnly = true;
break;
case '--angular-only':
options.angularOnly = true;
break;
case '--no-cleanup':
options.cleanup = false;
break;
case '--quiet':
options.verbose = false;
break;
case '--help':
case '-h':
showHelp();
process.exit(0);
break;
default:
console.warn(`⚠️ Unknown argument: ${arg}`);
}
}
return options;
}
/**
* Main execution function
*/
function main() {
const options = parseArgs();
// Update config with options
config.output.cleanup = options.cleanup;
config.output.verbose = options.verbose;
console.log(`🚀 GridStack Documentation Generator`);
console.log(` Main library: ${!options.angularOnly}`);
console.log(` Angular library: ${!options.mainOnly}`);
console.log(` Cleanup: ${config.output.cleanup}`);
console.log(` Verbose: ${config.output.verbose}`);
try {
// Cleanup if requested
if (config.output.cleanup) {
cleanup();
}
// Generate main library documentation
if (!options.angularOnly) {
generateLibraryDocs(config.mainLib, 'Main Library');
}
// Generate Angular library documentation
if (!options.mainOnly) {
generateLibraryDocs(config.angular, 'Angular Library');
}
// Run post-processing
if (!options.angularOnly) {
runPostProcessing();
}
console.log(`\n🎉 Documentation generation completed successfully!`);
console.log(`\nGenerated documentation:`);
if (!options.angularOnly) {
console.log(` 📄 Main Library Markdown: doc/API.md`);
console.log(` 🌐 Main Library HTML: doc/html/`);
}
if (!options.mainOnly) {
console.log(` 📄 Angular Library Markdown: angular/doc/api/`);
console.log(` 🌐 Angular Library HTML: angular/doc/html/`);
}
} catch (error) {
console.error(`\n💥 Documentation generation failed!`);
console.error(`Error: ${error.message}`);
process.exit(1);
}
}
// Run the script
if (require.main === module) {
main();
}
module.exports = {
generateLibraryDocs,
config
};