node-tao 0.0.4 → 1.0.0
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 +32 -14
- package/error-utils.d.ts +5 -3
- package/error-utils.d.ts.map +1 -1
- package/error-utils.js +27 -4
- package/error-utils.js.map +1 -1
- package/index.d.ts +1 -1
- package/index.d.ts.map +1 -1
- package/interfaces.d.ts +24 -33
- package/interfaces.d.ts.map +1 -1
- package/metrics.d.ts +5 -3
- package/metrics.d.ts.map +1 -1
- package/metrics.js +94 -34
- package/metrics.js.map +1 -1
- package/package.json +45 -45
- package/store.js +2 -4
- package/store.js.map +1 -1
- package/tao.d.ts +14 -7
- package/tao.d.ts.map +1 -1
- package/tao.js +255 -153
- package/tao.js.map +1 -1
- package/templates-access.d.ts +1 -3
- package/templates-access.d.ts.map +1 -1
- package/templates-access.js +2 -10
- package/templates-access.js.map +1 -1
- package/utils.d.ts +10 -17
- package/utils.d.ts.map +1 -1
- package/utils.js +37 -123
- package/utils.js.map +1 -1
- package/{checks.d.ts → validations.d.ts} +1 -1
- package/validations.d.ts.map +1 -0
- package/{checks.js → validations.js} +1 -1
- package/validations.js.map +1 -0
- package/checks.d.ts.map +0 -1
- package/checks.js.map +0 -1
- package/parsing-helpers.d.ts +0 -8
- package/parsing-helpers.d.ts.map +0 -1
- package/parsing-helpers.js +0 -62
- package/parsing-helpers.js.map +0 -1
- /package/{error/error.html → error.html} +0 -0
package/tao.js
CHANGED
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.Tao = void 0;
|
|
7
7
|
const default_config_1 = require("./default-config");
|
|
8
|
-
const
|
|
8
|
+
const validations_1 = require("./validations");
|
|
9
9
|
const templates_access_1 = require("./templates-access");
|
|
10
10
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
11
11
|
const utils_1 = require("./utils");
|
|
@@ -16,38 +16,40 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
16
16
|
const node_perf_hooks_1 = require("node:perf_hooks");
|
|
17
17
|
const metrics_1 = require("./metrics");
|
|
18
18
|
const init_1 = require("./init");
|
|
19
|
-
const parsing_helpers_1 = require("./parsing-helpers");
|
|
20
19
|
class Tao {
|
|
20
|
+
config;
|
|
21
|
+
templatePaths = [];
|
|
22
|
+
/**
|
|
23
|
+
* Stores already compiled templates.
|
|
24
|
+
*/
|
|
25
|
+
compiledStore = new store_1.Store();
|
|
26
|
+
/**
|
|
27
|
+
* Stores dynamically loaded templates.
|
|
28
|
+
*/
|
|
29
|
+
dynamictemplatesStore = new store_1.Store();
|
|
30
|
+
/**
|
|
31
|
+
* Stores global helpers.
|
|
32
|
+
*/
|
|
33
|
+
helpersStore = new store_1.Store();
|
|
34
|
+
/**
|
|
35
|
+
* Metrics - DX
|
|
36
|
+
*/
|
|
37
|
+
parentTemplate = '';
|
|
38
|
+
/**
|
|
39
|
+
* Metrics - DX
|
|
40
|
+
*/
|
|
41
|
+
childrenStore = new store_1.Store();
|
|
21
42
|
constructor(customConfig = {}) {
|
|
22
|
-
this.
|
|
23
|
-
this.prefixBuild = '';
|
|
24
|
-
/**
|
|
25
|
-
* Stores already compiled templates.
|
|
26
|
-
*/
|
|
27
|
-
this.compiledStore = new store_1.Store();
|
|
28
|
-
/**
|
|
29
|
-
* Stores dynamically loaded templates.
|
|
30
|
-
*/
|
|
31
|
-
this.dynamictemplatesStore = new store_1.Store();
|
|
32
|
-
/**
|
|
33
|
-
* Stores global helpers.
|
|
34
|
-
*/
|
|
35
|
-
this.helpersStore = new store_1.Store();
|
|
36
|
-
// Metrics - DX
|
|
37
|
-
this.parentTemplate = '';
|
|
38
|
-
// Metrics - DX
|
|
39
|
-
this.childrenStore = new store_1.Store();
|
|
40
|
-
this.config = Object.assign(Object.assign({}, default_config_1.defaultConfig), customConfig);
|
|
43
|
+
this.config = { ...default_config_1.defaultConfig, ...customConfig };
|
|
41
44
|
this.initializeConfig();
|
|
42
45
|
}
|
|
43
46
|
initializeConfig() {
|
|
44
47
|
const { views, extension, tags, parse } = this.config;
|
|
45
48
|
this.config.tags = (0, init_1.assignTags)(tags);
|
|
46
49
|
this.config.parse = (0, init_1.assignParse)(parse);
|
|
47
|
-
this.config.extension = (0,
|
|
48
|
-
(0,
|
|
49
|
-
(0,
|
|
50
|
-
this.prefixBuild = (0, utils_1.buildPrefixRegex)(this.config.parse);
|
|
50
|
+
this.config.extension = (0, validations_1.trimDotFromExtension)(extension);
|
|
51
|
+
(0, validations_1.checkOpeningAndClosingTag)(this.config.tags);
|
|
52
|
+
(0, validations_1.checkPrefixTemplateTags)(this.config.parse);
|
|
51
53
|
this.templatePaths = (0, templates_access_1.getFilesFromDirectory)(views, this.config.extension);
|
|
52
54
|
}
|
|
53
55
|
/**
|
|
@@ -66,8 +68,8 @@ class Tao {
|
|
|
66
68
|
};
|
|
67
69
|
return metricsData;
|
|
68
70
|
}
|
|
69
|
-
compileChild(content
|
|
70
|
-
const compiledAST = this.
|
|
71
|
+
compileChild(content) {
|
|
72
|
+
const compiledAST = this.templateLexer(content);
|
|
71
73
|
const result = `
|
|
72
74
|
${(0, utils_1.includeFn)()}
|
|
73
75
|
|
|
@@ -82,9 +84,9 @@ class Tao {
|
|
|
82
84
|
`;
|
|
83
85
|
return result;
|
|
84
86
|
}
|
|
85
|
-
compile(content, filename
|
|
87
|
+
compile(content, filename) {
|
|
86
88
|
const { development } = this.config;
|
|
87
|
-
const compiledAST = this.
|
|
89
|
+
const compiledAST = this.templateLexer(content);
|
|
88
90
|
this.childrenStore.set(this.parentTemplate, []);
|
|
89
91
|
const metricsData = this.getMetrics(filename);
|
|
90
92
|
const result = `
|
|
@@ -106,83 +108,201 @@ class Tao {
|
|
|
106
108
|
`;
|
|
107
109
|
return result;
|
|
108
110
|
}
|
|
109
|
-
|
|
111
|
+
/**
|
|
112
|
+
* A basic lexer covering most of the edge cases (quotes, comments, template literals, nested templates, etc.) to parse the template into an array of TemplateData containing the line information, start and end positions.
|
|
113
|
+
*/
|
|
114
|
+
templateLexer(rawExpression) {
|
|
110
115
|
const { parse, tags } = this.config;
|
|
111
|
-
const {
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
let
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
116
|
+
const { opening, closing } = tags;
|
|
117
|
+
const errorType = 'Parse Error';
|
|
118
|
+
const tokens = [];
|
|
119
|
+
let index = 0;
|
|
120
|
+
let line = 1;
|
|
121
|
+
const openingLength = opening.length;
|
|
122
|
+
const closingLength = closing.length;
|
|
123
|
+
const updatePosition = (char) => {
|
|
124
|
+
if (char === '\n')
|
|
125
|
+
line++;
|
|
126
|
+
};
|
|
127
|
+
while (index < rawExpression.length) {
|
|
128
|
+
const openIndex = rawExpression.indexOf(opening, index);
|
|
129
|
+
// Text after the last opening tag
|
|
130
|
+
if (openIndex === -1) {
|
|
131
|
+
const text = rawExpression.slice(index);
|
|
132
|
+
tokens.push({
|
|
133
|
+
type: null,
|
|
134
|
+
value: (0, utils_1.escapeJSLiteral)(text),
|
|
135
|
+
line,
|
|
136
|
+
startPos: index,
|
|
137
|
+
endPos: rawExpression.length,
|
|
138
|
+
});
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
// Text before an opening tag
|
|
142
|
+
if (openIndex > index) {
|
|
143
|
+
const text = rawExpression.slice(index, openIndex);
|
|
144
|
+
if (text.length > 0) {
|
|
145
|
+
tokens.push({
|
|
146
|
+
type: null,
|
|
147
|
+
value: (0, utils_1.escapeJSLiteral)(text),
|
|
148
|
+
line,
|
|
149
|
+
startPos: index,
|
|
150
|
+
endPos: openIndex,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// advance position until openIndex
|
|
155
|
+
while (index < openIndex) {
|
|
156
|
+
updatePosition(rawExpression[index]);
|
|
157
|
+
index++;
|
|
158
|
+
}
|
|
159
|
+
const blockLine = line;
|
|
160
|
+
let cursor = openIndex + openingLength;
|
|
161
|
+
const mode = (0, utils_1.getCurrentPrefixType)(rawExpression[cursor].trim(), parse);
|
|
162
|
+
if (mode !== null) {
|
|
163
|
+
cursor++;
|
|
164
|
+
}
|
|
165
|
+
const contentStart = cursor;
|
|
166
|
+
let inSingle = false;
|
|
167
|
+
let inDouble = false;
|
|
168
|
+
let inBacktick = false;
|
|
169
|
+
let inLineComment = false;
|
|
170
|
+
let inBlockComment = false;
|
|
171
|
+
let escaped = false;
|
|
172
|
+
let singleQuoteStart = null;
|
|
173
|
+
let doubleQuoteStart = null;
|
|
174
|
+
let backtickStart = null;
|
|
175
|
+
let blockCommentStart = null;
|
|
176
|
+
while (cursor < rawExpression.length) {
|
|
177
|
+
const char = rawExpression[cursor];
|
|
178
|
+
const next = rawExpression[cursor + 1];
|
|
179
|
+
updatePosition(char);
|
|
180
|
+
if (escaped) {
|
|
181
|
+
escaped = false;
|
|
182
|
+
cursor++;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (char === '\\') {
|
|
186
|
+
escaped = true;
|
|
187
|
+
cursor++;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
if (inLineComment) {
|
|
191
|
+
if (char === '\n')
|
|
192
|
+
inLineComment = false;
|
|
193
|
+
cursor++;
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
if (inBlockComment) {
|
|
197
|
+
if (char === '*' && next === '/') {
|
|
198
|
+
inBlockComment = false;
|
|
199
|
+
blockCommentStart = null;
|
|
200
|
+
cursor += 2;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
cursor++;
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (!inSingle && !inDouble && !inBacktick) {
|
|
207
|
+
if (char === '/' && next === '/') {
|
|
208
|
+
inLineComment = true;
|
|
209
|
+
cursor += 2;
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
if (char === '/' && next === '*') {
|
|
213
|
+
inBlockComment = true;
|
|
214
|
+
blockCommentStart = { line };
|
|
215
|
+
cursor += 2;
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (!inDouble && !inBacktick && char === "'") {
|
|
220
|
+
inSingle = !inSingle;
|
|
221
|
+
singleQuoteStart = inSingle ? { line } : null;
|
|
222
|
+
cursor++;
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
if (!inSingle && !inBacktick && char === '"') {
|
|
226
|
+
inDouble = !inDouble;
|
|
227
|
+
doubleQuoteStart = inDouble ? { line } : null;
|
|
228
|
+
cursor++;
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
if (!inSingle && !inDouble && char === '`') {
|
|
232
|
+
inBacktick = !inBacktick;
|
|
233
|
+
backtickStart = inBacktick ? { line } : null;
|
|
234
|
+
cursor++;
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
if (!inSingle &&
|
|
238
|
+
!inDouble &&
|
|
239
|
+
!inBacktick &&
|
|
240
|
+
!inLineComment &&
|
|
241
|
+
!inBlockComment &&
|
|
242
|
+
rawExpression.startsWith(closing, cursor)) {
|
|
137
243
|
break;
|
|
138
244
|
}
|
|
139
|
-
|
|
245
|
+
cursor++;
|
|
246
|
+
}
|
|
247
|
+
if (inSingle) {
|
|
248
|
+
const error = (0, error_utils_1.buildErrorData)('Unclosed single quote', singleQuoteStart.line, rawExpression, errorType);
|
|
249
|
+
throw error;
|
|
140
250
|
}
|
|
141
|
-
(
|
|
251
|
+
if (inDouble) {
|
|
252
|
+
const error = (0, error_utils_1.buildErrorData)('Unclosed double quote', doubleQuoteStart.line, rawExpression, errorType);
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
if (inBacktick) {
|
|
256
|
+
const error = (0, error_utils_1.buildErrorData)('Unclosed backtick', backtickStart.line, rawExpression, errorType);
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
259
|
+
if (inBlockComment) {
|
|
260
|
+
const error = (0, error_utils_1.buildErrorData)('Unclosed block comment', blockCommentStart.line, rawExpression, errorType);
|
|
261
|
+
throw error;
|
|
262
|
+
}
|
|
263
|
+
if (cursor >= rawExpression.length) {
|
|
264
|
+
const error = (0, error_utils_1.buildErrorData)(`Unclosed template block ${closing}`, line, rawExpression, errorType);
|
|
265
|
+
throw error;
|
|
266
|
+
}
|
|
267
|
+
const content = rawExpression.slice(contentStart, cursor).trim();
|
|
268
|
+
tokens.push({
|
|
269
|
+
type: mode,
|
|
270
|
+
value: content,
|
|
271
|
+
line: blockLine,
|
|
272
|
+
startPos: contentStart,
|
|
273
|
+
endPos: cursor,
|
|
274
|
+
});
|
|
275
|
+
index = cursor + closingLength;
|
|
142
276
|
}
|
|
143
|
-
|
|
144
|
-
const escapedEndOfTemplate = (0, utils_1.escapeJSLiteral)(endOfTemplate);
|
|
145
|
-
compiledData.push(escapedEndOfTemplate);
|
|
146
|
-
return compiledData;
|
|
277
|
+
return tokens;
|
|
147
278
|
}
|
|
148
279
|
/**
|
|
149
280
|
* Render a template with data and helpers.
|
|
150
281
|
* @param template The path of your template to render.
|
|
151
|
-
* @param
|
|
152
|
-
* @param helpers The helpers functions to inject.
|
|
282
|
+
* @param dataOrHelpers The variables and helpers to inject.
|
|
153
283
|
*/
|
|
154
|
-
render(template,
|
|
284
|
+
render(template, dataOrHelpers = {}) {
|
|
155
285
|
const debugData = (0, init_1.initDebugData)();
|
|
156
286
|
if (typeof template !== 'string') {
|
|
157
287
|
const error = (0, error_utils_1.handleWrongTypeOfTemplate)(template);
|
|
158
288
|
const { errorHTML } = this.manageError(error, template, debugData);
|
|
159
289
|
return errorHTML;
|
|
160
290
|
}
|
|
161
|
-
const { views, extension, fileResolution
|
|
291
|
+
const { views, extension, fileResolution } = this.config;
|
|
162
292
|
const ɵɵstart = node_perf_hooks_1.performance.now();
|
|
163
293
|
let ɵɵcacheHit = false;
|
|
164
|
-
const pathWithExtension = (0,
|
|
294
|
+
const pathWithExtension = (0, validations_1.getPathWithExtension)(template, extension);
|
|
165
295
|
const filename = (0, utils_1.getFileName)(pathWithExtension);
|
|
166
296
|
const fullPath = (0, utils_1.getResolvedPath)(views, pathWithExtension, fileResolution);
|
|
167
297
|
this.parentTemplate = filename;
|
|
168
298
|
this.childrenStore.remove(this.parentTemplate);
|
|
169
|
-
|
|
170
|
-
development,
|
|
171
|
-
fullPath,
|
|
172
|
-
data,
|
|
173
|
-
helpers,
|
|
174
|
-
helpersStore: this.helpersStore,
|
|
175
|
-
templatePaths: this.templatePaths,
|
|
176
|
-
};
|
|
177
|
-
(0, utils_1.injectUserDataForVSCodeExtension)(injectedData);
|
|
178
|
-
if ((0, checks_1.isTemplateDynamicallyDefined)(template)) {
|
|
299
|
+
if ((0, validations_1.isTemplateDynamicallyDefined)(template)) {
|
|
179
300
|
const cachedTemplate = this.compiledStore.get(template);
|
|
180
301
|
if (cachedTemplate) {
|
|
181
302
|
ɵɵcacheHit = true;
|
|
182
303
|
const executeData = {
|
|
183
304
|
compiledContent: cachedTemplate,
|
|
184
|
-
|
|
185
|
-
helpers,
|
|
305
|
+
dataOrHelpers,
|
|
186
306
|
ɵɵstart,
|
|
187
307
|
filename: template,
|
|
188
308
|
ɵɵcacheHit,
|
|
@@ -197,8 +317,7 @@ class Tao {
|
|
|
197
317
|
}
|
|
198
318
|
const templateData = {
|
|
199
319
|
templateLoaded,
|
|
200
|
-
|
|
201
|
-
helpers,
|
|
320
|
+
dataOrHelpers,
|
|
202
321
|
ɵɵstart,
|
|
203
322
|
filename: template,
|
|
204
323
|
ɵɵcacheHit,
|
|
@@ -211,7 +330,7 @@ class Tao {
|
|
|
211
330
|
return errorHTML;
|
|
212
331
|
}
|
|
213
332
|
const files = (0, templates_access_1.checkAccessPermission)(this.templatePaths, fullPath);
|
|
214
|
-
if (
|
|
333
|
+
if (files.length !== 1) {
|
|
215
334
|
const error = (0, error_utils_1.handleNonUniqueFile)(files, filename);
|
|
216
335
|
const { errorHTML } = this.manageError(error, filename, debugData);
|
|
217
336
|
return errorHTML;
|
|
@@ -221,8 +340,7 @@ class Tao {
|
|
|
221
340
|
ɵɵcacheHit = true;
|
|
222
341
|
const executeData = {
|
|
223
342
|
compiledContent: cachedTemplate,
|
|
224
|
-
|
|
225
|
-
helpers,
|
|
343
|
+
dataOrHelpers,
|
|
226
344
|
ɵɵstart,
|
|
227
345
|
filename,
|
|
228
346
|
ɵɵcacheHit,
|
|
@@ -234,8 +352,7 @@ class Tao {
|
|
|
234
352
|
const compileData = {
|
|
235
353
|
filename,
|
|
236
354
|
fullPath: file,
|
|
237
|
-
|
|
238
|
-
helpers,
|
|
355
|
+
dataOrHelpers,
|
|
239
356
|
ɵɵstart,
|
|
240
357
|
ɵɵcacheHit,
|
|
241
358
|
};
|
|
@@ -244,34 +361,24 @@ class Tao {
|
|
|
244
361
|
/**
|
|
245
362
|
* Render a child component. Called inside the parent template.
|
|
246
363
|
*/
|
|
247
|
-
renderChild(template,
|
|
364
|
+
renderChild(template, dataOrHelpers = {}) {
|
|
248
365
|
const debugData = (0, init_1.initDebugData)();
|
|
249
366
|
if (typeof template !== 'string') {
|
|
250
367
|
const error = (0, error_utils_1.handleWrongTypeOfTemplate)(template);
|
|
251
368
|
const errorData = this.handleChildError(error, template, debugData);
|
|
252
369
|
return errorData;
|
|
253
370
|
}
|
|
254
|
-
const { views, extension, fileResolution
|
|
255
|
-
const pathWithExtension = (0,
|
|
371
|
+
const { views, extension, fileResolution } = this.config;
|
|
372
|
+
const pathWithExtension = (0, validations_1.getPathWithExtension)(template, extension);
|
|
256
373
|
const filename = (0, utils_1.getFileName)(pathWithExtension);
|
|
257
374
|
const fullPath = (0, utils_1.getResolvedPath)(views, pathWithExtension, fileResolution);
|
|
258
375
|
(0, metrics_1.updateChildrenStore)(this.childrenStore, filename, this.parentTemplate, this.config.development);
|
|
259
|
-
|
|
260
|
-
development,
|
|
261
|
-
fullPath,
|
|
262
|
-
data,
|
|
263
|
-
helpers,
|
|
264
|
-
helpersStore: this.helpersStore,
|
|
265
|
-
templatePaths: this.templatePaths,
|
|
266
|
-
};
|
|
267
|
-
(0, utils_1.injectUserDataForVSCodeExtension)(injectedData);
|
|
268
|
-
if ((0, checks_1.isTemplateDynamicallyDefined)(template)) {
|
|
376
|
+
if ((0, validations_1.isTemplateDynamicallyDefined)(template)) {
|
|
269
377
|
const cachedTemplate = this.compiledStore.get(template);
|
|
270
378
|
if (cachedTemplate) {
|
|
271
379
|
const executeData = {
|
|
272
380
|
compiledContent: cachedTemplate,
|
|
273
|
-
|
|
274
|
-
helpers,
|
|
381
|
+
dataOrHelpers,
|
|
275
382
|
filename: template,
|
|
276
383
|
};
|
|
277
384
|
return this.executeChildFunction(executeData, debugData);
|
|
@@ -284,14 +391,13 @@ class Tao {
|
|
|
284
391
|
}
|
|
285
392
|
const templateData = {
|
|
286
393
|
templateLoaded,
|
|
287
|
-
|
|
288
|
-
helpers,
|
|
394
|
+
dataOrHelpers,
|
|
289
395
|
filename: template,
|
|
290
396
|
};
|
|
291
397
|
return this.handleLoadedChildTemplate(templateData, debugData);
|
|
292
398
|
}
|
|
293
399
|
const files = (0, templates_access_1.checkAccessPermission)(this.templatePaths, fullPath);
|
|
294
|
-
if (
|
|
400
|
+
if (files.length !== 1) {
|
|
295
401
|
const error = (0, error_utils_1.handleNonUniqueFile)(files, filename);
|
|
296
402
|
const errorData = this.handleChildError(error, filename, debugData);
|
|
297
403
|
return errorData;
|
|
@@ -300,8 +406,7 @@ class Tao {
|
|
|
300
406
|
if (cachedTemplate) {
|
|
301
407
|
const executeData = {
|
|
302
408
|
compiledContent: cachedTemplate,
|
|
303
|
-
|
|
304
|
-
helpers,
|
|
409
|
+
dataOrHelpers,
|
|
305
410
|
filename,
|
|
306
411
|
};
|
|
307
412
|
return this.executeChildFunction(executeData, debugData);
|
|
@@ -310,17 +415,16 @@ class Tao {
|
|
|
310
415
|
const compileData = {
|
|
311
416
|
filename,
|
|
312
417
|
fullPath: file,
|
|
313
|
-
|
|
314
|
-
helpers,
|
|
418
|
+
dataOrHelpers,
|
|
315
419
|
};
|
|
316
420
|
return this.compileAndExecuteChild(compileData, debugData);
|
|
317
421
|
}
|
|
318
422
|
compileAndExecuteChild(compileData, debugData) {
|
|
319
|
-
const {
|
|
423
|
+
const { dataOrHelpers, filename, fullPath } = compileData;
|
|
320
424
|
try {
|
|
321
|
-
const templateFn = this.readChildFileAndGetCompiledFn(fullPath,
|
|
322
|
-
const
|
|
323
|
-
const html = templateFn.call(this,
|
|
425
|
+
const templateFn = this.readChildFileAndGetCompiledFn(fullPath, dataOrHelpers, filename, debugData);
|
|
426
|
+
const { data, helpers } = (0, utils_1.cloneData)(dataOrHelpers);
|
|
427
|
+
const html = templateFn.call(this, data, helpers);
|
|
324
428
|
return html;
|
|
325
429
|
}
|
|
326
430
|
catch (error) {
|
|
@@ -329,11 +433,11 @@ class Tao {
|
|
|
329
433
|
}
|
|
330
434
|
}
|
|
331
435
|
compileAndExecute(compileData, debugData) {
|
|
332
|
-
const {
|
|
436
|
+
const { dataOrHelpers, filename, fullPath, ɵɵstart, ɵɵcacheHit } = compileData;
|
|
333
437
|
try {
|
|
334
|
-
const templateFn = this.readFileAndGetCompiledFn(fullPath,
|
|
335
|
-
const
|
|
336
|
-
const html = templateFn.call(this,
|
|
438
|
+
const templateFn = this.readFileAndGetCompiledFn(fullPath, dataOrHelpers, filename, debugData);
|
|
439
|
+
const { data, helpers } = (0, utils_1.cloneData)(dataOrHelpers);
|
|
440
|
+
const html = templateFn.call(this, data, helpers, ɵɵstart, ɵɵcacheHit);
|
|
337
441
|
return html;
|
|
338
442
|
}
|
|
339
443
|
catch (error) {
|
|
@@ -345,22 +449,21 @@ class Tao {
|
|
|
345
449
|
}
|
|
346
450
|
}
|
|
347
451
|
manageError(error, filename, debugData) {
|
|
348
|
-
// this.compiledStore.remove(filename); => pourquoi ?
|
|
349
452
|
error.filename = filename;
|
|
350
453
|
const errorData = this.handleErrorMessage(error, debugData);
|
|
351
|
-
console.error(new Error(`Error in ${filename}: ${errorData.message}`));
|
|
352
454
|
const errorHTML = this.initErrorTemplate(errorData);
|
|
353
455
|
errorData.errorHTML = errorHTML;
|
|
456
|
+
(0, error_utils_1.logger)('error', `Error in ${filename}: ${errorData.message} at line ${errorData.lineNumber}`);
|
|
354
457
|
return errorData;
|
|
355
458
|
}
|
|
356
459
|
executeChildFunction(executeData, debugData) {
|
|
357
|
-
const {
|
|
460
|
+
const { dataOrHelpers, filename, compiledContent } = executeData;
|
|
358
461
|
try {
|
|
359
|
-
const
|
|
360
|
-
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(data, helpers, this.helpersStore, compiledContent);
|
|
462
|
+
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(dataOrHelpers, this.helpersStore, compiledContent);
|
|
361
463
|
debugData.compiledAnonymousFnContent = contentReplaced;
|
|
362
464
|
const templateFn = (0, utils_1.compileChildToFunction)(contentReplaced);
|
|
363
|
-
const
|
|
465
|
+
const { data, helpers } = (0, utils_1.cloneData)(dataOrHelpers);
|
|
466
|
+
const html = templateFn.call(this, data, helpers);
|
|
364
467
|
return html;
|
|
365
468
|
}
|
|
366
469
|
catch (error) {
|
|
@@ -378,13 +481,13 @@ class Tao {
|
|
|
378
481
|
return errorData;
|
|
379
482
|
}
|
|
380
483
|
executeFunction(executeData, debugData) {
|
|
381
|
-
const {
|
|
484
|
+
const { dataOrHelpers, filename, ɵɵstart, compiledContent, ɵɵcacheHit } = executeData;
|
|
382
485
|
try {
|
|
383
|
-
const
|
|
384
|
-
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(
|
|
486
|
+
const { data, helpers } = (0, utils_1.cloneData)(dataOrHelpers);
|
|
487
|
+
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(dataOrHelpers, this.helpersStore, compiledContent);
|
|
385
488
|
debugData.compiledAnonymousFnContent = contentReplaced;
|
|
386
489
|
const templateFn = (0, utils_1.compileToFunction)(contentReplaced);
|
|
387
|
-
const html = templateFn.call(this,
|
|
490
|
+
const html = templateFn.call(this, data, helpers, ɵɵstart, ɵɵcacheHit);
|
|
388
491
|
return html;
|
|
389
492
|
}
|
|
390
493
|
catch (error) {
|
|
@@ -396,7 +499,6 @@ class Tao {
|
|
|
396
499
|
}
|
|
397
500
|
}
|
|
398
501
|
handleErrorMessage(error, debugData) {
|
|
399
|
-
var _a;
|
|
400
502
|
const [finalMessage, fileContentPerLine, correctedLineNumber] = (0, error_utils_1.findOriginalLineNumberWithMessage)(error, debugData.compiledAnonymousFnContent, debugData.fileContent);
|
|
401
503
|
const errorData = {
|
|
402
504
|
filename: error.filename,
|
|
@@ -404,7 +506,7 @@ class Tao {
|
|
|
404
506
|
message: finalMessage,
|
|
405
507
|
lineNumber: correctedLineNumber,
|
|
406
508
|
// Execution error is the last possible error
|
|
407
|
-
type:
|
|
509
|
+
type: error.type ?? 'Execution Error',
|
|
408
510
|
isAChildError: false,
|
|
409
511
|
errorHTML: '',
|
|
410
512
|
};
|
|
@@ -413,38 +515,38 @@ class Tao {
|
|
|
413
515
|
initErrorTemplate(errorData) {
|
|
414
516
|
if (!this.config.development)
|
|
415
517
|
return '';
|
|
416
|
-
const templatesPath = node_path_1.default.join(__dirname
|
|
518
|
+
const templatesPath = node_path_1.default.join(__dirname);
|
|
417
519
|
const tao = new Tao({ views: templatesPath });
|
|
418
520
|
return tao.render('error', errorData);
|
|
419
521
|
}
|
|
420
|
-
compileChildAndCache(content, filename
|
|
421
|
-
const compiledContent = this.compileChild(content
|
|
522
|
+
compileChildAndCache(content, filename) {
|
|
523
|
+
const compiledContent = this.compileChild(content);
|
|
422
524
|
if (this.config.cache) {
|
|
423
525
|
this.compiledStore.set(filename, compiledContent);
|
|
424
526
|
}
|
|
425
527
|
return compiledContent;
|
|
426
528
|
}
|
|
427
|
-
compileAndCache(content, filename
|
|
428
|
-
const compiledContent = this.compile(content, filename
|
|
529
|
+
compileAndCache(content, filename) {
|
|
530
|
+
const compiledContent = this.compile(content, filename);
|
|
429
531
|
if (this.config.cache) {
|
|
430
532
|
this.compiledStore.set(filename, compiledContent);
|
|
431
533
|
}
|
|
432
534
|
return compiledContent;
|
|
433
535
|
}
|
|
434
|
-
readChildFileAndGetCompiledFn(resolvedPath,
|
|
536
|
+
readChildFileAndGetCompiledFn(resolvedPath, dataOrHelpers, filename, debugData) {
|
|
435
537
|
const content = this.readFile(resolvedPath);
|
|
436
538
|
debugData.fileContent = content;
|
|
437
|
-
const compiledContent = this.compileChildAndCache(content, filename
|
|
438
|
-
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(
|
|
539
|
+
const compiledContent = this.compileChildAndCache(content, filename);
|
|
540
|
+
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(dataOrHelpers, this.helpersStore, compiledContent);
|
|
439
541
|
debugData.compiledAnonymousFnContent = contentReplaced;
|
|
440
542
|
const templateFn = (0, utils_1.compileChildToFunction)(contentReplaced);
|
|
441
543
|
return templateFn;
|
|
442
544
|
}
|
|
443
|
-
readFileAndGetCompiledFn(resolvedPath,
|
|
545
|
+
readFileAndGetCompiledFn(resolvedPath, dataOrHelpers, filename, debugData) {
|
|
444
546
|
const content = this.readFile(resolvedPath);
|
|
445
547
|
debugData.fileContent = content;
|
|
446
|
-
const compiledContent = this.compileAndCache(content, filename
|
|
447
|
-
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(
|
|
548
|
+
const compiledContent = this.compileAndCache(content, filename);
|
|
549
|
+
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(dataOrHelpers, this.helpersStore, compiledContent);
|
|
448
550
|
debugData.compiledAnonymousFnContent = contentReplaced;
|
|
449
551
|
const templateFn = (0, utils_1.compileToFunction)(contentReplaced);
|
|
450
552
|
return templateFn;
|
|
@@ -468,12 +570,12 @@ class Tao {
|
|
|
468
570
|
* Handle dynamically defined templates
|
|
469
571
|
*/
|
|
470
572
|
handleLoadedTemplate(templateData, debugData) {
|
|
471
|
-
const {
|
|
573
|
+
const { dataOrHelpers, filename, ɵɵstart, ɵɵcacheHit } = templateData;
|
|
472
574
|
try {
|
|
575
|
+
const { data, helpers } = (0, utils_1.cloneData)(dataOrHelpers);
|
|
473
576
|
const contentReplaced = this.compileLoadedTemplate(templateData, debugData);
|
|
474
577
|
const templateFn = (0, utils_1.compileToFunction)(contentReplaced);
|
|
475
|
-
const
|
|
476
|
-
const html = templateFn.call(this, immutableData, helpers, ɵɵstart, ɵɵcacheHit);
|
|
578
|
+
const html = templateFn.call(this, data, helpers, ɵɵstart, ɵɵcacheHit);
|
|
477
579
|
return html;
|
|
478
580
|
}
|
|
479
581
|
catch (error) {
|
|
@@ -485,12 +587,12 @@ class Tao {
|
|
|
485
587
|
}
|
|
486
588
|
}
|
|
487
589
|
handleLoadedChildTemplate(templateData, debugData) {
|
|
488
|
-
const {
|
|
590
|
+
const { dataOrHelpers, filename } = templateData;
|
|
489
591
|
try {
|
|
490
592
|
const contentReplaced = this.compileLoadedChildTemplate(templateData, debugData);
|
|
491
593
|
const templateFn = (0, utils_1.compileChildToFunction)(contentReplaced);
|
|
492
|
-
const
|
|
493
|
-
const html = templateFn.call(this,
|
|
594
|
+
const { data, helpers } = (0, utils_1.cloneData)(dataOrHelpers);
|
|
595
|
+
const html = templateFn.call(this, data, helpers);
|
|
494
596
|
return html;
|
|
495
597
|
}
|
|
496
598
|
catch (error) {
|
|
@@ -502,16 +604,16 @@ class Tao {
|
|
|
502
604
|
* Handle dynamically defined templates
|
|
503
605
|
*/
|
|
504
606
|
compileLoadedTemplate(templateData, debugData) {
|
|
505
|
-
const {
|
|
506
|
-
const compiledContent = this.compileAndCache(content, filename
|
|
507
|
-
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(
|
|
607
|
+
const { dataOrHelpers, filename, templateLoaded: content } = templateData;
|
|
608
|
+
const compiledContent = this.compileAndCache(content, filename);
|
|
609
|
+
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(dataOrHelpers, this.helpersStore, compiledContent);
|
|
508
610
|
debugData.compiledAnonymousFnContent = contentReplaced;
|
|
509
611
|
return contentReplaced;
|
|
510
612
|
}
|
|
511
613
|
compileLoadedChildTemplate(templateData, debugData) {
|
|
512
|
-
const {
|
|
513
|
-
const compiledContent = this.compileChildAndCache(content, filename
|
|
514
|
-
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(
|
|
614
|
+
const { dataOrHelpers, filename, templateLoaded: content } = templateData;
|
|
615
|
+
const compiledContent = this.compileChildAndCache(content, filename);
|
|
616
|
+
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(dataOrHelpers, this.helpersStore, compiledContent);
|
|
515
617
|
debugData.compiledAnonymousFnContent = contentReplaced;
|
|
516
618
|
return contentReplaced;
|
|
517
619
|
}
|
|
@@ -537,11 +639,11 @@ class Tao {
|
|
|
537
639
|
*/
|
|
538
640
|
loadTemplate(name, template) {
|
|
539
641
|
const duplicate = this.dynamictemplatesStore.get(name);
|
|
540
|
-
if (!(0,
|
|
642
|
+
if (!(0, validations_1.isTemplateDynamicallyDefined)(name)) {
|
|
541
643
|
throw new Error(`Dynamically loaded template ${name} should start with a '@'`);
|
|
542
644
|
}
|
|
543
645
|
if (duplicate) {
|
|
544
|
-
|
|
646
|
+
(0, error_utils_1.logger)('warn', `Duplicate template name ${name} provided. Template content has been erased.`);
|
|
545
647
|
}
|
|
546
648
|
this.dynamictemplatesStore.set(name, template);
|
|
547
649
|
}
|