@ololoepepe/template-renderer 0.1.49 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +5 -5
- package/src/index.js +14 -210
package/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
#
|
|
1
|
+
# eta-based template renderer
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ololoepepe/template-renderer",
|
|
3
|
-
"version": "0.1
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "eta-based template renderer",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"imports": {
|
|
7
7
|
"#src/*.js": "./src/*.js"
|
|
@@ -31,11 +31,11 @@
|
|
|
31
31
|
},
|
|
32
32
|
"homepage": "https://gitlab.void-walkers.com/libs/node.js/template-renderer#README",
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@ololoepepe/eslint-config": "^0.0.
|
|
34
|
+
"@ololoepepe/eslint-config": "^0.0.21",
|
|
35
35
|
"eslint": "8.57.0",
|
|
36
|
-
"mocha": "^11.
|
|
36
|
+
"mocha": "^11.7.5"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"
|
|
39
|
+
"eta": "^4.5.0"
|
|
40
40
|
}
|
|
41
41
|
}
|
package/src/index.js
CHANGED
|
@@ -1,228 +1,32 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {readFile} from 'node:fs/promises';
|
|
1
|
+
import {Eta} from 'eta';
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const RX_INCLUDE = /^(?<before>\s*)#include\s+'(?<include>[^']+)'(?<after>.*)$/u;
|
|
7
|
-
|
|
8
|
-
async function exists(path) {
|
|
9
|
-
return await new Promise(resolve => {
|
|
10
|
-
fs.exists(path, resolve);
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function _forEach(arr, callback) {
|
|
15
|
-
arr.forEach(callback);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function _renderTemplate(template, templateName, variables) {
|
|
19
|
-
if (!template) {
|
|
20
|
-
console.warn(`Template "${templateName}" not found`);
|
|
21
|
-
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const obj = {
|
|
26
|
-
_: {
|
|
27
|
-
forEach: _forEach
|
|
28
|
-
},
|
|
29
|
-
...variables
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
return template(obj);
|
|
3
|
+
function getTemplateName(name) {
|
|
4
|
+
return name.startsWith('@') ? name : `./${name}`;
|
|
33
5
|
}
|
|
34
6
|
|
|
35
7
|
export class TemplateRenderer {
|
|
36
|
-
#
|
|
37
|
-
#templatesDir = null;
|
|
38
|
-
#templateSettings = null;
|
|
39
|
-
#templateStringCache = new Map();
|
|
8
|
+
#eta = null;
|
|
40
9
|
|
|
41
10
|
constructor(templatesDir, templateSettings = {}) {
|
|
42
|
-
this.#
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (this.#templateCache.has(name)) {
|
|
50
|
-
return this.#templateCache.get(name);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const templateString = await this.#getTemplateStringRecursive(name);
|
|
54
|
-
|
|
55
|
-
return this.#getTemplate(name, templateString);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
getTemplateSync(name) {
|
|
59
|
-
if (this.#templateCache.has(name)) {
|
|
60
|
-
return this.#templateCache.get(name);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const templateString = this.#getTemplateStringRecursiveSync(name);
|
|
64
|
-
|
|
65
|
-
return this.#getTemplate(name, templateString);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async loadTemplate(name, text) {
|
|
69
|
-
if (this.#templateCache.has(name)) {
|
|
70
|
-
console.warn(`Template renderer: template "${name}" already exists, overriding it`);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const templateString = await this.#getTemplateStringRecursiveInternal(text);
|
|
74
|
-
|
|
75
|
-
this.#getTemplate(name, templateString);
|
|
11
|
+
this.#eta = new Eta({
|
|
12
|
+
autoEscape: false,
|
|
13
|
+
cache: true,
|
|
14
|
+
defaultExtension: '',
|
|
15
|
+
...templateSettings,
|
|
16
|
+
views: templatesDir
|
|
17
|
+
});
|
|
76
18
|
}
|
|
77
19
|
|
|
78
20
|
loadTemplateSync(name, text) {
|
|
79
|
-
|
|
80
|
-
console.warn(`Template renderer: template "${name}" already exists, overriding it`);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const templateString = this.#getTemplateStringRecursiveInternalSync(text);
|
|
84
|
-
|
|
85
|
-
this.#getTemplate(name, templateString);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
preloadSync(extension) {
|
|
89
|
-
this.#templateStringCache.clear();
|
|
90
|
-
this.#templateCache.clear();
|
|
91
|
-
|
|
92
|
-
this.#preloadRecursiveSync(extension);
|
|
21
|
+
this.#eta.loadTemplate(`@${name}`, text);
|
|
93
22
|
}
|
|
94
23
|
|
|
95
24
|
async renderTemplate(templateName, variables) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (typeof templateName === 'string') {
|
|
99
|
-
template = await this.getTemplate(templateName);
|
|
100
|
-
} else if (typeof templateName === 'function') {
|
|
101
|
-
template = templateName;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return _renderTemplate(template, templateName, variables);
|
|
25
|
+
return await this.#eta.renderAsync(getTemplateName(templateName), variables);
|
|
105
26
|
}
|
|
106
27
|
|
|
107
28
|
renderTemplateSync(templateName, variables) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (typeof templateName === 'string') {
|
|
111
|
-
template = this.getTemplateSync(templateName);
|
|
112
|
-
} else if (typeof templateName === 'function') {
|
|
113
|
-
template = templateName;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return _renderTemplate(template, templateName, variables);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
#getTemplate(name, templateString) {
|
|
120
|
-
if (!templateString) {
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const template = lodashTemplate(templateString, this.#templateSettings);
|
|
125
|
-
|
|
126
|
-
this.#templateCache.set(name, template);
|
|
127
|
-
|
|
128
|
-
return template;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
async #getTemplateStringRecursive(name) {
|
|
132
|
-
const templatePath = `${this.#templatesDir}/${name}`;
|
|
133
|
-
|
|
134
|
-
if (this.#templateStringCache.has(templatePath)) {
|
|
135
|
-
return this.#templateStringCache.get(templatePath);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const templateExists = await exists(templatePath);
|
|
139
|
-
|
|
140
|
-
if (!templateExists) {
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const templateString = await readFile(templatePath, 'utf8');
|
|
145
|
-
|
|
146
|
-
const result = await this.#getTemplateStringRecursiveInternal(templateString);
|
|
147
|
-
|
|
148
|
-
this.#templateStringCache.set(templatePath, result);
|
|
149
|
-
|
|
150
|
-
return result;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
async #getTemplateStringRecursiveInternal(templateString) {
|
|
154
|
-
const lines = templateString.split('\n');
|
|
155
|
-
|
|
156
|
-
for (let i = 0; i < lines.length; ++i) {
|
|
157
|
-
const line = lines[i];
|
|
158
|
-
|
|
159
|
-
const m = line.match(RX_INCLUDE);
|
|
160
|
-
|
|
161
|
-
if (m) {
|
|
162
|
-
const {after, before, include} = m.groups;
|
|
163
|
-
|
|
164
|
-
// eslint-disable-next-line no-await-in-loop
|
|
165
|
-
const part = await this.#getTemplateStringRecursive(include);
|
|
166
|
-
|
|
167
|
-
lines[i] = `${before}${part}${after}`;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return lines.join('\n');
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
#getTemplateStringRecursiveInternalSync(templateString) {
|
|
175
|
-
const lines = templateString.split('\n');
|
|
176
|
-
|
|
177
|
-
for (let i = 0; i < lines.length; ++i) {
|
|
178
|
-
const line = lines[i];
|
|
179
|
-
|
|
180
|
-
const m = line.match(RX_INCLUDE);
|
|
181
|
-
|
|
182
|
-
if (m) {
|
|
183
|
-
const {after, before, include} = m.groups;
|
|
184
|
-
|
|
185
|
-
const part = this.#getTemplateStringRecursiveSync(include);
|
|
186
|
-
|
|
187
|
-
lines[i] = `${before}${part}${after}`;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return lines.join('\n');
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
#getTemplateStringRecursiveSync(name) {
|
|
195
|
-
const templatePath = `${this.#templatesDir}/${name}`;
|
|
196
|
-
|
|
197
|
-
if (this.#templateStringCache.has(templatePath)) {
|
|
198
|
-
return this.#templateStringCache.get(templatePath);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const templateExists = fs.existsSync(templatePath);
|
|
202
|
-
|
|
203
|
-
if (!templateExists) {
|
|
204
|
-
return null;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const templateString = fs.readFileSync(templatePath, 'utf8');
|
|
208
|
-
|
|
209
|
-
const result = this.#getTemplateStringRecursiveInternalSync(templateString);
|
|
210
|
-
|
|
211
|
-
this.#templateStringCache.set(templatePath, result);
|
|
212
|
-
|
|
213
|
-
return result;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
#preloadRecursiveSync(extension, prefix = '') {
|
|
217
|
-
const path = `${this.#templatesDir}${prefix ? `/${prefix}` : ''}`;
|
|
218
|
-
|
|
219
|
-
const entries = fs.readdirSync(path);
|
|
220
|
-
|
|
221
|
-
entries.filter(entryName => entryName.endsWith(extension) && fs.statSync(`${path}/${entryName}`).isFile())
|
|
222
|
-
.forEach(fileName => this.getTemplateSync(`${prefix ? `${prefix}/` : ''}${fileName}`));
|
|
223
|
-
|
|
224
|
-
entries.filter(entryName => fs.statSync(`${path}/${entryName}`).isDirectory())
|
|
225
|
-
.forEach(dirName => this.#preloadRecursiveSync(extension, `${prefix ? `${prefix}/` : ''}${dirName}`));
|
|
29
|
+
return this.#eta.render(getTemplateName(templateName), variables);
|
|
226
30
|
}
|
|
227
31
|
}
|
|
228
32
|
|