node-tao 0.0.5 → 1.0.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 +30 -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 -44
- 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 -152
- 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 -16
- package/utils.d.ts.map +1 -1
- package/utils.js +51 -120
- 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,82 +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
|
-
|
|
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)) {
|
|
136
243
|
break;
|
|
137
244
|
}
|
|
138
|
-
|
|
245
|
+
cursor++;
|
|
246
|
+
}
|
|
247
|
+
if (inSingle) {
|
|
248
|
+
const error = (0, error_utils_1.buildErrorData)('Unclosed single quote', singleQuoteStart.line, rawExpression, errorType);
|
|
249
|
+
throw error;
|
|
139
250
|
}
|
|
140
|
-
(
|
|
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;
|
|
141
276
|
}
|
|
142
|
-
|
|
143
|
-
const escapedEndOfTemplate = (0, utils_1.escapeJSLiteral)(endOfTemplate);
|
|
144
|
-
compiledData.push(escapedEndOfTemplate);
|
|
145
|
-
return compiledData;
|
|
277
|
+
return tokens;
|
|
146
278
|
}
|
|
147
279
|
/**
|
|
148
280
|
* Render a template with data and helpers.
|
|
149
281
|
* @param template The path of your template to render.
|
|
150
|
-
* @param
|
|
151
|
-
* @param helpers The helpers functions to inject.
|
|
282
|
+
* @param dataOrHelpers The variables and helpers to inject.
|
|
152
283
|
*/
|
|
153
|
-
render(template,
|
|
284
|
+
render(template, dataOrHelpers = {}) {
|
|
154
285
|
const debugData = (0, init_1.initDebugData)();
|
|
155
286
|
if (typeof template !== 'string') {
|
|
156
287
|
const error = (0, error_utils_1.handleWrongTypeOfTemplate)(template);
|
|
157
288
|
const { errorHTML } = this.manageError(error, template, debugData);
|
|
158
289
|
return errorHTML;
|
|
159
290
|
}
|
|
160
|
-
const { views, extension, fileResolution
|
|
291
|
+
const { views, extension, fileResolution } = this.config;
|
|
161
292
|
const ɵɵstart = node_perf_hooks_1.performance.now();
|
|
162
293
|
let ɵɵcacheHit = false;
|
|
163
|
-
const pathWithExtension = (0,
|
|
294
|
+
const pathWithExtension = (0, validations_1.getPathWithExtension)(template, extension);
|
|
164
295
|
const filename = (0, utils_1.getFileName)(pathWithExtension);
|
|
165
296
|
const fullPath = (0, utils_1.getResolvedPath)(views, pathWithExtension, fileResolution);
|
|
166
297
|
this.parentTemplate = filename;
|
|
167
298
|
this.childrenStore.remove(this.parentTemplate);
|
|
168
|
-
|
|
169
|
-
development,
|
|
170
|
-
fullPath,
|
|
171
|
-
data,
|
|
172
|
-
helpers,
|
|
173
|
-
helpersStore: this.helpersStore,
|
|
174
|
-
templatePaths: this.templatePaths,
|
|
175
|
-
};
|
|
176
|
-
(0, utils_1.injectUserDataForVSCodeExtension)(injectedData);
|
|
177
|
-
if ((0, checks_1.isTemplateDynamicallyDefined)(template)) {
|
|
299
|
+
if ((0, validations_1.isTemplateDynamicallyDefined)(template)) {
|
|
178
300
|
const cachedTemplate = this.compiledStore.get(template);
|
|
179
301
|
if (cachedTemplate) {
|
|
180
302
|
ɵɵcacheHit = true;
|
|
181
303
|
const executeData = {
|
|
182
304
|
compiledContent: cachedTemplate,
|
|
183
|
-
|
|
184
|
-
helpers,
|
|
305
|
+
dataOrHelpers,
|
|
185
306
|
ɵɵstart,
|
|
186
307
|
filename: template,
|
|
187
308
|
ɵɵcacheHit,
|
|
@@ -196,8 +317,7 @@ class Tao {
|
|
|
196
317
|
}
|
|
197
318
|
const templateData = {
|
|
198
319
|
templateLoaded,
|
|
199
|
-
|
|
200
|
-
helpers,
|
|
320
|
+
dataOrHelpers,
|
|
201
321
|
ɵɵstart,
|
|
202
322
|
filename: template,
|
|
203
323
|
ɵɵcacheHit,
|
|
@@ -210,7 +330,7 @@ class Tao {
|
|
|
210
330
|
return errorHTML;
|
|
211
331
|
}
|
|
212
332
|
const files = (0, templates_access_1.checkAccessPermission)(this.templatePaths, fullPath);
|
|
213
|
-
if (
|
|
333
|
+
if (files.length !== 1) {
|
|
214
334
|
const error = (0, error_utils_1.handleNonUniqueFile)(files, filename);
|
|
215
335
|
const { errorHTML } = this.manageError(error, filename, debugData);
|
|
216
336
|
return errorHTML;
|
|
@@ -220,8 +340,7 @@ class Tao {
|
|
|
220
340
|
ɵɵcacheHit = true;
|
|
221
341
|
const executeData = {
|
|
222
342
|
compiledContent: cachedTemplate,
|
|
223
|
-
|
|
224
|
-
helpers,
|
|
343
|
+
dataOrHelpers,
|
|
225
344
|
ɵɵstart,
|
|
226
345
|
filename,
|
|
227
346
|
ɵɵcacheHit,
|
|
@@ -233,8 +352,7 @@ class Tao {
|
|
|
233
352
|
const compileData = {
|
|
234
353
|
filename,
|
|
235
354
|
fullPath: file,
|
|
236
|
-
|
|
237
|
-
helpers,
|
|
355
|
+
dataOrHelpers,
|
|
238
356
|
ɵɵstart,
|
|
239
357
|
ɵɵcacheHit,
|
|
240
358
|
};
|
|
@@ -243,34 +361,24 @@ class Tao {
|
|
|
243
361
|
/**
|
|
244
362
|
* Render a child component. Called inside the parent template.
|
|
245
363
|
*/
|
|
246
|
-
renderChild(template,
|
|
364
|
+
renderChild(template, dataOrHelpers = {}) {
|
|
247
365
|
const debugData = (0, init_1.initDebugData)();
|
|
248
366
|
if (typeof template !== 'string') {
|
|
249
367
|
const error = (0, error_utils_1.handleWrongTypeOfTemplate)(template);
|
|
250
368
|
const errorData = this.handleChildError(error, template, debugData);
|
|
251
369
|
return errorData;
|
|
252
370
|
}
|
|
253
|
-
const { views, extension, fileResolution
|
|
254
|
-
const pathWithExtension = (0,
|
|
371
|
+
const { views, extension, fileResolution } = this.config;
|
|
372
|
+
const pathWithExtension = (0, validations_1.getPathWithExtension)(template, extension);
|
|
255
373
|
const filename = (0, utils_1.getFileName)(pathWithExtension);
|
|
256
374
|
const fullPath = (0, utils_1.getResolvedPath)(views, pathWithExtension, fileResolution);
|
|
257
375
|
(0, metrics_1.updateChildrenStore)(this.childrenStore, filename, this.parentTemplate, this.config.development);
|
|
258
|
-
|
|
259
|
-
development,
|
|
260
|
-
fullPath,
|
|
261
|
-
data,
|
|
262
|
-
helpers,
|
|
263
|
-
helpersStore: this.helpersStore,
|
|
264
|
-
templatePaths: this.templatePaths,
|
|
265
|
-
};
|
|
266
|
-
(0, utils_1.injectUserDataForVSCodeExtension)(injectedData);
|
|
267
|
-
if ((0, checks_1.isTemplateDynamicallyDefined)(template)) {
|
|
376
|
+
if ((0, validations_1.isTemplateDynamicallyDefined)(template)) {
|
|
268
377
|
const cachedTemplate = this.compiledStore.get(template);
|
|
269
378
|
if (cachedTemplate) {
|
|
270
379
|
const executeData = {
|
|
271
380
|
compiledContent: cachedTemplate,
|
|
272
|
-
|
|
273
|
-
helpers,
|
|
381
|
+
dataOrHelpers,
|
|
274
382
|
filename: template,
|
|
275
383
|
};
|
|
276
384
|
return this.executeChildFunction(executeData, debugData);
|
|
@@ -283,14 +391,13 @@ class Tao {
|
|
|
283
391
|
}
|
|
284
392
|
const templateData = {
|
|
285
393
|
templateLoaded,
|
|
286
|
-
|
|
287
|
-
helpers,
|
|
394
|
+
dataOrHelpers,
|
|
288
395
|
filename: template,
|
|
289
396
|
};
|
|
290
397
|
return this.handleLoadedChildTemplate(templateData, debugData);
|
|
291
398
|
}
|
|
292
399
|
const files = (0, templates_access_1.checkAccessPermission)(this.templatePaths, fullPath);
|
|
293
|
-
if (
|
|
400
|
+
if (files.length !== 1) {
|
|
294
401
|
const error = (0, error_utils_1.handleNonUniqueFile)(files, filename);
|
|
295
402
|
const errorData = this.handleChildError(error, filename, debugData);
|
|
296
403
|
return errorData;
|
|
@@ -299,8 +406,7 @@ class Tao {
|
|
|
299
406
|
if (cachedTemplate) {
|
|
300
407
|
const executeData = {
|
|
301
408
|
compiledContent: cachedTemplate,
|
|
302
|
-
|
|
303
|
-
helpers,
|
|
409
|
+
dataOrHelpers,
|
|
304
410
|
filename,
|
|
305
411
|
};
|
|
306
412
|
return this.executeChildFunction(executeData, debugData);
|
|
@@ -309,17 +415,16 @@ class Tao {
|
|
|
309
415
|
const compileData = {
|
|
310
416
|
filename,
|
|
311
417
|
fullPath: file,
|
|
312
|
-
|
|
313
|
-
helpers,
|
|
418
|
+
dataOrHelpers,
|
|
314
419
|
};
|
|
315
420
|
return this.compileAndExecuteChild(compileData, debugData);
|
|
316
421
|
}
|
|
317
422
|
compileAndExecuteChild(compileData, debugData) {
|
|
318
|
-
const {
|
|
423
|
+
const { dataOrHelpers, filename, fullPath } = compileData;
|
|
319
424
|
try {
|
|
320
|
-
const templateFn = this.readChildFileAndGetCompiledFn(fullPath,
|
|
321
|
-
const
|
|
322
|
-
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);
|
|
323
428
|
return html;
|
|
324
429
|
}
|
|
325
430
|
catch (error) {
|
|
@@ -328,11 +433,11 @@ class Tao {
|
|
|
328
433
|
}
|
|
329
434
|
}
|
|
330
435
|
compileAndExecute(compileData, debugData) {
|
|
331
|
-
const {
|
|
436
|
+
const { dataOrHelpers, filename, fullPath, ɵɵstart, ɵɵcacheHit } = compileData;
|
|
332
437
|
try {
|
|
333
|
-
const templateFn = this.readFileAndGetCompiledFn(fullPath,
|
|
334
|
-
const
|
|
335
|
-
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);
|
|
336
441
|
return html;
|
|
337
442
|
}
|
|
338
443
|
catch (error) {
|
|
@@ -344,22 +449,21 @@ class Tao {
|
|
|
344
449
|
}
|
|
345
450
|
}
|
|
346
451
|
manageError(error, filename, debugData) {
|
|
347
|
-
// this.compiledStore.remove(filename); => pourquoi ?
|
|
348
452
|
error.filename = filename;
|
|
349
453
|
const errorData = this.handleErrorMessage(error, debugData);
|
|
350
|
-
console.error(new Error(`Error in ${filename}: ${errorData.message}`));
|
|
351
454
|
const errorHTML = this.initErrorTemplate(errorData);
|
|
352
455
|
errorData.errorHTML = errorHTML;
|
|
456
|
+
(0, error_utils_1.logger)('error', `Error in ${filename}: ${errorData.message} at line ${errorData.lineNumber}`);
|
|
353
457
|
return errorData;
|
|
354
458
|
}
|
|
355
459
|
executeChildFunction(executeData, debugData) {
|
|
356
|
-
const {
|
|
460
|
+
const { dataOrHelpers, filename, compiledContent } = executeData;
|
|
357
461
|
try {
|
|
358
|
-
const
|
|
359
|
-
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(data, helpers, this.helpersStore, compiledContent);
|
|
462
|
+
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(dataOrHelpers, this.helpersStore, compiledContent);
|
|
360
463
|
debugData.compiledAnonymousFnContent = contentReplaced;
|
|
361
464
|
const templateFn = (0, utils_1.compileChildToFunction)(contentReplaced);
|
|
362
|
-
const
|
|
465
|
+
const { data, helpers } = (0, utils_1.cloneData)(dataOrHelpers);
|
|
466
|
+
const html = templateFn.call(this, data, helpers);
|
|
363
467
|
return html;
|
|
364
468
|
}
|
|
365
469
|
catch (error) {
|
|
@@ -377,13 +481,13 @@ class Tao {
|
|
|
377
481
|
return errorData;
|
|
378
482
|
}
|
|
379
483
|
executeFunction(executeData, debugData) {
|
|
380
|
-
const {
|
|
484
|
+
const { dataOrHelpers, filename, ɵɵstart, compiledContent, ɵɵcacheHit } = executeData;
|
|
381
485
|
try {
|
|
382
|
-
const
|
|
383
|
-
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);
|
|
384
488
|
debugData.compiledAnonymousFnContent = contentReplaced;
|
|
385
489
|
const templateFn = (0, utils_1.compileToFunction)(contentReplaced);
|
|
386
|
-
const html = templateFn.call(this,
|
|
490
|
+
const html = templateFn.call(this, data, helpers, ɵɵstart, ɵɵcacheHit);
|
|
387
491
|
return html;
|
|
388
492
|
}
|
|
389
493
|
catch (error) {
|
|
@@ -395,7 +499,6 @@ class Tao {
|
|
|
395
499
|
}
|
|
396
500
|
}
|
|
397
501
|
handleErrorMessage(error, debugData) {
|
|
398
|
-
var _a;
|
|
399
502
|
const [finalMessage, fileContentPerLine, correctedLineNumber] = (0, error_utils_1.findOriginalLineNumberWithMessage)(error, debugData.compiledAnonymousFnContent, debugData.fileContent);
|
|
400
503
|
const errorData = {
|
|
401
504
|
filename: error.filename,
|
|
@@ -403,7 +506,7 @@ class Tao {
|
|
|
403
506
|
message: finalMessage,
|
|
404
507
|
lineNumber: correctedLineNumber,
|
|
405
508
|
// Execution error is the last possible error
|
|
406
|
-
type:
|
|
509
|
+
type: error.type ?? 'Execution Error',
|
|
407
510
|
isAChildError: false,
|
|
408
511
|
errorHTML: '',
|
|
409
512
|
};
|
|
@@ -412,38 +515,38 @@ class Tao {
|
|
|
412
515
|
initErrorTemplate(errorData) {
|
|
413
516
|
if (!this.config.development)
|
|
414
517
|
return '';
|
|
415
|
-
const templatesPath = node_path_1.default.join(__dirname
|
|
518
|
+
const templatesPath = node_path_1.default.join(__dirname);
|
|
416
519
|
const tao = new Tao({ views: templatesPath });
|
|
417
520
|
return tao.render('error', errorData);
|
|
418
521
|
}
|
|
419
|
-
compileChildAndCache(content, filename
|
|
420
|
-
const compiledContent = this.compileChild(content
|
|
522
|
+
compileChildAndCache(content, filename) {
|
|
523
|
+
const compiledContent = this.compileChild(content);
|
|
421
524
|
if (this.config.cache) {
|
|
422
525
|
this.compiledStore.set(filename, compiledContent);
|
|
423
526
|
}
|
|
424
527
|
return compiledContent;
|
|
425
528
|
}
|
|
426
|
-
compileAndCache(content, filename
|
|
427
|
-
const compiledContent = this.compile(content, filename
|
|
529
|
+
compileAndCache(content, filename) {
|
|
530
|
+
const compiledContent = this.compile(content, filename);
|
|
428
531
|
if (this.config.cache) {
|
|
429
532
|
this.compiledStore.set(filename, compiledContent);
|
|
430
533
|
}
|
|
431
534
|
return compiledContent;
|
|
432
535
|
}
|
|
433
|
-
readChildFileAndGetCompiledFn(resolvedPath,
|
|
536
|
+
readChildFileAndGetCompiledFn(resolvedPath, dataOrHelpers, filename, debugData) {
|
|
434
537
|
const content = this.readFile(resolvedPath);
|
|
435
538
|
debugData.fileContent = content;
|
|
436
|
-
const compiledContent = this.compileChildAndCache(content, filename
|
|
437
|
-
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(
|
|
539
|
+
const compiledContent = this.compileChildAndCache(content, filename);
|
|
540
|
+
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(dataOrHelpers, this.helpersStore, compiledContent);
|
|
438
541
|
debugData.compiledAnonymousFnContent = contentReplaced;
|
|
439
542
|
const templateFn = (0, utils_1.compileChildToFunction)(contentReplaced);
|
|
440
543
|
return templateFn;
|
|
441
544
|
}
|
|
442
|
-
readFileAndGetCompiledFn(resolvedPath,
|
|
545
|
+
readFileAndGetCompiledFn(resolvedPath, dataOrHelpers, filename, debugData) {
|
|
443
546
|
const content = this.readFile(resolvedPath);
|
|
444
547
|
debugData.fileContent = content;
|
|
445
|
-
const compiledContent = this.compileAndCache(content, filename
|
|
446
|
-
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(
|
|
548
|
+
const compiledContent = this.compileAndCache(content, filename);
|
|
549
|
+
const contentReplaced = (0, utils_1.injectDataAndHelpersInTemplate)(dataOrHelpers, this.helpersStore, compiledContent);
|
|
447
550
|
debugData.compiledAnonymousFnContent = contentReplaced;
|
|
448
551
|
const templateFn = (0, utils_1.compileToFunction)(contentReplaced);
|
|
449
552
|
return templateFn;
|
|
@@ -467,12 +570,12 @@ class Tao {
|
|
|
467
570
|
* Handle dynamically defined templates
|
|
468
571
|
*/
|
|
469
572
|
handleLoadedTemplate(templateData, debugData) {
|
|
470
|
-
const {
|
|
573
|
+
const { dataOrHelpers, filename, ɵɵstart, ɵɵcacheHit } = templateData;
|
|
471
574
|
try {
|
|
575
|
+
const { data, helpers } = (0, utils_1.cloneData)(dataOrHelpers);
|
|
472
576
|
const contentReplaced = this.compileLoadedTemplate(templateData, debugData);
|
|
473
577
|
const templateFn = (0, utils_1.compileToFunction)(contentReplaced);
|
|
474
|
-
const
|
|
475
|
-
const html = templateFn.call(this, immutableData, helpers, ɵɵstart, ɵɵcacheHit);
|
|
578
|
+
const html = templateFn.call(this, data, helpers, ɵɵstart, ɵɵcacheHit);
|
|
476
579
|
return html;
|
|
477
580
|
}
|
|
478
581
|
catch (error) {
|
|
@@ -484,12 +587,12 @@ class Tao {
|
|
|
484
587
|
}
|
|
485
588
|
}
|
|
486
589
|
handleLoadedChildTemplate(templateData, debugData) {
|
|
487
|
-
const {
|
|
590
|
+
const { dataOrHelpers, filename } = templateData;
|
|
488
591
|
try {
|
|
489
592
|
const contentReplaced = this.compileLoadedChildTemplate(templateData, debugData);
|
|
490
593
|
const templateFn = (0, utils_1.compileChildToFunction)(contentReplaced);
|
|
491
|
-
const
|
|
492
|
-
const html = templateFn.call(this,
|
|
594
|
+
const { data, helpers } = (0, utils_1.cloneData)(dataOrHelpers);
|
|
595
|
+
const html = templateFn.call(this, data, helpers);
|
|
493
596
|
return html;
|
|
494
597
|
}
|
|
495
598
|
catch (error) {
|
|
@@ -501,16 +604,16 @@ class Tao {
|
|
|
501
604
|
* Handle dynamically defined templates
|
|
502
605
|
*/
|
|
503
606
|
compileLoadedTemplate(templateData, debugData) {
|
|
504
|
-
const {
|
|
505
|
-
const compiledContent = this.compileAndCache(content, filename
|
|
506
|
-
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);
|
|
507
610
|
debugData.compiledAnonymousFnContent = contentReplaced;
|
|
508
611
|
return contentReplaced;
|
|
509
612
|
}
|
|
510
613
|
compileLoadedChildTemplate(templateData, debugData) {
|
|
511
|
-
const {
|
|
512
|
-
const compiledContent = this.compileChildAndCache(content, filename
|
|
513
|
-
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);
|
|
514
617
|
debugData.compiledAnonymousFnContent = contentReplaced;
|
|
515
618
|
return contentReplaced;
|
|
516
619
|
}
|
|
@@ -536,11 +639,11 @@ class Tao {
|
|
|
536
639
|
*/
|
|
537
640
|
loadTemplate(name, template) {
|
|
538
641
|
const duplicate = this.dynamictemplatesStore.get(name);
|
|
539
|
-
if (!(0,
|
|
642
|
+
if (!(0, validations_1.isTemplateDynamicallyDefined)(name)) {
|
|
540
643
|
throw new Error(`Dynamically loaded template ${name} should start with a '@'`);
|
|
541
644
|
}
|
|
542
645
|
if (duplicate) {
|
|
543
|
-
|
|
646
|
+
(0, error_utils_1.logger)('warn', `Duplicate template name ${name} provided. Template content has been erased.`);
|
|
544
647
|
}
|
|
545
648
|
this.dynamictemplatesStore.set(name, template);
|
|
546
649
|
}
|