1 | import * as ts from 'typescript';
|
2 | import * as fs from 'fs-extra';
|
3 | import * as path from 'path';
|
4 | import * as _ from 'lodash';
|
5 | import * as LiveServer from 'live-server';
|
6 | import * as Shelljs from 'shelljs';
|
7 | import marked from 'marked';
|
8 |
|
9 | const glob: any = require('glob');
|
10 |
|
11 | import { logger } from '../logger';
|
12 | import { HtmlEngine } from './engines/html.engine';
|
13 | import { MarkdownEngine } from './engines/markdown.engine';
|
14 | import { FileEngine } from './engines/file.engine';
|
15 | import { Configuration, IConfiguration } from './configuration';
|
16 | import { $dependenciesEngine } from './engines/dependencies.engine';
|
17 | import { NgdEngine } from './engines/ngd.engine';
|
18 | import { SearchEngine } from './engines/search.engine';
|
19 | import { Dependencies } from './compiler/dependencies';
|
20 | import { RouterParser } from '../utils/router.parser';
|
21 |
|
22 | import { COMPODOC_DEFAULTS } from '../utils/defaults';
|
23 |
|
24 | let pkg = require('../package.json'),
|
25 | cwd = process.cwd(),
|
26 | $htmlengine = new HtmlEngine(),
|
27 | $fileengine = new FileEngine(),
|
28 | $markdownengine = new MarkdownEngine(),
|
29 | $ngdengine = new NgdEngine(),
|
30 | $searchEngine = new SearchEngine(),
|
31 | startTime = new Date();
|
32 |
|
33 | export class Application {
|
34 | options:Object;
|
35 | files: Array<string>;
|
36 |
|
37 | configuration:IConfiguration;
|
38 |
|
39 | |
40 |
|
41 |
|
42 |
|
43 |
|
44 | constructor(options?:Object) {
|
45 | this.configuration = Configuration.getInstance();
|
46 |
|
47 | for (let option in options ) {
|
48 | if(typeof this.configuration.mainData[option] !== 'undefined') {
|
49 | this.configuration.mainData[option] = options[option];
|
50 | }
|
51 | }
|
52 | }
|
53 |
|
54 | |
55 |
|
56 |
|
57 | protected generate() {
|
58 | $htmlengine.init().then(() => {
|
59 | this.processPackageJson();
|
60 | });
|
61 | }
|
62 |
|
63 | setFiles(files:Array<string>) {
|
64 | this.files = files;
|
65 | }
|
66 |
|
67 | processPackageJson() {
|
68 | logger.info('Searching package.json file');
|
69 | $fileengine.get('package.json').then((packageData) => {
|
70 | let parsedData = JSON.parse(packageData);
|
71 | if (typeof parsedData.name !== 'undefined' && this.configuration.mainData.documentationMainName === COMPODOC_DEFAULTS.title) {
|
72 | this.configuration.mainData.documentationMainName = parsedData.name + ' documentation';
|
73 | }
|
74 | if (typeof parsedData.description !== 'undefined') {
|
75 | this.configuration.mainData.documentationMainDescription = parsedData.description;
|
76 | }
|
77 | logger.info('package.json file found');
|
78 | this.processMarkdown();
|
79 | }, (errorMessage) => {
|
80 | logger.error(errorMessage);
|
81 | logger.error('Continuing without package.json file');
|
82 | this.processMarkdown();
|
83 | });
|
84 | }
|
85 |
|
86 | processMarkdown() {
|
87 | logger.info('Searching README.md file');
|
88 | $markdownengine.getReadmeFile().then((readmeData: string) => {
|
89 | this.configuration.addPage({
|
90 | name: 'index',
|
91 | context: 'readme',
|
92 | depth: 1,
|
93 | pageType: COMPODOC_DEFAULTS.PAGE_TYPES.ROOT
|
94 | });
|
95 | this.configuration.addPage({
|
96 | name: 'overview',
|
97 | context: 'overview',
|
98 | pageType: COMPODOC_DEFAULTS.PAGE_TYPES.ROOT
|
99 | });
|
100 | this.configuration.mainData.readme = readmeData;
|
101 | logger.info('README.md file found');
|
102 | this.getDependenciesData();
|
103 | }, (errorMessage) => {
|
104 | logger.error(errorMessage);
|
105 | logger.error('Continuing without README.md file');
|
106 | this.configuration.addPage({
|
107 | name: 'index',
|
108 | context: 'overview'
|
109 | });
|
110 | this.getDependenciesData();
|
111 | });
|
112 | }
|
113 |
|
114 | getDependenciesData() {
|
115 | logger.info('Get dependencies data');
|
116 |
|
117 | let crawler = new Dependencies(
|
118 | this.files, {
|
119 | tsconfigDirectory: path.dirname(this.configuration.mainData.tsconfig)
|
120 | }
|
121 | );
|
122 |
|
123 | let dependenciesData = crawler.getDependencies();
|
124 |
|
125 | $dependenciesEngine.init(dependenciesData);
|
126 |
|
127 | this.prepareModules();
|
128 |
|
129 | this.prepareComponents().then((readmeData) => {
|
130 | if ($dependenciesEngine.directives.length > 0) {
|
131 | this.prepareDirectives();
|
132 | }
|
133 | if ($dependenciesEngine.injectables.length > 0) {
|
134 | this.prepareInjectables();
|
135 | }
|
136 | if ($dependenciesEngine.routes.length > 0) {
|
137 | this.prepareRoutes();
|
138 | }
|
139 |
|
140 | if ($dependenciesEngine.pipes.length > 0) {
|
141 | this.preparePipes();
|
142 | }
|
143 |
|
144 | if ($dependenciesEngine.classes.length > 0) {
|
145 | this.prepareClasses();
|
146 | }
|
147 |
|
148 | if ($dependenciesEngine.interfaces.length > 0) {
|
149 | this.prepareInterfaces();
|
150 | }
|
151 |
|
152 | if ($dependenciesEngine.miscellaneous.variables.length > 0 ||
|
153 | $dependenciesEngine.miscellaneous.functions.length > 0 ||
|
154 | $dependenciesEngine.miscellaneous.typealiases.length > 0 ||
|
155 | $dependenciesEngine.miscellaneous.enumerations.length > 0 ) {
|
156 | this.prepareMiscellaneous();
|
157 | }
|
158 |
|
159 | if (!this.configuration.mainData.disableCoverage) {
|
160 | this.prepareCoverage();
|
161 | }
|
162 |
|
163 | this.processPages();
|
164 | }, (errorMessage) => {
|
165 | logger.error(errorMessage);
|
166 | });
|
167 | }
|
168 |
|
169 | prepareModules() {
|
170 | logger.info('Prepare modules');
|
171 | this.configuration.mainData.modules = $dependenciesEngine.getModules().map(ngModule => {
|
172 | ['declarations', 'bootstrap', 'imports', 'exports'].forEach(metadataType => {
|
173 | ngModule[metadataType] = ngModule[metadataType].filter(metaDataItem => {
|
174 | switch (metaDataItem.type) {
|
175 | case 'directive':
|
176 | return $dependenciesEngine.getDirectives().some(directive => directive.name === metaDataItem.name);
|
177 |
|
178 | case 'component':
|
179 | return $dependenciesEngine.getComponents().some(component => component.name === metaDataItem.name);
|
180 |
|
181 | case 'module':
|
182 | return $dependenciesEngine.getModules().some(module => module.name === metaDataItem.name);
|
183 |
|
184 | case 'pipe':
|
185 | return $dependenciesEngine.getPipes().some(pipe => pipe.name === metaDataItem.name);
|
186 |
|
187 | default:
|
188 | return true;
|
189 | }
|
190 | });
|
191 | });
|
192 | ngModule.providers = ngModule.providers.filter(provider => {
|
193 | return $dependenciesEngine.getInjectables().some(injectable => injectable.name === provider.name);
|
194 | });
|
195 | return ngModule;
|
196 | });
|
197 | this.configuration.addPage({
|
198 | name: 'modules',
|
199 | context: 'modules',
|
200 | depth: 1,
|
201 | pageType: COMPODOC_DEFAULTS.PAGE_TYPES.ROOT
|
202 | });
|
203 | let i = 0,
|
204 | len = this.configuration.mainData.modules.length;
|
205 |
|
206 | for(i; i<len; i++) {
|
207 | this.configuration.addPage({
|
208 | path: 'modules',
|
209 | name: this.configuration.mainData.modules[i].name,
|
210 | context: 'module',
|
211 | module: this.configuration.mainData.modules[i],
|
212 | depth: 2,
|
213 | pageType: COMPODOC_DEFAULTS.PAGE_TYPES.INTERNAL
|
214 | });
|
215 | }
|
216 | }
|
217 |
|
218 | preparePipes = () => {
|
219 | logger.info('Prepare pipes');
|
220 | this.configuration.mainData.pipes = $dependenciesEngine.getPipes();
|
221 | let i = 0,
|
222 | len = this.configuration.mainData.pipes.length;
|
223 |
|
224 | for(i; i<len; i++) {
|
225 | this.configuration.addPage({
|
226 | path: 'pipes',
|
227 | name: this.configuration.mainData.pipes[i].name,
|
228 | context: 'pipe',
|
229 | pipe: this.configuration.mainData.pipes[i],
|
230 | depth: 2,
|
231 | pageType: COMPODOC_DEFAULTS.PAGE_TYPES.INTERNAL
|
232 | });
|
233 | }
|
234 | }
|
235 |
|
236 | prepareClasses = () => {
|
237 | logger.info('Prepare classes');
|
238 | this.configuration.mainData.classes = $dependenciesEngine.getClasses();
|
239 | let i = 0,
|
240 | len = this.configuration.mainData.classes.length;
|
241 |
|
242 | for(i; i<len; i++) {
|
243 | this.configuration.addPage({
|
244 | path: 'classes',
|
245 | name: this.configuration.mainData.classes[i].name,
|
246 | context: 'class',
|
247 | class: this.configuration.mainData.classes[i],
|
248 | depth: 2,
|
249 | pageType: COMPODOC_DEFAULTS.PAGE_TYPES.INTERNAL
|
250 | });
|
251 | }
|
252 | }
|
253 |
|
254 | prepareInterfaces() {
|
255 | logger.info('Prepare interfaces');
|
256 | this.configuration.mainData.interfaces = $dependenciesEngine.getInterfaces();
|
257 | let i = 0,
|
258 | len = this.configuration.mainData.interfaces.length;
|
259 | for(i; i<len; i++) {
|
260 | this.configuration.addPage({
|
261 | path: 'interfaces',
|
262 | name: this.configuration.mainData.interfaces[i].name,
|
263 | context: 'interface',
|
264 | interface: this.configuration.mainData.interfaces[i],
|
265 | depth: 2,
|
266 | pageType: COMPODOC_DEFAULTS.PAGE_TYPES.INTERNAL
|
267 | });
|
268 | }
|
269 | }
|
270 |
|
271 | prepareMiscellaneous() {
|
272 | logger.info('Prepare miscellaneous');
|
273 | this.configuration.mainData.miscellaneous = $dependenciesEngine.getMiscellaneous();
|
274 |
|
275 | this.configuration.addPage({
|
276 | name: 'miscellaneous',
|
277 | context: 'miscellaneous',
|
278 | depth: 1,
|
279 | pageType: COMPODOC_DEFAULTS.PAGE_TYPES.ROOT
|
280 | });
|
281 | }
|
282 |
|
283 | prepareComponents() {
|
284 | logger.info('Prepare components');
|
285 | let that = this;
|
286 | that.configuration.mainData.components = $dependenciesEngine.getComponents();
|
287 |
|
288 | return new Promise(function(resolve, reject) {
|
289 | let i = 0,
|
290 | len = that.configuration.mainData.components.length,
|
291 | loop = () => {
|
292 | if( i <= len-1) {
|
293 | let dirname = path.dirname(that.configuration.mainData.components[i].file),
|
294 | readmeFile = dirname + path.sep + 'README.md';
|
295 | if (fs.existsSync(readmeFile)) {
|
296 | logger.info('README.md exist for this component, include it');
|
297 | fs.readFile(readmeFile, 'utf8', (err, data) => {
|
298 | if (err) throw err;
|
299 | that.configuration.mainData.components[i].readme = marked(data);
|
300 | that.configuration.addPage({
|
301 | path: 'components',
|
302 | name: that.configuration.mainData.components[i].name,
|
303 | context: 'component',
|
304 | component: that.configuration.mainData.components[i],
|
305 | depth: 2,
|
306 | pageType: COMPODOC_DEFAULTS.PAGE_TYPES.INTERNAL
|
307 | });
|
308 | i++;
|
309 | loop();
|
310 | });
|
311 | } else {
|
312 | that.configuration.addPage({
|
313 | path: 'components',
|
314 | name: that.configuration.mainData.components[i].name,
|
315 | context: 'component',
|
316 | component: that.configuration.mainData.components[i]
|
317 | });
|
318 | i++;
|
319 | loop();
|
320 | }
|
321 | } else {
|
322 | resolve();
|
323 | }
|
324 | };
|
325 | loop();
|
326 | });
|
327 | }
|
328 |
|
329 | prepareDirectives = () => {
|
330 | logger.info('Prepare directives');
|
331 | this.configuration.mainData.directives = $dependenciesEngine.getDirectives();
|
332 |
|
333 | let i = 0,
|
334 | len = this.configuration.mainData.directives.length;
|
335 |
|
336 | for(i; i<len; i++) {
|
337 | this.configuration.addPage({
|
338 | path: 'directives',
|
339 | name: this.configuration.mainData.directives[i].name,
|
340 | context: 'directive',
|
341 | directive: this.configuration.mainData.directives[i],
|
342 | depth: 2,
|
343 | pageType: COMPODOC_DEFAULTS.PAGE_TYPES.INTERNAL
|
344 | });
|
345 | }
|
346 | }
|
347 |
|
348 | prepareInjectables() {
|
349 | logger.info('Prepare injectables');
|
350 | this.configuration.mainData.injectables = $dependenciesEngine.getInjectables();
|
351 |
|
352 | let i = 0,
|
353 | len = this.configuration.mainData.injectables.length;
|
354 |
|
355 | for(i; i<len; i++) {
|
356 | this.configuration.addPage({
|
357 | path: 'injectables',
|
358 | name: this.configuration.mainData.injectables[i].name,
|
359 | context: 'injectable',
|
360 | injectable: this.configuration.mainData.injectables[i],
|
361 | depth: 2,
|
362 | pageType: COMPODOC_DEFAULTS.PAGE_TYPES.INTERNAL
|
363 | });
|
364 | }
|
365 | }
|
366 |
|
367 | prepareRoutes() {
|
368 | logger.info('Process routes');
|
369 | this.configuration.mainData.routes = $dependenciesEngine.getRoutes();
|
370 |
|
371 | this.configuration.addPage({
|
372 | name: 'routes',
|
373 | context: 'routes',
|
374 | depth: 1,
|
375 | pageType: COMPODOC_DEFAULTS.PAGE_TYPES.ROOT
|
376 | });
|
377 | }
|
378 |
|
379 | prepareCoverage() {
|
380 | logger.info('Process documentation coverage report');
|
381 |
|
382 | |
383 |
|
384 |
|
385 | var files = [],
|
386 | totalProjectStatementDocumented = 0,
|
387 | getStatus = function(percent) {
|
388 | var status;
|
389 | if (percent <= 25) {
|
390 | status = 'low';
|
391 | } else if (percent > 25 && percent <= 50) {
|
392 | status = 'medium';
|
393 | } else if (percent > 50 && percent <= 75) {
|
394 | status = 'good';
|
395 | } else {
|
396 | status = 'very-good';
|
397 | }
|
398 | return status;
|
399 | };
|
400 |
|
401 | _.forEach(this.configuration.mainData.components, (component) => {
|
402 | if (!component.propertiesClass ||
|
403 | !component.methodsClass ||
|
404 | !component.inputsClass ||
|
405 | !component.outputsClass) {
|
406 | return;
|
407 | }
|
408 | let cl = {
|
409 | filePath: component.file,
|
410 | type: component.type,
|
411 | name: component.name
|
412 | },
|
413 | totalStatementDocumented = 0,
|
414 | totalStatements = component.propertiesClass.length + component.methodsClass.length + component.inputsClass.length + component.outputsClass.length + 1;
|
415 | _.forEach(component.propertiesClass, (property) => {
|
416 | if(property.description !== '') {
|
417 | totalStatementDocumented += 1;
|
418 | }
|
419 | });
|
420 | _.forEach(component.methodsClass, (method) => {
|
421 | if(method.description !== '') {
|
422 | totalStatementDocumented += 1;
|
423 | }
|
424 | });
|
425 | _.forEach(component.inputsClass, (input) => {
|
426 | if(input.description !== '') {
|
427 | totalStatementDocumented += 1;
|
428 | }
|
429 | });
|
430 | _.forEach(component.outputsClass, (output) => {
|
431 | if(output.description !== '') {
|
432 | totalStatementDocumented += 1;
|
433 | }
|
434 | });
|
435 | if (component.description !== '') {
|
436 | totalStatementDocumented += 1;
|
437 | }
|
438 | cl.coveragePercent = Math.floor((totalStatementDocumented / totalStatements) * 100);
|
439 | if(totalStatements === 0) {
|
440 | cl.coveragePercent = 0;
|
441 | }
|
442 | cl.coverageCount = totalStatementDocumented + '/' + totalStatements;
|
443 | cl.status = getStatus(cl.coveragePercent);
|
444 | totalProjectStatementDocumented += cl.coveragePercent;
|
445 | files.push(cl);
|
446 | })
|
447 | _.forEach(this.configuration.mainData.classes, (classe) => {
|
448 | if (!classe.properties ||
|
449 | !classe.methods) {
|
450 | return;
|
451 | }
|
452 | let cl = {
|
453 | filePath: classe.file,
|
454 | type: 'classe',
|
455 | name: classe.name
|
456 | },
|
457 | totalStatementDocumented = 0,
|
458 | totalStatements = classe.properties.length + classe.methods.length;
|
459 | _.forEach(classe.properties, (property) => {
|
460 | if(property.description !== '') {
|
461 | totalStatementDocumented += 1;
|
462 | }
|
463 | });
|
464 | _.forEach(classe.methods, (method) => {
|
465 | if(method.description !== '') {
|
466 | totalStatementDocumented += 1;
|
467 | }
|
468 | });
|
469 | cl.coveragePercent = Math.floor((totalStatementDocumented / totalStatements) * 100);
|
470 | if(totalStatements === 0) {
|
471 | cl.coveragePercent = 0;
|
472 | }
|
473 | cl.coverageCount = totalStatementDocumented + '/' + totalStatements;
|
474 | cl.status = getStatus(cl.coveragePercent);
|
475 | totalProjectStatementDocumented += cl.coveragePercent;
|
476 | files.push(cl);
|
477 | });
|
478 | _.forEach(this.configuration.mainData.injectables, (injectable) => {
|
479 | if (!injectable.properties ||
|
480 | !injectable.methods) {
|
481 | return;
|
482 | }
|
483 | let cl = {
|
484 | filePath: injectable.file,
|
485 | type: injectable.type,
|
486 | name: injectable.name
|
487 | },
|
488 | totalStatementDocumented = 0,
|
489 | totalStatements = injectable.properties.length + injectable.methods.length;
|
490 | _.forEach(injectable.properties, (property) => {
|
491 | if(property.description !== '') {
|
492 | totalStatementDocumented += 1;
|
493 | }
|
494 | });
|
495 | _.forEach(injectable.methods, (method) => {
|
496 | if(method.description !== '') {
|
497 | totalStatementDocumented += 1;
|
498 | }
|
499 | });
|
500 | cl.coveragePercent = Math.floor((totalStatementDocumented / totalStatements) * 100);
|
501 | if(totalStatements === 0) {
|
502 | cl.coveragePercent = 0;
|
503 | }
|
504 | cl.coverageCount = totalStatementDocumented + '/' + totalStatements;
|
505 | cl.status = getStatus(cl.coveragePercent);
|
506 | totalProjectStatementDocumented += cl.coveragePercent;
|
507 | files.push(cl);
|
508 | });
|
509 | _.forEach(this.configuration.mainData.interfaces, (inter) => {
|
510 | if (!inter.properties ||
|
511 | !inter.methods) {
|
512 | return;
|
513 | }
|
514 | let cl = {
|
515 | filePath: inter.file,
|
516 | type: inter.type,
|
517 | name: inter.name
|
518 | },
|
519 | totalStatementDocumented = 0,
|
520 | totalStatements = inter.properties.length + inter.methods.length;
|
521 | _.forEach(inter.properties, (property) => {
|
522 | if(property.description !== '') {
|
523 | totalStatementDocumented += 1;
|
524 | }
|
525 | });
|
526 | _.forEach(inter.methods, (method) => {
|
527 | if(method.description !== '') {
|
528 | totalStatementDocumented += 1;
|
529 | }
|
530 | });
|
531 | cl.coveragePercent = Math.floor((totalStatementDocumented / totalStatements) * 100);
|
532 | if(totalStatements === 0) {
|
533 | cl.coveragePercent = 0;
|
534 | }
|
535 | cl.coverageCount = totalStatementDocumented + '/' + totalStatements;
|
536 | cl.status = getStatus(cl.coveragePercent);
|
537 | totalProjectStatementDocumented += cl.coveragePercent;
|
538 | files.push(cl);
|
539 | });
|
540 | _.forEach(this.configuration.mainData.pipes, (pipe) => {
|
541 | let cl = {
|
542 | filePath: pipe.file,
|
543 | type: pipe.type,
|
544 | name: pipe.name
|
545 | },
|
546 | totalStatementDocumented = 0,
|
547 | totalStatements = 1;
|
548 | if (pipe.description !== '') {
|
549 | totalStatementDocumented += 1;
|
550 | }
|
551 | cl.coveragePercent = Math.floor((totalStatementDocumented / totalStatements) * 100);
|
552 | cl.coverageCount = totalStatementDocumented + '/' + totalStatements;
|
553 | cl.status = getStatus(cl.coveragePercent);
|
554 | totalProjectStatementDocumented += cl.coveragePercent;
|
555 | files.push(cl);
|
556 | });
|
557 | files = _.sortBy(files, ['filePath']);
|
558 | var coverageData = {
|
559 | count: Math.floor(totalProjectStatementDocumented / files.length),
|
560 | status: ''
|
561 | };
|
562 | coverageData.status = getStatus(coverageData.count);
|
563 | this.configuration.addPage({
|
564 | name: 'coverage',
|
565 | context: 'coverage',
|
566 | files: files,
|
567 | data: coverageData,
|
568 | depth: 1,
|
569 | pageType: COMPODOC_DEFAULTS.PAGE_TYPES.ROOT
|
570 | });
|
571 | }
|
572 |
|
573 | processPages() {
|
574 | logger.info('Process pages');
|
575 | let pages = this.configuration.pages,
|
576 | i = 0,
|
577 | len = pages.length,
|
578 | loop = () => {
|
579 | if( i <= len-1) {
|
580 | logger.info('Process page', pages[i].name);
|
581 | $htmlengine.render(this.configuration.mainData, pages[i]).then((htmlData) => {
|
582 | let finalPath = this.configuration.mainData.output;
|
583 | if(this.configuration.mainData.output.lastIndexOf('/') === -1) {
|
584 | finalPath += '/';
|
585 | }
|
586 | if (pages[i].path) {
|
587 | finalPath += pages[i].path + '/';
|
588 | }
|
589 | finalPath += pages[i].name + '.html';
|
590 | $searchEngine.indexPage({
|
591 | infos: pages[i],
|
592 | rawData: htmlData,
|
593 | url: finalPath
|
594 | });
|
595 | fs.outputFile(path.resolve(finalPath), htmlData, function (err) {
|
596 | if (err) {
|
597 | logger.error('Error during ' + pages[i].name + ' page generation');
|
598 | } else {
|
599 | i++;
|
600 | loop();
|
601 | }
|
602 | });
|
603 | }, (errorMessage) => {
|
604 | logger.error(errorMessage);
|
605 | });
|
606 | } else {
|
607 | $searchEngine.generateSearchIndexJson(this.configuration.mainData.output).then(() => {
|
608 | if (this.configuration.mainData.assetsFolder !== '') {
|
609 | this.processAssetsFolder();
|
610 | }
|
611 | this.processResources();
|
612 | }, (e) => {
|
613 | logger.error(e);
|
614 | });
|
615 | }
|
616 | };
|
617 | loop();
|
618 | }
|
619 |
|
620 | processAssetsFolder() {
|
621 | logger.info('Copy assets folder');
|
622 |
|
623 | if (!fs.existsSync(this.configuration.mainData.assetsFolder)) {
|
624 | logger.error(`Provided assets folder ${this.configuration.mainData.assetsFolder} did not exist`);
|
625 | } else {
|
626 | let that = this;
|
627 | fs.copy(path.resolve(this.configuration.mainData.assetsFolder), path.resolve(process.cwd() + path.sep + this.configuration.mainData.output + path.sep + this.configuration.mainData.assetsFolder), function (err) {
|
628 | if(err) {
|
629 | logger.error('Error during resources copy ', err);
|
630 | }
|
631 | });
|
632 | }
|
633 | }
|
634 |
|
635 | processResources() {
|
636 | logger.info('Copy main resources');
|
637 | let that = this;
|
638 | fs.copy(path.resolve(__dirname + '/../src/resources/'), path.resolve(process.cwd() + path.sep + this.configuration.mainData.output), function (err) {
|
639 | if(err) {
|
640 | logger.error('Error during resources copy ', err);
|
641 | }
|
642 | else {
|
643 | if (that.configuration.mainData.extTheme) {
|
644 | fs.copy(path.resolve(process.cwd() + path.sep + that.configuration.mainData.extTheme), path.resolve(process.cwd() + path.sep + that.configuration.mainData.output + '/styles/'), function (err) {
|
645 | if (err) {
|
646 | logger.error('Error during external styling theme copy ', err);
|
647 | } else {
|
648 | logger.info('External styling theme copy succeeded');
|
649 | that.processGraphs();
|
650 | }
|
651 | });
|
652 | }
|
653 | else {
|
654 | that.processGraphs();
|
655 | }
|
656 | }
|
657 | });
|
658 | }
|
659 |
|
660 | processGraphs() {
|
661 |
|
662 | const onComplete = () => {
|
663 | let finalTime = (new Date() - startTime) / 1000;
|
664 | logger.info('Documentation generated in ' + this.configuration.mainData.output + ' in ' + finalTime + ' seconds using ' + this.configuration.mainData.theme + ' theme');
|
665 | if (this.configuration.mainData.serve) {
|
666 | logger.info(`Serving documentation from ${this.configuration.mainData.output} at http://127.0.0.1:${this.configuration.mainData.port}`);
|
667 | this.runWebServer(this.configuration.mainData.output);
|
668 | }
|
669 | };
|
670 |
|
671 | if (this.configuration.mainData.disableGraph) {
|
672 |
|
673 | logger.info('Graph generation disabled');
|
674 | onComplete();
|
675 |
|
676 | } else {
|
677 |
|
678 | logger.info('Process main graph');
|
679 | let modules = this.configuration.mainData.modules,
|
680 | i = 0,
|
681 | len = modules.length,
|
682 | loop = () => {
|
683 | if( i <= len-1) {
|
684 | logger.info('Process module graph', modules[i].name);
|
685 | let finalPath = this.configuration.mainData.output;
|
686 | if(this.configuration.mainData.output.lastIndexOf('/') === -1) {
|
687 | finalPath += '/';
|
688 | }
|
689 | finalPath += 'modules/' + modules[i].name;
|
690 | $ngdengine.renderGraph(modules[i].file, finalPath, 'f', modules[i].name).then(() => {
|
691 | i++;
|
692 | loop();
|
693 | }, (errorMessage) => {
|
694 | logger.error(errorMessage);
|
695 | });
|
696 | } else {
|
697 | onComplete();
|
698 | }
|
699 | };
|
700 | let finalMainGraphPath = this.configuration.mainData.output;
|
701 | if(finalMainGraphPath.lastIndexOf('/') === -1) {
|
702 | finalMainGraphPath += '/';
|
703 | }
|
704 | finalMainGraphPath += 'graph';
|
705 | $ngdengine.renderGraph(this.configuration.mainData.tsconfig, path.resolve(finalMainGraphPath), 'p').then(() => {
|
706 | loop();
|
707 | }, (err) => {
|
708 | logger.error('Error during graph generation: ', err);
|
709 | });
|
710 |
|
711 | }
|
712 | }
|
713 |
|
714 | runWebServer(folder) {
|
715 | LiveServer.start({
|
716 | root: folder,
|
717 | open: this.configuration.mainData.open,
|
718 | quiet: true,
|
719 | logLevel: 0,
|
720 | port: this.configuration.mainData.port
|
721 | });
|
722 | }
|
723 |
|
724 | |
725 |
|
726 |
|
727 | get application():Application {
|
728 | return this;
|
729 | }
|
730 |
|
731 |
|
732 | get isCLI():boolean {
|
733 | return false;
|
734 | }
|
735 | }
|