@kosatyi/ejs 0.0.96 → 0.0.98
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/dist/cjs/browser.js +923 -649
- package/dist/cjs/bundler.js +28 -22
- package/dist/cjs/element.js +8 -1
- package/dist/cjs/index.js +932 -657
- package/dist/cjs/worker.js +919 -647
- package/dist/esm/browser.js +691 -609
- package/dist/esm/bundler.js +21 -15
- package/dist/esm/element.js +12 -2
- package/dist/esm/index.js +700 -618
- package/dist/esm/worker.js +707 -626
- package/dist/umd/browser.js +1136 -862
- package/dist/umd/browser.min.js +1 -1
- package/dist/umd/element.js +8 -1
- package/dist/umd/element.min.js +1 -1
- package/dist/umd/index.js +1170 -895
- package/dist/umd/index.min.js +1 -1
- package/dist/umd/worker.js +919 -647
- package/dist/umd/worker.min.js +1 -1
- package/package.json +1 -1
- package/types/global.d.ts +4 -0
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
3
|
|
|
4
4
|
const typeProp = function () {
|
|
5
5
|
const args = [].slice.call(arguments);
|
|
@@ -60,13 +60,22 @@ const symbols = (string) => {
|
|
|
60
60
|
|
|
61
61
|
const safeValue = (value, escape) => {
|
|
62
62
|
const check = value;
|
|
63
|
-
return check == null
|
|
63
|
+
return check == null
|
|
64
|
+
? ''
|
|
65
|
+
: Boolean(escape) === true
|
|
66
|
+
? entities(check)
|
|
67
|
+
: check
|
|
64
68
|
};
|
|
65
69
|
|
|
66
70
|
const instanceOf = (object, instance) => {
|
|
67
71
|
return Boolean(object instanceof instance)
|
|
68
72
|
};
|
|
69
73
|
|
|
74
|
+
const assertInstanceOf = (object, instance) => {
|
|
75
|
+
if (instanceOf(object, instance) === false)
|
|
76
|
+
throw new TypeError(`${object} in not instance of ${instance}`)
|
|
77
|
+
};
|
|
78
|
+
|
|
70
79
|
const getPath = (context, name, strict) => {
|
|
71
80
|
let data = context;
|
|
72
81
|
let chunks = String(name).split('.');
|
|
@@ -88,6 +97,14 @@ const getPath = (context, name, strict) => {
|
|
|
88
97
|
return [data, prop]
|
|
89
98
|
};
|
|
90
99
|
|
|
100
|
+
const bindContext = (object, methods = []) => {
|
|
101
|
+
methods.forEach((name) => {
|
|
102
|
+
if (name in object) {
|
|
103
|
+
object[name] = object[name].bind(object);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
};
|
|
107
|
+
|
|
91
108
|
const ext = (path, defaults) => {
|
|
92
109
|
const ext = path.split('.').pop();
|
|
93
110
|
if (ext !== defaults) {
|
|
@@ -155,6 +172,12 @@ const omit = (object, list) => {
|
|
|
155
172
|
})
|
|
156
173
|
};
|
|
157
174
|
|
|
175
|
+
/**
|
|
176
|
+
*
|
|
177
|
+
* @param object
|
|
178
|
+
* @param prop
|
|
179
|
+
* @return {boolean}
|
|
180
|
+
*/
|
|
158
181
|
const hasProp = (object, prop) => {
|
|
159
182
|
return object && object.hasOwnProperty(prop)
|
|
160
183
|
};
|
|
@@ -165,6 +188,18 @@ const joinPath = (path, template) => {
|
|
|
165
188
|
return template
|
|
166
189
|
};
|
|
167
190
|
|
|
191
|
+
const matchTokens = (regex, text, callback) => {
|
|
192
|
+
let index = 0;
|
|
193
|
+
text.replace(regex, function () {
|
|
194
|
+
const params = [].slice.call(arguments, 0, -1);
|
|
195
|
+
const offset = params.pop();
|
|
196
|
+
const match = params.shift();
|
|
197
|
+
callback(params, index, offset);
|
|
198
|
+
index = offset + match.length;
|
|
199
|
+
return match
|
|
200
|
+
});
|
|
201
|
+
};
|
|
202
|
+
|
|
168
203
|
const defaults = {};
|
|
169
204
|
|
|
170
205
|
defaults.export = 'ejsPrecompiled';
|
|
@@ -243,153 +278,142 @@ const configSchema = (config, options) => {
|
|
|
243
278
|
|
|
244
279
|
const global = typeof globalThis !== 'undefined' ? globalThis : window || self;
|
|
245
280
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
if (
|
|
255
|
-
this
|
|
256
|
-
}
|
|
257
|
-
};
|
|
258
|
-
this.clear = function () {
|
|
259
|
-
cache.list = {};
|
|
260
|
-
};
|
|
261
|
-
this.load = function (data) {
|
|
262
|
-
if (cache.enabled) {
|
|
263
|
-
extend(cache.list, data || {});
|
|
281
|
+
class Cache {
|
|
282
|
+
#enabled = true
|
|
283
|
+
#list = {}
|
|
284
|
+
constructor(config) {
|
|
285
|
+
bindContext(this, ['configure']);
|
|
286
|
+
this.configure(config);
|
|
287
|
+
}
|
|
288
|
+
load(data) {
|
|
289
|
+
if (this.#enabled) {
|
|
290
|
+
extend(this.#list, data || {});
|
|
264
291
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
return cache.list[key]
|
|
292
|
+
}
|
|
293
|
+
get(key) {
|
|
294
|
+
if (this.#enabled) {
|
|
295
|
+
return this.#list[key]
|
|
270
296
|
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
if (
|
|
274
|
-
|
|
297
|
+
}
|
|
298
|
+
set(key, value) {
|
|
299
|
+
if (this.#enabled) {
|
|
300
|
+
this.#list[key] = value;
|
|
275
301
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
302
|
+
}
|
|
303
|
+
exist(key) {
|
|
304
|
+
return hasProp(this.#list, key)
|
|
305
|
+
}
|
|
306
|
+
clear() {
|
|
307
|
+
this.#list = {};
|
|
308
|
+
}
|
|
309
|
+
remove(key) {
|
|
310
|
+
delete this.#list[key];
|
|
311
|
+
}
|
|
312
|
+
resolve(key) {
|
|
279
313
|
return Promise.resolve(this.get(key))
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
}
|
|
314
|
+
}
|
|
315
|
+
configure(config) {
|
|
316
|
+
this.#enabled = config.cache;
|
|
317
|
+
if (isNode() === false) {
|
|
318
|
+
this.load(global[config.export]);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
287
321
|
}
|
|
288
322
|
|
|
289
|
-
|
|
290
|
-
{
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
323
|
+
class Compiler {
|
|
324
|
+
#config = {}
|
|
325
|
+
#symbols = [
|
|
326
|
+
{
|
|
327
|
+
symbol: '-',
|
|
328
|
+
format(value) {
|
|
329
|
+
return `')\n${this.BUFFER}(${this.SAFE}(${value},1))\n${this.BUFFER}('`
|
|
330
|
+
},
|
|
294
331
|
},
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
332
|
+
{
|
|
333
|
+
symbol: '=',
|
|
334
|
+
format(value) {
|
|
335
|
+
return `')\n${this.BUFFER}(${this.SAFE}(${value}))\n${this.BUFFER}('`
|
|
336
|
+
},
|
|
300
337
|
},
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
338
|
+
{
|
|
339
|
+
symbol: '#',
|
|
340
|
+
format(value) {
|
|
341
|
+
return `')\n/**${value}**/\n${this.BUFFER}('`
|
|
342
|
+
},
|
|
306
343
|
},
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
344
|
+
{
|
|
345
|
+
symbol: '',
|
|
346
|
+
format(value) {
|
|
347
|
+
return `')\n${value.trim()}\n${this.BUFFER}('`
|
|
348
|
+
},
|
|
312
349
|
},
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
const compiler = {};
|
|
332
|
-
|
|
333
|
-
this.configure = function (config) {
|
|
334
|
-
compiler.withObject = config.withObject;
|
|
335
|
-
compiler.rmWhitespace = config.rmWhitespace;
|
|
336
|
-
compiler.token = config.token;
|
|
337
|
-
compiler.vars = config.vars;
|
|
338
|
-
compiler.globalHelpers = config.globalHelpers;
|
|
339
|
-
compiler.matches = [];
|
|
340
|
-
compiler.formats = [];
|
|
341
|
-
compiler.slurp = {
|
|
342
|
-
match: '[\s\t\n]*',
|
|
343
|
-
start: [compiler.token.start, '_'],
|
|
344
|
-
end: ['_', compiler.token.end],
|
|
350
|
+
]
|
|
351
|
+
constructor(config) {
|
|
352
|
+
bindContext(this, ['configure', 'compile']);
|
|
353
|
+
this.configure(config);
|
|
354
|
+
}
|
|
355
|
+
configure(config) {
|
|
356
|
+
this.#config.withObject = config.withObject;
|
|
357
|
+
this.#config.rmWhitespace = config.rmWhitespace;
|
|
358
|
+
this.#config.token = config.token;
|
|
359
|
+
this.#config.vars = config.vars;
|
|
360
|
+
this.#config.globalHelpers = config.globalHelpers;
|
|
361
|
+
this.#config.matches = [];
|
|
362
|
+
this.#config.formats = [];
|
|
363
|
+
this.#config.slurp = {
|
|
364
|
+
match: '[s\t\n]*',
|
|
365
|
+
start: [this.#config.token.start, '_'],
|
|
366
|
+
end: ['_', this.#config.token.end],
|
|
345
367
|
};
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
368
|
+
this.#symbols.forEach((item) => {
|
|
369
|
+
this.#config.matches.push(
|
|
370
|
+
this.#config.token.start
|
|
349
371
|
.concat(item.symbol)
|
|
350
|
-
.concat(
|
|
351
|
-
.concat(
|
|
372
|
+
.concat(this.#config.token.regex)
|
|
373
|
+
.concat(this.#config.token.end)
|
|
352
374
|
);
|
|
353
|
-
|
|
375
|
+
this.#config.formats.push(item.format.bind(this.#config.vars));
|
|
354
376
|
});
|
|
355
|
-
|
|
356
|
-
|
|
377
|
+
this.#config.regex = new RegExp(
|
|
378
|
+
this.#config.matches.join('|').concat('|$'),
|
|
357
379
|
'g'
|
|
358
380
|
);
|
|
359
|
-
|
|
360
|
-
[
|
|
381
|
+
this.#config.slurpStart = new RegExp(
|
|
382
|
+
[this.#config.slurp.match, this.#config.slurp.start.join('')].join(
|
|
383
|
+
''
|
|
384
|
+
),
|
|
361
385
|
'gm'
|
|
362
386
|
);
|
|
363
|
-
|
|
364
|
-
[
|
|
387
|
+
this.#config.slurpEnd = new RegExp(
|
|
388
|
+
[this.#config.slurp.end.join(''), this.#config.slurp.match].join(
|
|
389
|
+
''
|
|
390
|
+
),
|
|
365
391
|
'gm'
|
|
366
392
|
);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
if (compiler.rmWhitespace) {
|
|
374
|
-
content = content
|
|
393
|
+
}
|
|
394
|
+
compile(content, path) {
|
|
395
|
+
const { SCOPE, SAFE, BUFFER, COMPONENT } = this.#config.vars;
|
|
396
|
+
const GLOBALS = this.#config.globalHelpers;
|
|
397
|
+
if (this.#config.rmWhitespace) {
|
|
398
|
+
content = String(content)
|
|
375
399
|
.replace(/[\r\n]+/g, '\n')
|
|
376
400
|
.replace(/^\s+|\s+$/gm, '');
|
|
377
401
|
}
|
|
378
|
-
content = content
|
|
379
|
-
.replace(
|
|
380
|
-
.replace(
|
|
402
|
+
content = String(content)
|
|
403
|
+
.replace(this.#config.slurpStart, this.#config.token.start)
|
|
404
|
+
.replace(this.#config.slurpEnd, this.#config.token.end);
|
|
381
405
|
let source = `${BUFFER}('`;
|
|
382
|
-
matchTokens(
|
|
406
|
+
matchTokens(this.#config.regex, content, (params, index, offset) => {
|
|
383
407
|
source += symbols(content.slice(index, offset));
|
|
384
408
|
params.forEach((value, index) => {
|
|
385
409
|
if (value) {
|
|
386
|
-
source +=
|
|
410
|
+
source += this.#config.formats[index](value);
|
|
387
411
|
}
|
|
388
412
|
});
|
|
389
413
|
});
|
|
390
414
|
source += `');`;
|
|
391
415
|
source = `try{${source}}catch(e){return ${BUFFER}.error(e)}`;
|
|
392
|
-
if (
|
|
416
|
+
if (this.#config.withObject) {
|
|
393
417
|
source = `with(${SCOPE}){${source}}`;
|
|
394
418
|
}
|
|
395
419
|
source = `${BUFFER}.start();${source}return ${BUFFER}.end();`;
|
|
@@ -405,57 +429,50 @@ function Compiler(config) {
|
|
|
405
429
|
throw e
|
|
406
430
|
}
|
|
407
431
|
return result
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
this.configure(config);
|
|
432
|
+
}
|
|
411
433
|
}
|
|
412
434
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
435
|
+
class Template {
|
|
436
|
+
#path
|
|
437
|
+
#cache
|
|
438
|
+
#compiler
|
|
439
|
+
#resolver
|
|
440
|
+
constructor(config, cache, compiler) {
|
|
441
|
+
assertInstanceOf(cache, Cache);
|
|
442
|
+
assertInstanceOf(compiler, Compiler);
|
|
443
|
+
this.#cache = cache;
|
|
444
|
+
this.#compiler = compiler;
|
|
445
|
+
bindContext(this, ['configure', 'get']);
|
|
446
|
+
this.configure(config);
|
|
447
|
+
}
|
|
448
|
+
#resolve(path) {
|
|
449
|
+
return this.#resolver(this.#path, path)
|
|
450
|
+
}
|
|
451
|
+
#result(template, content) {
|
|
452
|
+
this.#cache.set(template, content);
|
|
427
453
|
return content
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
const resolve = (path) => {
|
|
431
|
-
return template.resolver(template.path, path)
|
|
432
|
-
};
|
|
433
|
-
|
|
434
|
-
const compile = (content, template) => {
|
|
454
|
+
}
|
|
455
|
+
#compile(content, template) {
|
|
435
456
|
if (isFunction(content)) {
|
|
436
457
|
return content
|
|
437
458
|
} else {
|
|
438
|
-
return compiler.compile(content, template)
|
|
459
|
+
return this.#compiler.compile(content, template)
|
|
439
460
|
}
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
template.path = config.path;
|
|
444
|
-
template.cache = config.cache;
|
|
461
|
+
}
|
|
462
|
+
configure(config) {
|
|
463
|
+
this.#path = config.path;
|
|
445
464
|
if (isFunction(config.resolver)) {
|
|
446
|
-
|
|
465
|
+
this.#resolver = config.resolver;
|
|
447
466
|
}
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
return cache.resolve(template)
|
|
467
|
+
}
|
|
468
|
+
get(template) {
|
|
469
|
+
if (this.#cache.exist(template)) {
|
|
470
|
+
return this.#cache.resolve(template)
|
|
453
471
|
}
|
|
454
|
-
return resolve(template).then((content) =>
|
|
455
|
-
result(template, compile(content, template))
|
|
472
|
+
return this.#resolve(template).then((content) =>
|
|
473
|
+
this.#result(template, this.#compile(content, template))
|
|
456
474
|
)
|
|
457
|
-
}
|
|
458
|
-
this.configure(config);
|
|
475
|
+
}
|
|
459
476
|
}
|
|
460
477
|
|
|
461
478
|
const selfClosed = [
|
|
@@ -494,7 +511,7 @@ const element = (tag, attrs, content) => {
|
|
|
494
511
|
}
|
|
495
512
|
}).join(space);
|
|
496
513
|
result.push([lt, tag, space, attributes, gt].join(''));
|
|
497
|
-
if (content) {
|
|
514
|
+
if (content && hasClosedTag) {
|
|
498
515
|
result.push(content instanceof Array ? content.join('') : content);
|
|
499
516
|
}
|
|
500
517
|
if (hasClosedTag) {
|
|
@@ -503,475 +520,431 @@ const element = (tag, attrs, content) => {
|
|
|
503
520
|
return result.join('')
|
|
504
521
|
};
|
|
505
522
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
523
|
+
class TemplateError extends Error {
|
|
524
|
+
code = 0
|
|
525
|
+
constructor(message) {
|
|
526
|
+
super();
|
|
527
|
+
this.message = message;
|
|
528
|
+
}
|
|
529
|
+
getCode() {
|
|
530
|
+
return this.code
|
|
531
|
+
}
|
|
532
|
+
getMessage() {
|
|
533
|
+
return this.message
|
|
534
|
+
}
|
|
535
|
+
toString() {
|
|
536
|
+
return this.getMessage()
|
|
537
|
+
}
|
|
516
538
|
}
|
|
517
539
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
*/
|
|
521
|
-
Object.setPrototypeOf(TemplateError.prototype, Error.prototype);
|
|
522
|
-
Object.assign(TemplateError.prototype, { code: 1 });
|
|
523
|
-
/**
|
|
524
|
-
*
|
|
525
|
-
* @return {number}
|
|
526
|
-
*/
|
|
527
|
-
TemplateError.prototype.getCode = function() {
|
|
528
|
-
return this.code
|
|
529
|
-
};
|
|
530
|
-
/**
|
|
531
|
-
*
|
|
532
|
-
* @return {string}
|
|
533
|
-
*/
|
|
534
|
-
TemplateError.prototype.getMessage = function() {
|
|
535
|
-
return this.message
|
|
536
|
-
};
|
|
537
|
-
/**
|
|
538
|
-
* @return {string}
|
|
539
|
-
*/
|
|
540
|
-
TemplateError.prototype.toString = function() {
|
|
541
|
-
return this.getMessage()
|
|
542
|
-
};
|
|
543
|
-
|
|
544
|
-
/**
|
|
545
|
-
* @extends TemplateError
|
|
546
|
-
* @param {string} message
|
|
547
|
-
* @constructor
|
|
548
|
-
*/
|
|
549
|
-
function TemplateNotFound(message) {
|
|
550
|
-
TemplateError.call(this);
|
|
551
|
-
this.name = 'TemplateNotFound';
|
|
552
|
-
this.message = message;
|
|
540
|
+
class TemplateNotFound extends TemplateError {
|
|
541
|
+
code = 404
|
|
553
542
|
}
|
|
554
543
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
*/
|
|
558
|
-
Object.setPrototypeOf(TemplateNotFound.prototype, TemplateError.prototype);
|
|
559
|
-
Object.assign(TemplateNotFound.prototype, { code: 404 });
|
|
560
|
-
/**
|
|
561
|
-
* @extends TemplateError
|
|
562
|
-
* @param {string} message
|
|
563
|
-
* @constructor
|
|
564
|
-
*/
|
|
565
|
-
function TemplateSyntaxError(message) {
|
|
566
|
-
TemplateError.call(this);
|
|
567
|
-
this.name = 'TemplateSyntaxError';
|
|
568
|
-
this.message = message;
|
|
544
|
+
class TemplateSyntaxError extends TemplateError {
|
|
545
|
+
code = 500
|
|
569
546
|
}
|
|
570
547
|
|
|
571
|
-
/**
|
|
572
|
-
*
|
|
573
|
-
*/
|
|
574
|
-
Object.setPrototypeOf(TemplateSyntaxError.prototype, TemplateError.prototype);
|
|
575
|
-
Object.assign(TemplateSyntaxError.prototype, { code: 500 });
|
|
576
|
-
|
|
577
548
|
function resolve(list) {
|
|
578
|
-
return Promise.all(list || [])
|
|
549
|
+
return Promise.all(list || [])
|
|
550
|
+
.then((list) => list.join(''))
|
|
551
|
+
.catch((e) => e)
|
|
579
552
|
}
|
|
580
553
|
|
|
581
554
|
function reject(error) {
|
|
582
555
|
return Promise.reject(new TemplateSyntaxError(error.message))
|
|
583
556
|
}
|
|
584
557
|
|
|
558
|
+
/**
|
|
559
|
+
*
|
|
560
|
+
* @return {buffer}
|
|
561
|
+
*/
|
|
585
562
|
function createBuffer() {
|
|
586
563
|
let store = [],
|
|
587
564
|
array = [];
|
|
588
565
|
|
|
589
|
-
|
|
566
|
+
const buffer = (value) => {
|
|
590
567
|
array.push(value);
|
|
591
|
-
}
|
|
568
|
+
};
|
|
592
569
|
|
|
593
|
-
buffer.start =
|
|
570
|
+
buffer.start = () => {
|
|
594
571
|
array = [];
|
|
595
572
|
};
|
|
596
|
-
buffer.backup =
|
|
573
|
+
buffer.backup = () => {
|
|
597
574
|
store.push(array.concat());
|
|
598
575
|
array = [];
|
|
599
576
|
};
|
|
600
|
-
buffer.restore =
|
|
577
|
+
buffer.restore = () => {
|
|
601
578
|
const result = array.concat();
|
|
602
579
|
array = store.pop();
|
|
603
580
|
return resolve(result)
|
|
604
581
|
};
|
|
605
|
-
buffer.error =
|
|
582
|
+
buffer.error = (e) => {
|
|
606
583
|
return reject(e)
|
|
607
584
|
};
|
|
608
|
-
buffer.end =
|
|
585
|
+
buffer.end = () => {
|
|
609
586
|
return resolve(array)
|
|
610
587
|
};
|
|
611
588
|
return buffer
|
|
612
589
|
}
|
|
613
590
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
this
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
* @name ContextScope
|
|
628
|
-
* @param data
|
|
629
|
-
* @constructor
|
|
630
|
-
*/
|
|
631
|
-
function Scope(data) {
|
|
632
|
-
this[BLOCKS] = {};
|
|
633
|
-
this[MACRO] = {};
|
|
634
|
-
extend(this, data || {});
|
|
635
|
-
}
|
|
591
|
+
const createScope = (config, methods) => {
|
|
592
|
+
const { BLOCKS, MACRO, EXTEND, LAYOUT, BUFFER, COMPONENT, SAFE, SCOPE } =
|
|
593
|
+
config.vars;
|
|
594
|
+
/**
|
|
595
|
+
* @name ContextScope
|
|
596
|
+
* @param data
|
|
597
|
+
* @constructor
|
|
598
|
+
*/
|
|
599
|
+
function ContextScope(data) {
|
|
600
|
+
this[BLOCKS] = {};
|
|
601
|
+
this[MACRO] = {};
|
|
602
|
+
Object.assign(this, omit(data, [SCOPE, BUFFER, SAFE, COMPONENT]));
|
|
603
|
+
}
|
|
636
604
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
},
|
|
663
|
-
[EXTEND]: {
|
|
664
|
-
value: false,
|
|
665
|
-
writable: true,
|
|
666
|
-
configurable: false,
|
|
667
|
-
enumerable: false,
|
|
668
|
-
},
|
|
669
|
-
getMacro: {
|
|
670
|
-
value() {
|
|
671
|
-
return this[MACRO]
|
|
672
|
-
},
|
|
673
|
-
writable: false,
|
|
674
|
-
configurable: false,
|
|
675
|
-
enumerable: false,
|
|
605
|
+
Object.assign(ContextScope.prototype, methods);
|
|
606
|
+
Object.defineProperties(ContextScope.prototype, {
|
|
607
|
+
[BUFFER]: {
|
|
608
|
+
value: createBuffer(),
|
|
609
|
+
},
|
|
610
|
+
[BLOCKS]: {
|
|
611
|
+
value: {},
|
|
612
|
+
writable: true,
|
|
613
|
+
},
|
|
614
|
+
[MACRO]: {
|
|
615
|
+
value: {},
|
|
616
|
+
writable: true,
|
|
617
|
+
},
|
|
618
|
+
[LAYOUT]: {
|
|
619
|
+
value: false,
|
|
620
|
+
writable: true,
|
|
621
|
+
},
|
|
622
|
+
[EXTEND]: {
|
|
623
|
+
value: false,
|
|
624
|
+
writable: true,
|
|
625
|
+
},
|
|
626
|
+
/** @type {()=>this[MACRO]} */
|
|
627
|
+
getMacro: {
|
|
628
|
+
value() {
|
|
629
|
+
return this[MACRO]
|
|
676
630
|
},
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
configurable: false,
|
|
683
|
-
enumerable: false,
|
|
631
|
+
},
|
|
632
|
+
/** @type {function} */
|
|
633
|
+
getBuffer: {
|
|
634
|
+
value() {
|
|
635
|
+
return this[BUFFER]
|
|
684
636
|
},
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
}
|
|
692
|
-
}
|
|
637
|
+
},
|
|
638
|
+
/** @type {function} */
|
|
639
|
+
getComponent: {
|
|
640
|
+
value() {
|
|
641
|
+
const context = this;
|
|
642
|
+
if (COMPONENT in context) {
|
|
693
643
|
return function () {
|
|
694
|
-
|
|
644
|
+
return context[COMPONENT].apply(context, arguments)
|
|
695
645
|
}
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
646
|
+
}
|
|
647
|
+
return function () {
|
|
648
|
+
console.log('%s function not defined', COMPONENT);
|
|
649
|
+
}
|
|
700
650
|
},
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
configurable: false,
|
|
707
|
-
enumerable: false,
|
|
651
|
+
},
|
|
652
|
+
/** @type {function} */
|
|
653
|
+
getBlocks: {
|
|
654
|
+
value() {
|
|
655
|
+
return this[BLOCKS]
|
|
708
656
|
},
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
configurable: false,
|
|
715
|
-
enumerable: false,
|
|
657
|
+
},
|
|
658
|
+
/** @type {function} */
|
|
659
|
+
setExtend: {
|
|
660
|
+
value(value) {
|
|
661
|
+
this[EXTEND] = value;
|
|
716
662
|
},
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
configurable: false,
|
|
723
|
-
enumerable: false,
|
|
663
|
+
},
|
|
664
|
+
/** @type {function} */
|
|
665
|
+
getExtend: {
|
|
666
|
+
value() {
|
|
667
|
+
return this[EXTEND]
|
|
724
668
|
},
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
configurable: false,
|
|
731
|
-
enumerable: false,
|
|
669
|
+
},
|
|
670
|
+
/** @type {function} */
|
|
671
|
+
setLayout: {
|
|
672
|
+
value(layout) {
|
|
673
|
+
this[LAYOUT] = layout;
|
|
732
674
|
},
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
configurable: false,
|
|
739
|
-
enumerable: false,
|
|
675
|
+
},
|
|
676
|
+
/** @type {function} */
|
|
677
|
+
getLayout: {
|
|
678
|
+
value() {
|
|
679
|
+
return this[LAYOUT]
|
|
740
680
|
},
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
configurable: false,
|
|
751
|
-
enumerable: false,
|
|
681
|
+
},
|
|
682
|
+
/** @type {function} */
|
|
683
|
+
clone: {
|
|
684
|
+
value(exclude_blocks) {
|
|
685
|
+
const filter = [LAYOUT, EXTEND, BUFFER];
|
|
686
|
+
if (exclude_blocks === true) {
|
|
687
|
+
filter.push(BLOCKS);
|
|
688
|
+
}
|
|
689
|
+
return omit(this, filter)
|
|
752
690
|
},
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
configurable: false,
|
|
760
|
-
enumerable: false,
|
|
691
|
+
},
|
|
692
|
+
/** @type {function} */
|
|
693
|
+
extend: {
|
|
694
|
+
value(layout) {
|
|
695
|
+
this.setExtend(true);
|
|
696
|
+
this.setLayout(layout);
|
|
761
697
|
},
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
configurable: false,
|
|
770
|
-
enumerable: false,
|
|
698
|
+
},
|
|
699
|
+
/** @type {function} */
|
|
700
|
+
echo: {
|
|
701
|
+
value(layout) {
|
|
702
|
+
const buffer = this.getBuffer();
|
|
703
|
+
const params = [].slice.call(arguments);
|
|
704
|
+
params.forEach(buffer);
|
|
771
705
|
},
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
706
|
+
},
|
|
707
|
+
/** @type {function} */
|
|
708
|
+
fn: {
|
|
709
|
+
value(callback) {
|
|
710
|
+
const buffer = this.getBuffer();
|
|
711
|
+
const context = this;
|
|
712
|
+
return function () {
|
|
713
|
+
buffer.backup();
|
|
714
|
+
if (isFunction(callback)) {
|
|
715
|
+
callback.apply(context, arguments);
|
|
782
716
|
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
configurable: false,
|
|
786
|
-
enumerable: false,
|
|
717
|
+
return buffer.restore()
|
|
718
|
+
}
|
|
787
719
|
},
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
configurable: true,
|
|
797
|
-
enumerable: false,
|
|
720
|
+
},
|
|
721
|
+
/** @type {function} */
|
|
722
|
+
get: {
|
|
723
|
+
value(name, defaults) {
|
|
724
|
+
const path = getPath(this, name, true);
|
|
725
|
+
const result = path.shift();
|
|
726
|
+
const prop = path.pop();
|
|
727
|
+
return hasProp(result, prop) ? result[prop] : defaults
|
|
798
728
|
},
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
return
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
configurable: false,
|
|
811
|
-
enumerable: false,
|
|
729
|
+
},
|
|
730
|
+
/** @type {function} */
|
|
731
|
+
set: {
|
|
732
|
+
value(name, value) {
|
|
733
|
+
const path = getPath(this, name, false);
|
|
734
|
+
const result = path.shift();
|
|
735
|
+
const prop = path.pop();
|
|
736
|
+
if (this.getExtend() && hasProp(result, prop)) {
|
|
737
|
+
return result[prop]
|
|
738
|
+
}
|
|
739
|
+
return (result[prop] = value)
|
|
812
740
|
},
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
configurable: false,
|
|
824
|
-
enumerable: false,
|
|
741
|
+
},
|
|
742
|
+
/** @type {function} */
|
|
743
|
+
macro: {
|
|
744
|
+
value(name, callback) {
|
|
745
|
+
const list = this.getMacro();
|
|
746
|
+
const macro = this.fn(callback);
|
|
747
|
+
const context = this;
|
|
748
|
+
list[name] = function () {
|
|
749
|
+
return context.echo(macro.apply(undefined, arguments))
|
|
750
|
+
};
|
|
825
751
|
},
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
configurable: false,
|
|
837
|
-
enumerable: false,
|
|
752
|
+
},
|
|
753
|
+
/** @type {function} */
|
|
754
|
+
call: {
|
|
755
|
+
value(name) {
|
|
756
|
+
const list = this.getMacro();
|
|
757
|
+
const macro = list[name];
|
|
758
|
+
const params = [].slice.call(arguments, 1);
|
|
759
|
+
if (isFunction(macro)) {
|
|
760
|
+
return macro.apply(macro, params)
|
|
761
|
+
}
|
|
838
762
|
},
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
return noop
|
|
763
|
+
},
|
|
764
|
+
/** @type {function} */
|
|
765
|
+
block: {
|
|
766
|
+
value(name, callback) {
|
|
767
|
+
const blocks = this.getBlocks();
|
|
768
|
+
blocks[name] = blocks[name] || [];
|
|
769
|
+
blocks[name].push(this.fn(callback));
|
|
770
|
+
if (this.getExtend()) return
|
|
771
|
+
const list = Object.assign([], blocks[name]);
|
|
772
|
+
const current = function () {
|
|
773
|
+
return list.shift()
|
|
774
|
+
};
|
|
775
|
+
const next = () => {
|
|
776
|
+
const parent = current();
|
|
777
|
+
if (parent) {
|
|
778
|
+
return () => {
|
|
779
|
+
this.echo(parent(next()));
|
|
857
780
|
}
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
enumerable: false,
|
|
781
|
+
} else {
|
|
782
|
+
return noop
|
|
783
|
+
}
|
|
784
|
+
};
|
|
785
|
+
this.echo(current()(next()));
|
|
864
786
|
},
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
configurable: false,
|
|
871
|
-
enumerable: false,
|
|
787
|
+
},
|
|
788
|
+
/** @type {function} */
|
|
789
|
+
hasBlock: {
|
|
790
|
+
value(name) {
|
|
791
|
+
return this.getBlocks().hasOwnProperty(name)
|
|
872
792
|
},
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
configurable: false,
|
|
882
|
-
enumerable: false,
|
|
793
|
+
},
|
|
794
|
+
/** @type {function} */
|
|
795
|
+
include: {
|
|
796
|
+
value(path, data, cx) {
|
|
797
|
+
const context = cx === false ? {} : this.clone(true);
|
|
798
|
+
const params = extend(context, data || {});
|
|
799
|
+
const promise = this.render(path, params);
|
|
800
|
+
this.echo(promise);
|
|
883
801
|
},
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
configurable: false,
|
|
892
|
-
enumerable: false,
|
|
802
|
+
},
|
|
803
|
+
/** @type {function} */
|
|
804
|
+
promiseResolve: {
|
|
805
|
+
value(value, callback) {
|
|
806
|
+
return Promise.resolve(
|
|
807
|
+
isFunction(value) ? this.fn(value)() : value
|
|
808
|
+
).then(callback.bind(this))
|
|
893
809
|
},
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
);
|
|
907
|
-
},
|
|
908
|
-
writable: false,
|
|
909
|
-
configurable: false,
|
|
910
|
-
enumerable: false,
|
|
810
|
+
},
|
|
811
|
+
/** @type {function} */
|
|
812
|
+
use: {
|
|
813
|
+
value(path, namespace) {
|
|
814
|
+
this.echo(
|
|
815
|
+
this.promiseResolve(this.require(path), function (exports) {
|
|
816
|
+
const list = this.getMacro();
|
|
817
|
+
each(exports, function (macro, name) {
|
|
818
|
+
list[[namespace, name].join('.')] = macro;
|
|
819
|
+
});
|
|
820
|
+
})
|
|
821
|
+
);
|
|
911
822
|
},
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
configurable: false,
|
|
922
|
-
enumerable: false,
|
|
823
|
+
},
|
|
824
|
+
/** @type {function} */
|
|
825
|
+
async: {
|
|
826
|
+
value(promise, callback) {
|
|
827
|
+
this.echo(
|
|
828
|
+
this.promiseResolve(promise, function (data) {
|
|
829
|
+
return this.fn(callback)(data)
|
|
830
|
+
})
|
|
831
|
+
);
|
|
923
832
|
},
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
configurable: false,
|
|
933
|
-
enumerable: false,
|
|
833
|
+
},
|
|
834
|
+
/** @type {function} */
|
|
835
|
+
each: {
|
|
836
|
+
value: function (object, callback) {
|
|
837
|
+
if (isString(object)) {
|
|
838
|
+
object = this.get(object, []);
|
|
839
|
+
}
|
|
840
|
+
each(object, callback);
|
|
934
841
|
},
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
configurable: false,
|
|
941
|
-
enumerable: false,
|
|
842
|
+
},
|
|
843
|
+
/** @type {function} */
|
|
844
|
+
element: {
|
|
845
|
+
value(tag, attr, content) {
|
|
846
|
+
return element(tag, attr, content)
|
|
942
847
|
},
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
configurable: false,
|
|
953
|
-
enumerable: false,
|
|
848
|
+
},
|
|
849
|
+
/** @type {function} */
|
|
850
|
+
el: {
|
|
851
|
+
value(tag, attr, content) {
|
|
852
|
+
this.echo(
|
|
853
|
+
this.promiseResolve(content, function (content) {
|
|
854
|
+
return this.element(tag, attr, content)
|
|
855
|
+
})
|
|
856
|
+
);
|
|
954
857
|
},
|
|
955
|
-
}
|
|
956
|
-
};
|
|
957
|
-
|
|
958
|
-
}
|
|
858
|
+
},
|
|
859
|
+
});
|
|
860
|
+
return ContextScope
|
|
861
|
+
};
|
|
959
862
|
|
|
960
|
-
|
|
961
|
-
|
|
863
|
+
class Context {
|
|
864
|
+
#scope
|
|
962
865
|
|
|
963
|
-
|
|
964
|
-
|
|
866
|
+
constructor(config, methods) {
|
|
867
|
+
bindContext(this, ['create', 'helpers', 'configure']);
|
|
868
|
+
this.configure(config, methods);
|
|
869
|
+
}
|
|
965
870
|
|
|
966
|
-
|
|
871
|
+
create(data) {
|
|
872
|
+
return new this.#scope(data)
|
|
873
|
+
}
|
|
967
874
|
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
875
|
+
configure(config, methods) {
|
|
876
|
+
this.#scope = createScope(config, methods);
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
helpers(methods) {
|
|
880
|
+
extend(this.#scope.prototype, methods || {});
|
|
881
|
+
}
|
|
882
|
+
}
|
|
972
883
|
|
|
973
|
-
|
|
974
|
-
|
|
884
|
+
class EJS {
|
|
885
|
+
#config = {}
|
|
886
|
+
#extend = {}
|
|
887
|
+
#context
|
|
888
|
+
#compiler
|
|
889
|
+
#cache
|
|
890
|
+
#template
|
|
891
|
+
constructor(options) {
|
|
892
|
+
configSchema(this.#config, options || {});
|
|
893
|
+
this.#context = new Context(this.#config, this.#extend);
|
|
894
|
+
this.#compiler = new Compiler(this.#config);
|
|
895
|
+
this.#cache = new Cache(this.#config);
|
|
896
|
+
this.#template = new Template(this.#config, this.#cache, this.#compiler);
|
|
897
|
+
//
|
|
898
|
+
bindContext(this, [
|
|
899
|
+
'configure',
|
|
900
|
+
'create',
|
|
901
|
+
'render',
|
|
902
|
+
'context',
|
|
903
|
+
'preload',
|
|
904
|
+
'compile',
|
|
905
|
+
'helpers',
|
|
906
|
+
]);
|
|
907
|
+
//
|
|
908
|
+
this.helpers({ require: this.#require, render: this.render });
|
|
909
|
+
}
|
|
910
|
+
configure(options) {
|
|
911
|
+
configSchema(this.#config, options || {});
|
|
912
|
+
this.#context.configure(this.#config, this.#extend);
|
|
913
|
+
this.#compiler.configure(this.#config);
|
|
914
|
+
this.#cache.configure(this.#config);
|
|
915
|
+
this.#template.configure(this.#config);
|
|
916
|
+
return this.#config
|
|
917
|
+
}
|
|
918
|
+
render(name, data) {
|
|
919
|
+
const filepath = ext(name, this.#config.extension);
|
|
920
|
+
const scope = this.context(data);
|
|
921
|
+
return this.#output(filepath, scope).then((content) => {
|
|
922
|
+
if (scope.getExtend()) {
|
|
923
|
+
scope.setExtend(false);
|
|
924
|
+
const layout = scope.getLayout();
|
|
925
|
+
const data = scope.clone();
|
|
926
|
+
return this.render(layout, data)
|
|
927
|
+
}
|
|
928
|
+
return content
|
|
929
|
+
})
|
|
930
|
+
}
|
|
931
|
+
helpers(methods) {
|
|
932
|
+
this.#context.helpers(extend(this.#extend, methods));
|
|
933
|
+
}
|
|
934
|
+
context(data) {
|
|
935
|
+
return this.#context.create(data)
|
|
936
|
+
}
|
|
937
|
+
compile(content, path) {
|
|
938
|
+
return this.#compiler.compile(content, path)
|
|
939
|
+
}
|
|
940
|
+
preload(list) {
|
|
941
|
+
return this.#cache.load(list || {})
|
|
942
|
+
}
|
|
943
|
+
create(options) {
|
|
944
|
+
return new this.constructor(options)
|
|
945
|
+
}
|
|
946
|
+
#output(path, scope) {
|
|
947
|
+
const { globalHelpers } = this.#config;
|
|
975
948
|
const params = [
|
|
976
949
|
scope,
|
|
977
950
|
scope.getComponent(),
|
|
@@ -982,60 +955,168 @@ function EJS(options) {
|
|
|
982
955
|
.filter((name) => isFunction(scope[name]))
|
|
983
956
|
.map((name) => scope[name].bind(scope))
|
|
984
957
|
);
|
|
985
|
-
return template
|
|
958
|
+
return this.#template
|
|
986
959
|
.get(path)
|
|
987
960
|
.then((callback) => callback.apply(scope, params))
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
const
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
};
|
|
995
|
-
const render = (name, data) => {
|
|
996
|
-
const filepath = ext(name, config.extension);
|
|
997
|
-
const scope = context.create(data);
|
|
998
|
-
return output(filepath, scope).then((content) => {
|
|
999
|
-
if (scope.getExtend()) {
|
|
1000
|
-
scope.setExtend(false);
|
|
1001
|
-
const layout = scope.getLayout();
|
|
1002
|
-
const data = scope.clone();
|
|
1003
|
-
return render(layout, data)
|
|
1004
|
-
}
|
|
1005
|
-
return content
|
|
1006
|
-
})
|
|
1007
|
-
};
|
|
1008
|
-
this.configure = function (options) {
|
|
1009
|
-
options = options || {};
|
|
1010
|
-
configSchema(config, options);
|
|
1011
|
-
context.configure(config, scope);
|
|
1012
|
-
compiler.configure(config);
|
|
1013
|
-
cache.configure(config);
|
|
1014
|
-
template.configure(config);
|
|
1015
|
-
return config
|
|
1016
|
-
};
|
|
1017
|
-
this.render = function (name, data) {
|
|
1018
|
-
return render(name, data)
|
|
1019
|
-
};
|
|
1020
|
-
this.helpers = function (methods) {
|
|
1021
|
-
context.helpers(extend(scope, methods));
|
|
1022
|
-
};
|
|
1023
|
-
this.preload = function (list) {
|
|
1024
|
-
return cache.load(list || {})
|
|
1025
|
-
};
|
|
1026
|
-
this.create = function (options) {
|
|
1027
|
-
return new EJS(options)
|
|
1028
|
-
};
|
|
1029
|
-
this.compile = function (content, path) {
|
|
1030
|
-
return compiler.compile(content, path)
|
|
1031
|
-
};
|
|
1032
|
-
this.context = function (data) {
|
|
1033
|
-
return context.create(data)
|
|
1034
|
-
};
|
|
1035
|
-
this.helpers({ require, render });
|
|
1036
|
-
return this
|
|
961
|
+
}
|
|
962
|
+
#require(name) {
|
|
963
|
+
const filepath = ext(name, this.#config.extension);
|
|
964
|
+
const scope = this.context({});
|
|
965
|
+
return this.#output(filepath, scope).then(() => scope.getMacro())
|
|
966
|
+
}
|
|
1037
967
|
}
|
|
1038
968
|
|
|
969
|
+
// export function EJS2(options) {
|
|
970
|
+
// const self = {
|
|
971
|
+
// config: {},
|
|
972
|
+
// helpers: {},
|
|
973
|
+
// /**
|
|
974
|
+
// * @type {Context}
|
|
975
|
+
// */
|
|
976
|
+
// context: null,
|
|
977
|
+
// /**
|
|
978
|
+
// * @type {Compiler}
|
|
979
|
+
// */
|
|
980
|
+
// compiler: null,
|
|
981
|
+
// /**
|
|
982
|
+
// * @type {Template}
|
|
983
|
+
// */
|
|
984
|
+
// template: null,
|
|
985
|
+
// /**
|
|
986
|
+
// * @type {Cache}
|
|
987
|
+
// */
|
|
988
|
+
// cache: null,
|
|
989
|
+
// }
|
|
990
|
+
// /**
|
|
991
|
+
// *
|
|
992
|
+
// */
|
|
993
|
+
// configSchema(self.config, options || {})
|
|
994
|
+
// self.context = useContext(self.config, self.helpers)
|
|
995
|
+
// self.compiler = useCompiler(self.config)
|
|
996
|
+
// self.cache = useCache(self.config)
|
|
997
|
+
// self.template = useTemplate(self.config, self.cache, self.compiler)
|
|
998
|
+
// /**
|
|
999
|
+
// *
|
|
1000
|
+
// * @param {string} path
|
|
1001
|
+
// * @param {ContextScope} scope
|
|
1002
|
+
// * @return {Promise<string>}
|
|
1003
|
+
// */
|
|
1004
|
+
// const output = (path, scope) => {
|
|
1005
|
+
// const { globalHelpers } = self.config
|
|
1006
|
+
// const params = [
|
|
1007
|
+
// scope,
|
|
1008
|
+
// scope.getComponent(),
|
|
1009
|
+
// scope.getBuffer(),
|
|
1010
|
+
// safeValue,
|
|
1011
|
+
// ].concat(
|
|
1012
|
+
// globalHelpers
|
|
1013
|
+
// .filter((name) => isFunction(scope[name]))
|
|
1014
|
+
// .map((name) => scope[name].bind(scope))
|
|
1015
|
+
// )
|
|
1016
|
+
// return self.template
|
|
1017
|
+
// .get(path)
|
|
1018
|
+
// .then((callback) => callback.apply(scope, params))
|
|
1019
|
+
// }
|
|
1020
|
+
// /**
|
|
1021
|
+
// *
|
|
1022
|
+
// * @param name
|
|
1023
|
+
// * @return {Promise<string>}
|
|
1024
|
+
// */
|
|
1025
|
+
// const require = (name) => {
|
|
1026
|
+
// const filepath = ext(name, self.config.extension)
|
|
1027
|
+
// const scope = context({})
|
|
1028
|
+
// return output(filepath, scope).then(() => scope.getMacro())
|
|
1029
|
+
// }
|
|
1030
|
+
// /**
|
|
1031
|
+
// *
|
|
1032
|
+
// * @param {string} name
|
|
1033
|
+
// * @param {{}} [data]
|
|
1034
|
+
// * @return {Promise<string>}
|
|
1035
|
+
// */
|
|
1036
|
+
// const render = (name, data) => {
|
|
1037
|
+
// const filepath = ext(name, self.config.extension)
|
|
1038
|
+
// const scope = context(data)
|
|
1039
|
+
// return output(filepath, scope).then((content) => {
|
|
1040
|
+
// if (scope.getExtend()) {
|
|
1041
|
+
// scope.setExtend(false)
|
|
1042
|
+
// const layout = scope.getLayout()
|
|
1043
|
+
// const data = scope.clone()
|
|
1044
|
+
// return render(layout, data)
|
|
1045
|
+
// }
|
|
1046
|
+
// return content
|
|
1047
|
+
// })
|
|
1048
|
+
// }
|
|
1049
|
+
// /**
|
|
1050
|
+
// *
|
|
1051
|
+
// * @param options
|
|
1052
|
+
// * @return {{}}
|
|
1053
|
+
// */
|
|
1054
|
+
// const configure = (options = {}) => {
|
|
1055
|
+
// configSchema(self.config, options || {})
|
|
1056
|
+
// self.context.configure(self.config, self.helpers)
|
|
1057
|
+
// self.compiler.configure(self.config)
|
|
1058
|
+
// self.cache.configure(self.config)
|
|
1059
|
+
// self.template.configure(self.config)
|
|
1060
|
+
// return self.config
|
|
1061
|
+
// }
|
|
1062
|
+
// /**
|
|
1063
|
+
// *
|
|
1064
|
+
// * @param methods
|
|
1065
|
+
// */
|
|
1066
|
+
// const helpers = (methods) => {
|
|
1067
|
+
// self.context.helpers(extend(self.helpers, methods))
|
|
1068
|
+
// }
|
|
1069
|
+
// /**
|
|
1070
|
+
// *
|
|
1071
|
+
// * @param list
|
|
1072
|
+
// * @return {*}
|
|
1073
|
+
// */
|
|
1074
|
+
// const preload = (list) => {
|
|
1075
|
+
// return self.cache.load(list || {})
|
|
1076
|
+
// }
|
|
1077
|
+
// /**
|
|
1078
|
+
// *
|
|
1079
|
+
// * @param options
|
|
1080
|
+
// * @return {any}
|
|
1081
|
+
// */
|
|
1082
|
+
// const create = (options) => {
|
|
1083
|
+
// return EJS(options)
|
|
1084
|
+
// }
|
|
1085
|
+
// /**
|
|
1086
|
+
// *
|
|
1087
|
+
// * @param content
|
|
1088
|
+
// * @param path
|
|
1089
|
+
// * @return {Function}
|
|
1090
|
+
// */
|
|
1091
|
+
// const compile = (content, path) => {
|
|
1092
|
+
// return self.compiler.compile(content, path)
|
|
1093
|
+
// }
|
|
1094
|
+
// /**
|
|
1095
|
+
// *
|
|
1096
|
+
// * @param data
|
|
1097
|
+
// * @return {ContextScope}
|
|
1098
|
+
// */
|
|
1099
|
+
// const context = (data = {}) => {
|
|
1100
|
+
// return self.context.create(data)
|
|
1101
|
+
// }
|
|
1102
|
+
// /**
|
|
1103
|
+
// *
|
|
1104
|
+
// */
|
|
1105
|
+
// helpers({ require, render })
|
|
1106
|
+
// /**
|
|
1107
|
+
// *
|
|
1108
|
+
// */
|
|
1109
|
+
// return {
|
|
1110
|
+
// configure,
|
|
1111
|
+
// helpers,
|
|
1112
|
+
// preload,
|
|
1113
|
+
// context,
|
|
1114
|
+
// compile,
|
|
1115
|
+
// create,
|
|
1116
|
+
// render,
|
|
1117
|
+
// }
|
|
1118
|
+
// }
|
|
1119
|
+
|
|
1039
1120
|
function readFile(path, template) {
|
|
1040
1121
|
return new Promise((resolve, reject) => {
|
|
1041
1122
|
fs.readFile(joinPath(path, template), (error, data) => {
|
|
@@ -1050,10 +1131,11 @@ function readFile(path, template) {
|
|
|
1050
1131
|
|
|
1051
1132
|
/**
|
|
1052
1133
|
*
|
|
1053
|
-
* @param {
|
|
1054
|
-
* @
|
|
1134
|
+
* @param {function(config: object):object} configure
|
|
1135
|
+
* @param {function(name: string, data?: object):Promise<string>} render
|
|
1136
|
+
* @return {function(name:any, options:any, callback: any): Promise<void>}
|
|
1055
1137
|
*/
|
|
1056
|
-
function expressRenderer(
|
|
1138
|
+
function expressRenderer(configure, render) {
|
|
1057
1139
|
return function (name, options, callback) {
|
|
1058
1140
|
if (isFunction(options)) {
|
|
1059
1141
|
callback = options;
|
|
@@ -1071,9 +1153,8 @@ function expressRenderer(ejs) {
|
|
|
1071
1153
|
const filename = path.relative(viewPath, name);
|
|
1072
1154
|
viewOptions.path = viewPath;
|
|
1073
1155
|
viewOptions.cache = viewCache;
|
|
1074
|
-
|
|
1075
|
-
return
|
|
1076
|
-
.render(filename, options)
|
|
1156
|
+
configure(viewOptions);
|
|
1157
|
+
return render(filename, options)
|
|
1077
1158
|
.then((content) => {
|
|
1078
1159
|
callback(null, content);
|
|
1079
1160
|
})
|
|
@@ -1083,10 +1164,11 @@ function expressRenderer(ejs) {
|
|
|
1083
1164
|
}
|
|
1084
1165
|
}
|
|
1085
1166
|
|
|
1086
|
-
const
|
|
1087
|
-
|
|
1088
|
-
|
|
1167
|
+
const { render, context, compile, helpers, preload, configure, create } =
|
|
1168
|
+
new EJS({
|
|
1169
|
+
resolver: readFile,
|
|
1170
|
+
});
|
|
1089
1171
|
|
|
1090
|
-
const __express = expressRenderer(
|
|
1172
|
+
const __express = expressRenderer(configure, render);
|
|
1091
1173
|
|
|
1092
1174
|
export { TemplateError, TemplateNotFound, TemplateSyntaxError, __express, compile, configure, context, create, helpers, preload, render };
|