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