@kosatyi/ejs 0.0.76 → 0.0.78

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.
@@ -0,0 +1,1034 @@
1
+ const typeProp = function () {
2
+ const args = [].slice.call(arguments);
3
+ const callback = args.shift();
4
+ return args.filter(callback).pop()
5
+ };
6
+ const isArray = (v) => Array.isArray(v);
7
+ const isFunction = (v) => typeof v === 'function';
8
+ const isString = (v) => typeof v === 'string';
9
+ const isBoolean = (v) => typeof v === 'boolean';
10
+ const isUndefined = (v) => typeof v === 'undefined';
11
+
12
+ const isNodeEnv =
13
+ Object.prototype.toString.call(
14
+ typeof process !== 'undefined' ? process : 0
15
+ ) === '[object process]';
16
+
17
+ const isNode = () => isNodeEnv;
18
+
19
+ const symbolEntities = {
20
+ "'": "'",
21
+ '\\': '\\',
22
+ '\r': 'r',
23
+ '\n': 'n',
24
+ '\t': 't',
25
+ '\u2028': 'u2028',
26
+ '\u2029': 'u2029',
27
+ };
28
+
29
+ const htmlEntities = {
30
+ '&': '&',
31
+ '<': '&lt;',
32
+ '>': '&gt;',
33
+ '"': '&quot;',
34
+ "'": '&#x27;',
35
+ };
36
+
37
+ const regexKeys = (obj) =>
38
+ new RegExp(['[', Object.keys(obj).join(''), ']'].join(''), 'g');
39
+
40
+ const htmlEntitiesMatch = regexKeys(htmlEntities);
41
+
42
+ const symbolEntitiesMatch = regexKeys(symbolEntities);
43
+
44
+ const entities = (string = '') => {
45
+ return ('' + string).replace(
46
+ htmlEntitiesMatch,
47
+ (match) => htmlEntities[match]
48
+ )
49
+ };
50
+
51
+ const symbols = (string) => {
52
+ return ('' + string).replace(
53
+ symbolEntitiesMatch,
54
+ (match) => '\\' + symbolEntities[match]
55
+ )
56
+ };
57
+
58
+ const safeValue = (value, escape) => {
59
+ const check = value;
60
+ return check == null ? '' : escape === true ? entities(check) : check
61
+ };
62
+
63
+ const instanceOf = (object, instance) => {
64
+ return Boolean(object instanceof instance)
65
+ };
66
+
67
+ const getPath = (context, name, strict) => {
68
+ let data = context;
69
+ let chunks = String(name).split('.');
70
+ let prop = chunks.pop();
71
+ for (let i = 0; i < chunks.length; i++) {
72
+ const part = chunks[i];
73
+ if (isFunction(data['toJSON'])) {
74
+ data = data.toJSON();
75
+ }
76
+ if (strict && data.hasOwnProperty(part) === false) {
77
+ data = {};
78
+ break
79
+ }
80
+ data = data[part] = data[part] || {};
81
+ }
82
+ if (isFunction(data['toJSON'])) {
83
+ data = data.toJSON();
84
+ }
85
+ return [data, prop]
86
+ };
87
+
88
+ const ext = (path, defaults) => {
89
+ const ext = path.split('.').pop();
90
+ if (ext !== defaults) {
91
+ path = [path, defaults].join('.');
92
+ }
93
+ return path
94
+ };
95
+
96
+ /**
97
+ * @type {<T extends {}, U, V, W,Y>(T,U,V,W,Y)=> T & U & V & W & Y}
98
+ */
99
+ const extend = (target, ...args) => {
100
+ return args
101
+ .filter((source) => source)
102
+ .reduce((target, source) => Object.assign(target, source), target)
103
+ };
104
+
105
+ const noop = () => {};
106
+
107
+ const each = (object, callback) => {
108
+ let prop;
109
+ for (prop in object) {
110
+ if (hasProp(object, prop)) {
111
+ callback(object[prop], prop, object);
112
+ }
113
+ }
114
+ };
115
+
116
+ const map = (object, callback, context) => {
117
+ const result = [];
118
+ each(
119
+ object,
120
+ (value, key, object) => {
121
+ let item = callback(value, key, object);
122
+ if (isUndefined(item) === false) {
123
+ result.push(item);
124
+ }
125
+ });
126
+ return result
127
+ };
128
+
129
+ const filter = (object, callback, context) => {
130
+ const isArray = object instanceof Array;
131
+ const result = isArray ? [] : {};
132
+ each(
133
+ object,
134
+ (value, key, object) => {
135
+ let item = callback(value, key, object);
136
+ if (isUndefined(item) === false) {
137
+ if (isArray) {
138
+ result.push(item);
139
+ } else {
140
+ result[key] = item;
141
+ }
142
+ }
143
+ });
144
+ return result
145
+ };
146
+
147
+ const omit = (object, list) => {
148
+ return filter(object, (value, key) => {
149
+ if (list.indexOf(key) === -1) {
150
+ return value
151
+ }
152
+ })
153
+ };
154
+
155
+ const resolve$1 = (value, callback, context) =>
156
+ Promise.resolve(value).then(callback.bind(context));
157
+
158
+ const hasProp = (object, prop) => {
159
+ return object && object.hasOwnProperty(prop)
160
+ };
161
+
162
+ const defaults = {};
163
+
164
+ defaults.export = 'ejsPrecompiled';
165
+ defaults.cache = true;
166
+ defaults.chokidar = null;
167
+ defaults.path = 'views';
168
+ defaults.resolver = function (path, template) {
169
+ return Promise.resolve(
170
+ ['resolver is not defined', path, template].join(' ')
171
+ )
172
+ };
173
+ defaults.extension = 'ejs';
174
+ defaults.rmWhitespace = true;
175
+ defaults.withObject = true;
176
+ defaults.globalHelpers = [];
177
+ defaults.vars = {
178
+ SCOPE: 'ejs',
179
+ COMPONENT: 'ui',
180
+ EXTEND: '$$e',
181
+ BUFFER: '$$a',
182
+ LAYOUT: '$$l',
183
+ BLOCKS: '$$b',
184
+ MACRO: '$$m',
185
+ SAFE: '$$v',
186
+ };
187
+ defaults.token = {
188
+ start: '<%',
189
+ end: '%>',
190
+ regex: '([\\s\\S]+?)',
191
+ };
192
+
193
+ const configSchema = (config, options) => {
194
+ extend(config, {
195
+ path: typeProp(isString, defaults.path, config.path, options.path),
196
+ export: typeProp(
197
+ isString,
198
+ defaults.export,
199
+ config.export,
200
+ options.export
201
+ ),
202
+ resolver: typeProp(
203
+ isFunction,
204
+ defaults.resolver,
205
+ config.resolver,
206
+ options.resolver
207
+ ),
208
+ extension: typeProp(
209
+ isString,
210
+ defaults.extension,
211
+ config.extension,
212
+ options.extension
213
+ ),
214
+ withObject: typeProp(
215
+ isBoolean,
216
+ defaults.withObject,
217
+ config.withObject,
218
+ options.withObject
219
+ ),
220
+ rmWhitespace: typeProp(
221
+ isBoolean,
222
+ defaults.rmWhitespace,
223
+ config.rmWhitespace,
224
+ options.rmWhitespace
225
+ ),
226
+ cache: typeProp(isBoolean, defaults.cache, config.cache, options.cache),
227
+ token: extend({}, defaults.token, config.token, options.token),
228
+ vars: extend({}, defaults.vars, config.vars, options.vars),
229
+ globalHelpers: typeProp(
230
+ isArray,
231
+ defaults.globalHelpers,
232
+ config.globalHelpers,
233
+ options.globalHelpers
234
+ ),
235
+ });
236
+ };
237
+
238
+ const global = typeof globalThis !== 'undefined' ? globalThis : window || self;
239
+
240
+ function Cache(config) {
241
+ if (instanceOf(this, Cache) === false) return new Cache()
242
+ const cache = {
243
+ enabled: true,
244
+ list: {},
245
+ };
246
+ this.configure = function (config) {
247
+ cache.enabled = config.cache;
248
+ if (isNode() === false) {
249
+ this.load(global[config.export]);
250
+ }
251
+ };
252
+ this.clear = function () {
253
+ cache.list = {};
254
+ };
255
+ this.load = function (data) {
256
+ if (cache.enabled) {
257
+ extend(cache.list, data || {});
258
+ }
259
+ return this
260
+ };
261
+ this.get = function (key) {
262
+ if (cache.enabled) {
263
+ return cache.list[key]
264
+ }
265
+ };
266
+ this.set = function (key, value) {
267
+ if (cache.enabled) {
268
+ cache.list[key] = value;
269
+ }
270
+ return this
271
+ };
272
+ this.resolve = function (key) {
273
+ return Promise.resolve(this.get(key))
274
+ };
275
+ this.remove = function (key) {
276
+ delete cache.list[key];
277
+ };
278
+ this.exist = function (key) {
279
+ return hasProp(cache.list, key)
280
+ };
281
+ }
282
+
283
+ const tagList = [
284
+ {
285
+ symbol: '-',
286
+ format(value) {
287
+ return `')\n${this.BUFFER}(${this.SAFE}(${value},1))\n${this.BUFFER}('`
288
+ },
289
+ },
290
+ {
291
+ symbol: '=',
292
+ format(value) {
293
+ return `')\n${this.BUFFER}(${this.SAFE}(${value}))\n${this.BUFFER}('`
294
+ },
295
+ },
296
+ {
297
+ symbol: '#',
298
+ format(value) {
299
+ return `')\n/**${value}**/\n${this.BUFFER}('`
300
+ },
301
+ },
302
+ {
303
+ symbol: '',
304
+ format(value) {
305
+ return `')\n${value.trim()}\n${this.BUFFER}('`
306
+ },
307
+ },
308
+ ];
309
+
310
+ function matchTokens(regex, text, callback) {
311
+ let index = 0;
312
+ text.replace(regex, function () {
313
+ const params = [].slice.call(arguments, 0, -1);
314
+ const offset = params.pop();
315
+ const match = params.shift();
316
+ callback(params, index, offset);
317
+ index = offset + match.length;
318
+ return match
319
+ });
320
+ }
321
+
322
+ function Compiler(config) {
323
+ if (instanceOf(this, Compiler) === false) return new Compiler(config)
324
+
325
+ const compiler = {};
326
+
327
+ this.configure = function (config) {
328
+ compiler.withObject = config.withObject;
329
+ compiler.rmWhitespace = config.rmWhitespace;
330
+ compiler.token = config.token;
331
+ compiler.vars = config.vars;
332
+ compiler.globalHelpers = config.globalHelpers;
333
+ compiler.matches = [];
334
+ compiler.formats = [];
335
+ compiler.slurp = {
336
+ match: '[ \\t]*',
337
+ start: [compiler.token.start, '_'],
338
+ end: ['_', compiler.token.end],
339
+ };
340
+ tagList.forEach((item) => {
341
+ compiler.matches.push(
342
+ compiler.token.start
343
+ .concat(item.symbol)
344
+ .concat(compiler.token.regex)
345
+ .concat(compiler.token.end)
346
+ );
347
+ compiler.formats.push(item.format.bind(compiler.vars));
348
+ });
349
+ compiler.regex = new RegExp(
350
+ compiler.matches.join('|').concat('|$'),
351
+ 'g'
352
+ );
353
+ compiler.slurpStart = new RegExp(
354
+ [compiler.slurp.match, compiler.slurp.start.join('')].join(''),
355
+ 'gm'
356
+ );
357
+ compiler.slurpEnd = new RegExp(
358
+ [compiler.slurp.end.join(''), compiler.slurp.match].join(''),
359
+ 'gm'
360
+ );
361
+ };
362
+
363
+ this.compile = function (content, path) {
364
+ const { SCOPE, SAFE, BUFFER, COMPONENT } = compiler.vars;
365
+ const GLOBALS = compiler.globalHelpers;
366
+ content = String(content);
367
+ if (compiler.rmWhitespace) {
368
+ content = content
369
+ .replace(/[\r\n]+/g, '\n')
370
+ .replace(/^\s+|\s+$/gm, '');
371
+ }
372
+ content = content
373
+ .replace(compiler.slurpStart, compiler.token.start)
374
+ .replace(compiler.slurpEnd, compiler.token.end);
375
+ let source = `${BUFFER}('`;
376
+ matchTokens(compiler.regex, content, (params, index, offset) => {
377
+ source += symbols(content.slice(index, offset));
378
+ params.forEach((value, index) => {
379
+ if (value) {
380
+ source += compiler.formats[index](value);
381
+ }
382
+ });
383
+ });
384
+ source += `');`;
385
+ source = `try{${source}}catch(e){return ${BUFFER}.error(e)}`;
386
+ if (compiler.withObject) {
387
+ source = `with(${SCOPE}){${source}}`;
388
+ }
389
+ source = `${BUFFER}.start();${source}return ${BUFFER}.end();`;
390
+ source += `\n//# sourceURL=${path}`;
391
+ let result = null;
392
+ let params = [SCOPE, COMPONENT, BUFFER, SAFE].concat(GLOBALS);
393
+ try {
394
+ result = Function.apply(null, params.concat(source));
395
+ result.source = `(function(${params.join(',')}){\n${source}\n})`;
396
+ } catch (e) {
397
+ e.filename = path;
398
+ e.source = source;
399
+ throw e
400
+ }
401
+ return result
402
+ };
403
+
404
+ this.configure(config);
405
+ }
406
+
407
+ function Template(config, cache, compiler) {
408
+ if (instanceOf(this, Template) === false)
409
+ return new Template(config, cache, compiler)
410
+
411
+ if (instanceOf(cache, Cache) === false)
412
+ throw new TypeError('cache is not instance of Cache')
413
+
414
+ if (instanceOf(compiler, Compiler) === false)
415
+ throw new TypeError('compiler is not instance of Compiler')
416
+
417
+ const template = {};
418
+
419
+ const result = (template, content) => {
420
+ cache.set(template, content);
421
+ return content
422
+ };
423
+
424
+ const resolve = (path) => {
425
+ return template.resolver(template.path, path)
426
+ };
427
+
428
+ const compile = (content, template) => {
429
+ if (isFunction(content)) {
430
+ return content
431
+ } else {
432
+ return compiler.compile(content, template)
433
+ }
434
+ };
435
+
436
+ this.configure = function (config) {
437
+ template.path = config.path;
438
+ template.cache = config.cache;
439
+ if (isFunction(config.resolver)) {
440
+ template.resolver = config.resolver;
441
+ }
442
+ };
443
+
444
+ this.get = function (template) {
445
+ if (cache.exist(template)) {
446
+ return cache.resolve(template)
447
+ }
448
+ return resolve(template).then((content) =>
449
+ result(template, compile(content, template))
450
+ )
451
+ };
452
+ this.configure(config);
453
+ }
454
+
455
+ const selfClosed = [
456
+ 'area',
457
+ 'base',
458
+ 'br',
459
+ 'col',
460
+ 'embed',
461
+ 'hr',
462
+ 'img',
463
+ 'input',
464
+ 'link',
465
+ 'meta',
466
+ 'param',
467
+ 'source',
468
+ 'track',
469
+ 'wbr',
470
+ ];
471
+
472
+ const space = ' ';
473
+ const quote = '"';
474
+ const equal = '=';
475
+ const slash = '/';
476
+ const lt = '<';
477
+ const gt = '>';
478
+
479
+ const element = (tag, attrs, content) => {
480
+ const result = [];
481
+ const hasClosedTag = selfClosed.indexOf(tag) === -1;
482
+ const attributes = map(attrs, (value, key) => {
483
+ if (value !== null && value !== undefined) {
484
+ return [
485
+ entities(key),
486
+ [quote, entities(value), quote].join(''),
487
+ ].join(equal)
488
+ }
489
+ }).join(space);
490
+ result.push([lt, tag, space, attributes, gt].join(''));
491
+ if (content) {
492
+ result.push(content instanceof Array ? content.join('') : content);
493
+ }
494
+ if (hasClosedTag) {
495
+ result.push([lt, slash, tag, gt].join(''));
496
+ }
497
+ return result.join('')
498
+ };
499
+
500
+ function TemplateError(message) {
501
+ this.code = 1;
502
+ this.name = 'TemplateError';
503
+ this.message = message;
504
+ Error.call(this);
505
+ }
506
+ Object.setPrototypeOf(TemplateNotFound.prototype, Error.prototype);
507
+
508
+ function TemplateNotFound(message) {
509
+ TemplateError.call(this);
510
+ this.code = 404;
511
+ this.name = 'TemplateNotFound';
512
+ this.message = message;
513
+ }
514
+
515
+ Object.setPrototypeOf(TemplateNotFound.prototype, TemplateError.prototype);
516
+
517
+ function TemplateSyntaxError(message) {
518
+ TemplateError.call(this);
519
+ this.code = 500;
520
+ this.name = 'TemplateSyntaxError';
521
+ this.message = message;
522
+ }
523
+
524
+ Object.setPrototypeOf(TemplateSyntaxError.prototype, TemplateError.prototype);
525
+
526
+ function resolve(list) {
527
+ return Promise.all(list || []).then((list) => list.join(''))
528
+ }
529
+
530
+ function reject(error) {
531
+ return Promise.reject(new TemplateSyntaxError(error.message))
532
+ }
533
+
534
+ function createBuffer() {
535
+ let store = [],
536
+ array = [];
537
+ function buffer(value) {
538
+ array.push(value);
539
+ }
540
+ buffer.start = function () {
541
+ array = [];
542
+ };
543
+ buffer.backup = function () {
544
+ store.push(array.concat());
545
+ array = [];
546
+ };
547
+ buffer.restore = function () {
548
+ const result = array.concat();
549
+ array = store.pop();
550
+ return resolve(result)
551
+ };
552
+ buffer.error = function (e) {
553
+ return reject(e)
554
+ };
555
+ buffer.end = function () {
556
+ return resolve(array)
557
+ };
558
+ return buffer
559
+ }
560
+
561
+ function Context(config) {
562
+ if (instanceOf(this, Context) === false) return new Context(config)
563
+ this.configure = function (config, methods) {
564
+ const { BLOCKS, MACRO, EXTEND, LAYOUT, BUFFER, COMPONENT } = config.vars;
565
+
566
+ this.create = function (data) {
567
+ return new Scope(data)
568
+ };
569
+
570
+ this.helpers = function (methods) {
571
+ extend(Scope.prototype, methods || {});
572
+ };
573
+ /**
574
+ * @name ContextScope
575
+ * @param data
576
+ * @constructor
577
+ */
578
+ function Scope(data) {
579
+ this[BLOCKS] = {};
580
+ this[MACRO] = {};
581
+ extend(this, data || {});
582
+ }
583
+
584
+ Scope.prototype = extend({}, methods || {});
585
+ Object.defineProperties(Scope.prototype, {
586
+ [BUFFER]: {
587
+ value: createBuffer(),
588
+ writable: true,
589
+ configurable: false,
590
+ enumerable: false,
591
+ },
592
+ [BLOCKS]: {
593
+ value: {},
594
+ writable: true,
595
+ configurable: false,
596
+ enumerable: false,
597
+ },
598
+ [MACRO]: {
599
+ value: {},
600
+ writable: true,
601
+ configurable: false,
602
+ enumerable: false,
603
+ },
604
+ [LAYOUT]: {
605
+ value: false,
606
+ writable: true,
607
+ configurable: false,
608
+ enumerable: false,
609
+ },
610
+ [EXTEND]: {
611
+ value: false,
612
+ writable: true,
613
+ configurable: false,
614
+ enumerable: false,
615
+ },
616
+ getMacro: {
617
+ value() {
618
+ return this[MACRO]
619
+ },
620
+ writable: false,
621
+ configurable: false,
622
+ enumerable: false,
623
+ },
624
+ getBuffer: {
625
+ value() {
626
+ return this[BUFFER]
627
+ },
628
+ writable: false,
629
+ configurable: false,
630
+ enumerable: false,
631
+ },
632
+ getComponent: {
633
+ value() {
634
+ const context = this;
635
+ if (COMPONENT in context) {
636
+ return function () {
637
+ return context[COMPONENT].apply(context, arguments)
638
+ }
639
+ }
640
+ return function () {
641
+ console.log('%s function not defined', COMPONENT);
642
+ }
643
+ },
644
+ writable: false,
645
+ configurable: false,
646
+ enumerable: false,
647
+ },
648
+ getBlocks: {
649
+ value() {
650
+ return this[BLOCKS]
651
+ },
652
+ writable: false,
653
+ configurable: false,
654
+ enumerable: false,
655
+ },
656
+ setExtend: {
657
+ value(value) {
658
+ this[EXTEND] = value;
659
+ },
660
+ writable: false,
661
+ configurable: false,
662
+ enumerable: false,
663
+ },
664
+ getExtend: {
665
+ value() {
666
+ return this[EXTEND]
667
+ },
668
+ writable: false,
669
+ configurable: false,
670
+ enumerable: false,
671
+ },
672
+ setLayout: {
673
+ value(layout) {
674
+ this[LAYOUT] = layout;
675
+ },
676
+ writable: false,
677
+ configurable: false,
678
+ enumerable: false,
679
+ },
680
+ getLayout: {
681
+ value() {
682
+ return this[LAYOUT]
683
+ },
684
+ writable: false,
685
+ configurable: false,
686
+ enumerable: false,
687
+ },
688
+ clone: {
689
+ value(exclude_blocks) {
690
+ const filter = [LAYOUT, EXTEND, BUFFER];
691
+ if (exclude_blocks === true) {
692
+ filter.push(BLOCKS);
693
+ }
694
+ return omit(this, filter)
695
+ },
696
+ writable: false,
697
+ configurable: false,
698
+ enumerable: false,
699
+ },
700
+
701
+ extend: {
702
+ value(layout) {
703
+ this.setExtend(true);
704
+ this.setLayout(layout);
705
+ },
706
+ writable: false,
707
+ configurable: false,
708
+ enumerable: false,
709
+ },
710
+ echo: {
711
+ value(layout) {
712
+ const buffer = this.getBuffer();
713
+ const params = [].slice.call(arguments);
714
+ params.forEach(buffer);
715
+ },
716
+ writable: false,
717
+ configurable: false,
718
+ enumerable: false,
719
+ },
720
+ fn: {
721
+ value(callback) {
722
+ const buffer = this.getBuffer();
723
+ const context = this;
724
+ return function () {
725
+ buffer.backup();
726
+ if (isFunction(callback)) {
727
+ callback.apply(context, arguments);
728
+ }
729
+ return buffer.restore()
730
+ }
731
+ },
732
+ writable: false,
733
+ configurable: false,
734
+ enumerable: false,
735
+ },
736
+ get: {
737
+ value(name, defaults) {
738
+ const path = getPath(this, name, true);
739
+ const result = path.shift();
740
+ const prop = path.pop();
741
+ return hasProp(result, prop) ? result[prop] : defaults
742
+ },
743
+ writable: true,
744
+ configurable: true,
745
+ enumerable: false,
746
+ },
747
+ set: {
748
+ value(name, value) {
749
+ const path = getPath(this, name, false);
750
+ const result = path.shift();
751
+ const prop = path.pop();
752
+ if (this.getExtend() && hasProp(result, prop)) {
753
+ return result[prop]
754
+ }
755
+ return (result[prop] = value)
756
+ },
757
+ writable: false,
758
+ configurable: false,
759
+ enumerable: false,
760
+ },
761
+ macro: {
762
+ value(name, callback) {
763
+ const list = this.getMacro();
764
+ const macro = this.fn(callback);
765
+ const context = this;
766
+ list[name] = function () {
767
+ return context.echo(macro.apply(undefined, arguments))
768
+ };
769
+ },
770
+ writable: false,
771
+ configurable: false,
772
+ enumerable: false,
773
+ },
774
+ call: {
775
+ value(name) {
776
+ const list = this.getMacro();
777
+ const macro = list[name];
778
+ const params = [].slice.call(arguments, 1);
779
+ if (isFunction(macro)) {
780
+ return macro.apply(macro, params)
781
+ }
782
+ },
783
+ writable: false,
784
+ configurable: false,
785
+ enumerable: false,
786
+ },
787
+ block: {
788
+ value(name, callback) {
789
+ const blocks = this.getBlocks();
790
+ blocks[name] = blocks[name] || [];
791
+ blocks[name].push(this.fn(callback));
792
+ if (this.getExtend()) return
793
+ const list = Object.assign([], blocks[name]);
794
+ const current = function () {
795
+ return list.shift()
796
+ };
797
+ const next = () => {
798
+ const parent = current();
799
+ if (parent) {
800
+ return () => {
801
+ this.echo(parent(next()));
802
+ }
803
+ } else {
804
+ return noop
805
+ }
806
+ };
807
+ this.echo(current()(next()));
808
+ },
809
+ writable: false,
810
+ configurable: false,
811
+ enumerable: false,
812
+ },
813
+ include: {
814
+ value(path, data, cx) {
815
+ const context = cx === false ? {} : this.clone(true);
816
+ const params = extend(context, data || {});
817
+ const promise = this.render(path, params);
818
+ this.echo(promise);
819
+ },
820
+ writable: false,
821
+ configurable: false,
822
+ enumerable: false,
823
+ },
824
+ use: {
825
+ value(path, namespace) {
826
+ const promise = this.require(path);
827
+ this.echo(
828
+ resolve$1(
829
+ promise,
830
+ function (exports) {
831
+ const list = this.getMacro();
832
+ each(exports, function (macro, name) {
833
+ list[[namespace, name].join('.')] = macro;
834
+ });
835
+ },
836
+ this
837
+ )
838
+ );
839
+ },
840
+ writable: false,
841
+ configurable: false,
842
+ enumerable: false,
843
+ },
844
+ async: {
845
+ value(promise, callback) {
846
+ this.echo(
847
+ resolve$1(
848
+ promise,
849
+ function (data) {
850
+ return this.fn(callback)(data)
851
+ },
852
+ this
853
+ )
854
+ );
855
+ },
856
+ writable: false,
857
+ configurable: false,
858
+ enumerable: false,
859
+ },
860
+ each: {
861
+ value: function (object, callback) {
862
+ if (isString(object)) {
863
+ object = this.get(object, []);
864
+ }
865
+ each(object, callback);
866
+ },
867
+ writable: false,
868
+ configurable: false,
869
+ enumerable: false,
870
+ },
871
+ element: {
872
+ value(tag, attr, content) {
873
+ return element(tag, attr, content)
874
+ },
875
+ writable: false,
876
+ configurable: false,
877
+ enumerable: false,
878
+ },
879
+ el: {
880
+ value(tag, attr, content) {
881
+ if (isFunction(content)) {
882
+ content = this.fn(content)();
883
+ }
884
+ this.echo(
885
+ resolve$1(
886
+ content,
887
+ function (content) {
888
+ return this.element(tag, attr, content)
889
+ },
890
+ this
891
+ )
892
+ );
893
+ },
894
+ writable: false,
895
+ configurable: false,
896
+ enumerable: false,
897
+ },
898
+ });
899
+ };
900
+ this.configure(config);
901
+ }
902
+
903
+ function EJS(options) {
904
+ if (instanceOf(this, EJS) === false) return new EJS(options)
905
+
906
+ const scope = {};
907
+ const config = {};
908
+
909
+ configSchema(config, options || {});
910
+
911
+ const context = new Context(config);
912
+ const compiler = new Compiler(config);
913
+ const cache = new Cache();
914
+ const template = new Template(config, cache, compiler);
915
+
916
+ const output = (path, scope) => {
917
+ const { globalHelpers } = config;
918
+ const params = [
919
+ scope,
920
+ scope.getComponent(),
921
+ scope.getBuffer(),
922
+ safeValue,
923
+ ].concat(
924
+ globalHelpers
925
+ .filter((name) => isFunction(scope[name]))
926
+ .map((name) => scope[name].bind(scope))
927
+ );
928
+ return template
929
+ .get(path)
930
+ .then((callback) => callback.apply(scope, params))
931
+ };
932
+
933
+ const require = (name) => {
934
+ const filepath = ext(name, config.extension);
935
+ const scope = context.create({});
936
+ return output(filepath, scope).then(() => scope.getMacro())
937
+ };
938
+ const render = (name, data) => {
939
+ const filepath = ext(name, config.extension);
940
+ const scope = context.create(data);
941
+ return output(filepath, scope).then((content) => {
942
+ if (scope.getExtend()) {
943
+ scope.setExtend(false);
944
+ const layout = scope.getLayout();
945
+ const data = scope.clone();
946
+ return render(layout, data)
947
+ }
948
+ return content
949
+ })
950
+ };
951
+ this.configure = function (options) {
952
+ options = options || {};
953
+ configSchema(config, options);
954
+ context.configure(config, scope);
955
+ compiler.configure(config);
956
+ cache.configure(config);
957
+ template.configure(config);
958
+ return config
959
+ };
960
+ this.render = function (name, data) {
961
+ return render(name, data)
962
+ };
963
+ this.helpers = function (methods) {
964
+ context.helpers(extend(scope, methods));
965
+ };
966
+ this.preload = function (list) {
967
+ return cache.load(list || {})
968
+ };
969
+ this.create = function (options) {
970
+ return new EJS(options)
971
+ };
972
+ this.compile = function (content, path) {
973
+ return compiler.compile(content, path)
974
+ };
975
+ this.context = function (data) {
976
+ return context.create(data)
977
+ };
978
+ this.helpers({ require, render });
979
+ return this
980
+ }
981
+
982
+ const templateCache = {};
983
+
984
+ const ejs = new EJS({
985
+ cache: false,
986
+ withObject: false,
987
+ resolver(path, name) {
988
+ return new Promise((resolve, reject) => {
989
+ if (templateCache.hasOwnProperty(name)) {
990
+ resolve(templateCache[name]);
991
+ } else {
992
+ reject(new TemplateNotFound(`template ${name} not found`));
993
+ }
994
+ })
995
+ },
996
+ });
997
+
998
+ const getOrigin = (url, secure) => {
999
+ url = new URL(url);
1000
+ if (secure) url.protocol = 'https:';
1001
+ return url.origin
1002
+ };
1003
+
1004
+ function setTemplates(list) {
1005
+ Object.assign(templateCache, list || {});
1006
+ }
1007
+
1008
+ /**
1009
+ * @typedef {Object<string,any>} HonoContext
1010
+ * @property {function(*):Promise<Response>} html
1011
+ * @property {function(name:string,data:{}):Promise<string>} render
1012
+ * @property {function(name:string,data:{}):Promise<string>} ejs
1013
+ * @property {ContextScope} data
1014
+ */
1015
+
1016
+ /**
1017
+ *
1018
+ * @param {Object<string,any>} options
1019
+ * @return {(function(c:Context, next): Promise<any>)|*}
1020
+ */
1021
+ function setRenderer({ secure = true, version = '1.0' }) {
1022
+ return async (c, next) => {
1023
+ c.data = context({});
1024
+ c.data.set('version', version);
1025
+ c.data.set('origin', getOrigin(c.req.url, secure));
1026
+ c.ejs = (name, data) => render(name, Object.assign({}, c.data, data));
1027
+ c.render = (name, data) => c.html(c.ejs(name, data));
1028
+ await next();
1029
+ }
1030
+ }
1031
+
1032
+ const { render, context, compile, helpers, preload, configure, create } = ejs;
1033
+
1034
+ export { compile, configure, context, create, helpers, preload, render, setRenderer, setTemplates };