@ololoepepe/template-renderer 0.1.41 → 0.1.43
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/package.json +14 -5
- package/src/index.js +229 -0
- package/index.js +0 -1
- package/src/template-renderer.js +0 -217
package/package.json
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ololoepepe/template-renderer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.43",
|
|
4
4
|
"description": "Lodash-based template renderer",
|
|
5
|
-
"main": "index.js",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"imports": {
|
|
7
|
+
"#src/*.js": "./src/*.js"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
6
10
|
"scripts": {
|
|
7
11
|
"lint": "eslint ./src",
|
|
8
12
|
"test": "mocha ./test/*"
|
|
@@ -10,6 +14,11 @@
|
|
|
10
14
|
"publishConfig": {
|
|
11
15
|
"registry": "https://registry.npmjs.com"
|
|
12
16
|
},
|
|
17
|
+
"files": [
|
|
18
|
+
"src",
|
|
19
|
+
"package.json",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
13
22
|
"repository": {
|
|
14
23
|
"type": "git",
|
|
15
24
|
"url": "git+ssh://git@ssh.gitlab.void-walkers.com:1022/libs/node.js/template-renderer.git"
|
|
@@ -21,12 +30,12 @@
|
|
|
21
30
|
},
|
|
22
31
|
"homepage": "https://gitlab.void-walkers.com/libs/node.js/template-renderer#README",
|
|
23
32
|
"devDependencies": {
|
|
24
|
-
"eslint": "
|
|
33
|
+
"@ololoepepe/eslint-config": "^0.0.16",
|
|
34
|
+
"eslint": "8.55.0",
|
|
25
35
|
"eslint-config-xo": "^0.43.1",
|
|
26
36
|
"mocha": "^10.2.0"
|
|
27
37
|
},
|
|
28
38
|
"dependencies": {
|
|
29
|
-
"
|
|
30
|
-
"lodash.template": "^4.4.0"
|
|
39
|
+
"lodash.template": "^4.5.0"
|
|
31
40
|
}
|
|
32
41
|
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import {readFile} from 'node:fs/promises';
|
|
3
|
+
|
|
4
|
+
import lodashTemplate from 'lodash.template';
|
|
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);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class TemplateRenderer {
|
|
36
|
+
#templateCache = new Map();
|
|
37
|
+
#templatesDir = null;
|
|
38
|
+
#templateSettings = null;
|
|
39
|
+
#templateStringCache = new Map();
|
|
40
|
+
|
|
41
|
+
constructor(templatesDir, templateSettings = {}) {
|
|
42
|
+
this.#templatesDir = templatesDir;
|
|
43
|
+
this.#templateCache = new Map();
|
|
44
|
+
this.#templateStringCache = new Map();
|
|
45
|
+
this.#templateSettings = templateSettings;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async getTemplate(name) {
|
|
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);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
loadTemplateSync(name, text) {
|
|
79
|
+
if (this.#templateCache.has(name)) {
|
|
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);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async renderTemplate(templateName, variables) {
|
|
96
|
+
let template = null;
|
|
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);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
renderTemplateSync(templateName, variables) {
|
|
108
|
+
let template = null;
|
|
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}`));
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export default TemplateRenderer;
|
package/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('./src/template-renderer');
|
package/src/template-renderer.js
DELETED
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const {exists, readFile} = require('fs-extra');
|
|
3
|
-
const _ = {
|
|
4
|
-
template: require('lodash.template')
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
const RX_INCLUDE = /^(\s*)#include\s+'([^']+)'(.*)$/;
|
|
8
|
-
|
|
9
|
-
function _forEach(arr, callback) {
|
|
10
|
-
arr.forEach(callback);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function _renderTemplate(template, templateName, variables) {
|
|
14
|
-
if (!template) {
|
|
15
|
-
console.warn(`Template "${templateName}" not found`);
|
|
16
|
-
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const obj = {
|
|
21
|
-
_: {
|
|
22
|
-
forEach: _forEach
|
|
23
|
-
},
|
|
24
|
-
...variables
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
return template(obj);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
class TemplateRenderer {
|
|
31
|
-
constructor(templatesDir, templateSettings = {}) {
|
|
32
|
-
this.templatesDir = templatesDir;
|
|
33
|
-
this._templateCache = new Map();
|
|
34
|
-
this._templateStringCache = new Map();
|
|
35
|
-
this._templateSettings = templateSettings;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async _getTemplateStringRecursiveInternal(templateString) {
|
|
39
|
-
const lines = templateString.split('\n');
|
|
40
|
-
|
|
41
|
-
for (let i = 0; i < lines.length; ++i) {
|
|
42
|
-
const line = lines[i];
|
|
43
|
-
|
|
44
|
-
const m = line.match(RX_INCLUDE);
|
|
45
|
-
|
|
46
|
-
if (m) {
|
|
47
|
-
// eslint-disable-next-line no-await-in-loop
|
|
48
|
-
const part = await this._getTemplateStringRecursive(m[2]);
|
|
49
|
-
|
|
50
|
-
lines[i] = `${m[1]}${part}${m[3]}`;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return lines.join('\n');
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async _getTemplateStringRecursive(name) {
|
|
58
|
-
const templatePath = `${this.templatesDir}/${name}`;
|
|
59
|
-
|
|
60
|
-
if (this._templateStringCache.has(templatePath)) {
|
|
61
|
-
return this._templateStringCache.get(templatePath);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const templateExists = await exists(templatePath);
|
|
65
|
-
|
|
66
|
-
if (!templateExists) {
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const templateString = await readFile(templatePath, 'utf8');
|
|
71
|
-
|
|
72
|
-
const result = await this._getTemplateStringRecursiveInternal(templateString);
|
|
73
|
-
|
|
74
|
-
this._templateStringCache.set(templatePath, result);
|
|
75
|
-
|
|
76
|
-
return result;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
_getTemplateStringRecursiveInternalSync(templateString) {
|
|
80
|
-
const lines = templateString.split('\n');
|
|
81
|
-
|
|
82
|
-
for (let i = 0; i < lines.length; ++i) {
|
|
83
|
-
const line = lines[i];
|
|
84
|
-
|
|
85
|
-
const m = line.match(RX_INCLUDE);
|
|
86
|
-
|
|
87
|
-
if (m) {
|
|
88
|
-
const part = this._getTemplateStringRecursiveSync(m[2]);
|
|
89
|
-
|
|
90
|
-
lines[i] = `${m[1]}${part}${m[3]}`;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return lines.join('\n');
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
_getTemplateStringRecursiveSync(name) {
|
|
98
|
-
const templatePath = `${this.templatesDir}/${name}`;
|
|
99
|
-
|
|
100
|
-
if (this._templateStringCache.has(templatePath)) {
|
|
101
|
-
return this._templateStringCache.get(templatePath);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const templateExists = fs.existsSync(templatePath);
|
|
105
|
-
|
|
106
|
-
if (!templateExists) {
|
|
107
|
-
return null;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const templateString = fs.readFileSync(templatePath, 'utf8');
|
|
111
|
-
|
|
112
|
-
const result = this._getTemplateStringRecursiveInternalSync(templateString);
|
|
113
|
-
|
|
114
|
-
this._templateStringCache.set(templatePath, result);
|
|
115
|
-
|
|
116
|
-
return result;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
_getTemplate(name, templateString) {
|
|
120
|
-
if (!templateString) {
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const template = _.template(templateString, this._templateSettings);
|
|
125
|
-
|
|
126
|
-
this._templateCache.set(name, template);
|
|
127
|
-
|
|
128
|
-
return template;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
_preloadRecursiveSync(extension, prefix = '') {
|
|
132
|
-
const path = `${this.templatesDir}${prefix ? `/${prefix}` : ''}`;
|
|
133
|
-
|
|
134
|
-
const entries = fs.readdirSync(path);
|
|
135
|
-
|
|
136
|
-
entries.filter(entryName => entryName.endsWith(extension) && fs.statSync(`${path}/${entryName}`).isFile())
|
|
137
|
-
.forEach(fileName => this.getTemplateSync(`${prefix ? `${prefix}/` : ''}${fileName}`));
|
|
138
|
-
|
|
139
|
-
entries.filter(entryName => fs.statSync(`${path}/${entryName}`).isDirectory())
|
|
140
|
-
.forEach(dirName => this._preloadRecursiveSync(extension, `${prefix ? `${prefix}/` : ''}${dirName}`));
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
async getTemplate(name) {
|
|
144
|
-
if (this._templateCache.has(name)) {
|
|
145
|
-
return this._templateCache.get(name);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const templateString = await this._getTemplateStringRecursive(name);
|
|
149
|
-
|
|
150
|
-
return this._getTemplate(name, templateString);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
getTemplateSync(name) {
|
|
154
|
-
if (this._templateCache.has(name)) {
|
|
155
|
-
return this._templateCache.get(name);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const templateString = this._getTemplateStringRecursiveSync(name);
|
|
159
|
-
|
|
160
|
-
return this._getTemplate(name, templateString);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
async loadTemplate(name, text) {
|
|
164
|
-
if (this._templateCache.has(name)) {
|
|
165
|
-
console.warn(`Template renderer: template "${name}" already exists, overriding it`);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const templateString = await this._getTemplateStringRecursiveInternal(text);
|
|
169
|
-
|
|
170
|
-
this._getTemplate(name, templateString);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
loadTemplateSync(name, text) {
|
|
174
|
-
if (this._templateCache.has(name)) {
|
|
175
|
-
console.warn(`Template renderer: template "${name}" already exists, overriding it`);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const templateString = this._getTemplateStringRecursiveInternalSync(text);
|
|
179
|
-
|
|
180
|
-
this._getTemplate(name, templateString);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
preloadSync(extension) {
|
|
184
|
-
this._templateStringCache.clear();
|
|
185
|
-
this._templateCache.clear();
|
|
186
|
-
|
|
187
|
-
this._preloadRecursiveSync(extension);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
async renderTemplate(templateName, variables) {
|
|
191
|
-
let template = null;
|
|
192
|
-
|
|
193
|
-
if (typeof templateName === 'string') {
|
|
194
|
-
template = await this.getTemplate(templateName);
|
|
195
|
-
} else if (typeof templateName === 'function') {
|
|
196
|
-
template = templateName;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
return _renderTemplate(template, templateName, variables);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
renderTemplateSync(templateName, variables) {
|
|
203
|
-
let template = null;
|
|
204
|
-
|
|
205
|
-
if (typeof templateName === 'string') {
|
|
206
|
-
template = this.getTemplateSync(templateName);
|
|
207
|
-
} else if (typeof templateName === 'function') {
|
|
208
|
-
template = templateName;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return _renderTemplate(template, templateName, variables);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
module.exports = {
|
|
216
|
-
TemplateRenderer
|
|
217
|
-
};
|