1 | import * as Handlebars from 'handlebars';
|
2 | import * as path from 'path';
|
3 |
|
4 | import { logger } from '../../utils/logger';
|
5 | import FileEngine from './file.engine';
|
6 | import { HtmlEngineHelpers } from './html.engine.helpers';
|
7 |
|
8 | export class HtmlEngine {
|
9 | private cache: { page: string } = {} as any;
|
10 | private compiledPage;
|
11 |
|
12 | private precompiledMenu;
|
13 |
|
14 | private static instance: HtmlEngine;
|
15 | private constructor() {
|
16 | const helper = new HtmlEngineHelpers();
|
17 | helper.registerHelpers(Handlebars);
|
18 | }
|
19 | public static getInstance() {
|
20 | if (!HtmlEngine.instance) {
|
21 | HtmlEngine.instance = new HtmlEngine();
|
22 | }
|
23 | return HtmlEngine.instance;
|
24 | }
|
25 |
|
26 | public init(templatePath: string): Promise<void> {
|
27 | const partials = [
|
28 | 'overview',
|
29 | 'markdown',
|
30 | 'modules',
|
31 | 'module',
|
32 | 'component',
|
33 | 'controller',
|
34 | 'entity',
|
35 | 'component-detail',
|
36 | 'directive',
|
37 | 'injectable',
|
38 | 'interceptor',
|
39 | 'guard',
|
40 | 'pipe',
|
41 | 'class',
|
42 | 'interface',
|
43 | 'routes',
|
44 | 'index',
|
45 | 'index-misc',
|
46 | 'search-results',
|
47 | 'search-input',
|
48 | 'link-type',
|
49 | 'block-method',
|
50 | 'block-host-listener',
|
51 | 'block-enum',
|
52 | 'block-property',
|
53 | 'block-index',
|
54 | 'block-constructor',
|
55 | 'block-typealias',
|
56 | 'block-accessors',
|
57 | 'block-input',
|
58 | 'block-output',
|
59 | 'coverage-report',
|
60 | 'unit-test-report',
|
61 | 'miscellaneous-functions',
|
62 | 'miscellaneous-variables',
|
63 | 'miscellaneous-typealiases',
|
64 | 'miscellaneous-enumerations',
|
65 | 'additional-page',
|
66 | 'package-dependencies',
|
67 | 'package-properties'
|
68 | ];
|
69 | if (templatePath) {
|
70 | if (
|
71 | FileEngine.existsSync(path.resolve(process.cwd() + path.sep + templatePath)) ===
|
72 | false
|
73 | ) {
|
74 | logger.warn(
|
75 | 'Template path specificed but does not exist...using default templates'
|
76 | );
|
77 | }
|
78 | }
|
79 |
|
80 | return Promise.all(
|
81 | partials.map(partial => {
|
82 | let partialPath = this.determineTemplatePath(
|
83 | templatePath,
|
84 | 'partials/' + partial + '.hbs'
|
85 | );
|
86 | return FileEngine.get(partialPath).then(data =>
|
87 | Handlebars.registerPartial(partial, data)
|
88 | );
|
89 | })
|
90 | )
|
91 | .then(() => {
|
92 | let pagePath = this.determineTemplatePath(templatePath, 'page.hbs');
|
93 | return FileEngine.get(pagePath).then(data => {
|
94 | this.cache.page = data;
|
95 | this.compiledPage = Handlebars.compile(this.cache.page, {
|
96 | preventIndent: true,
|
97 | strict: true
|
98 | });
|
99 | });
|
100 | })
|
101 | .then(() => {
|
102 | let menuPath = this.determineTemplatePath(templatePath, 'partials/menu.hbs');
|
103 | return FileEngine.get(menuPath).then(menuTemplate => {
|
104 | this.precompiledMenu = Handlebars.compile(menuTemplate, {
|
105 | preventIndent: true,
|
106 | strict: true
|
107 | });
|
108 | });
|
109 | });
|
110 | }
|
111 |
|
112 | public renderMenu(templatePath, data) {
|
113 | let menuPath = this.determineTemplatePath(templatePath, 'partials/menu.hbs');
|
114 | return FileEngine.get(menuPath).then(menuTemplate => {
|
115 | data.menu = 'normal';
|
116 | return Handlebars.compile(menuTemplate, {
|
117 | preventIndent: true,
|
118 | strict: true
|
119 | })({ ...data });
|
120 | });
|
121 | }
|
122 |
|
123 | public render(mainData: any, page: any): string {
|
124 | let o = mainData;
|
125 | (Object as any).assign(o, page);
|
126 |
|
127 |
|
128 |
|
129 |
|
130 | return this.compiledPage({
|
131 | data: o
|
132 | });
|
133 | }
|
134 | private determineTemplatePath(templatePath: string, filePath: string): string {
|
135 | let outPath = path.resolve(__dirname + '/../src/templates/' + filePath);
|
136 | if (templatePath) {
|
137 | let testPath = path.resolve(
|
138 | process.cwd() + path.sep + templatePath + path.sep + filePath
|
139 | );
|
140 | outPath = FileEngine.existsSync(testPath) ? testPath : outPath;
|
141 | }
|
142 | return outPath;
|
143 | }
|
144 |
|
145 | public generateCoverageBadge(outputFolder, label, coverageData) {
|
146 | return FileEngine.get(
|
147 | path.resolve(__dirname + '/../src/templates/partials/coverage-badge.hbs')
|
148 | ).then(
|
149 | data => {
|
150 | let template: any = Handlebars.compile(data);
|
151 | coverageData.label = label;
|
152 | let result = template({
|
153 | data: coverageData
|
154 | });
|
155 | let testOutputDir = outputFolder.match(process.cwd());
|
156 | if (testOutputDir && testOutputDir.length > 0) {
|
157 | outputFolder = outputFolder.replace(process.cwd() + path.sep, '');
|
158 | }
|
159 |
|
160 | return FileEngine.write(
|
161 | outputFolder + path.sep + '/images/coverage-badge-' + label + '.svg',
|
162 | result
|
163 | ).catch(err => {
|
164 | logger.error('Error during coverage badge ' + label + ' file generation ', err);
|
165 | return Promise.reject(err);
|
166 | });
|
167 | },
|
168 | err => Promise.reject('Error during coverage badge generation')
|
169 | );
|
170 | }
|
171 | }
|
172 |
|
173 | export default HtmlEngine.getInstance();
|