@kosatyi/ejs 0.0.13 → 0.0.15

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 CHANGED
@@ -12,21 +12,17 @@ defaults.path = 'views';
12
12
 
13
13
  defaults.resolver = null;
14
14
 
15
- defaults.extension = {
16
- template: 'ejs',
17
- module: 'mjs',
18
- };
15
+ defaults.extension = 'ejs';
16
+
17
+ defaults.withObject = false;
19
18
 
20
19
  defaults.vars = {
21
- EXTEND: '$$$',
20
+ SCOPE: 'ejs',
21
+ EXTEND: '$$e',
22
22
  BUFFER: '$$a',
23
- OUTPUT: '$$i',
24
23
  LAYOUT: '$$l',
25
- MACROS: '$$m',
26
- PRINT: '$$j',
27
24
  BLOCKS: '$$b',
28
- ERROR: '$$e',
29
- SCOPE: '$$s',
25
+ MACRO: '$$m',
30
26
  SAFE: '$$v',
31
27
  };
32
28
 
@@ -41,7 +37,6 @@ const typeProp = function () {
41
37
  const callback = args.shift();
42
38
  return args.filter(callback).pop()
43
39
  };
44
-
45
40
  const isFunction = (v) => typeof v === 'function';
46
41
  const isString = (v) => typeof v === 'string';
47
42
  const isBoolean = (v) => typeof v === 'boolean';
@@ -112,6 +107,8 @@ const extend = (...args) => {
112
107
  }, target)
113
108
  };
114
109
 
110
+ const noop = () => {};
111
+
115
112
  const each = (object, callback) => {
116
113
  let prop;
117
114
  for (prop in object) {
@@ -160,6 +157,9 @@ const omit = (object, list) => {
160
157
  })
161
158
  };
162
159
 
160
+ const resolve$1 = (value,callback,context) =>
161
+ Promise.resolve(value).then(callback.bind(context));
162
+
163
163
  const hasProp = (object, prop) => {
164
164
  return object && object.hasOwnProperty(prop)
165
165
  };
@@ -249,14 +249,14 @@ const match = (regex, text, callback) => {
249
249
  };
250
250
  /**
251
251
  *
252
- * @param {Object} config
252
+ * @param {object} config
253
253
  * @return {function(*, *): Function}
254
254
  * @constructor
255
255
  */
256
256
  const Compiler = (config) => {
257
+ const withObject = config.withObject;
257
258
  const token = config.token;
258
259
  const vars = config.vars;
259
- const module = config.extension.module;
260
260
  const matches = [];
261
261
  const formats = [];
262
262
  const slurp = {
@@ -277,19 +277,15 @@ const Compiler = (config) => {
277
277
  const slurpStart = new RegExp([slurp.match, slurp.start].join(''), 'gm');
278
278
  const slurpEnd = new RegExp([slurp.end, slurp.match].join(''), 'gm');
279
279
  /**
280
- * @type Function
280
+ * @type function
281
281
  * @name Compile
282
282
  */
283
283
  return function (content, path) {
284
284
  const { SCOPE, SAFE, BUFFER } = vars;
285
- const extension = path.split('.').pop();
286
285
  content = content.replace(/[\r\n]+/g, '\n').replace(/^\s+|\s+$/gm, '');
287
286
  content = content
288
287
  .replace(slurpStart, slurp.start)
289
288
  .replace(slurpEnd, slurp.end);
290
- if (extension === module) {
291
- content = [token.start, content, token.end].join('\n');
292
- }
293
289
  let source = `${BUFFER}('`;
294
290
  match(regex, content, (params, index, offset) => {
295
291
  source += symbols(content.slice(index, offset));
@@ -298,15 +294,18 @@ const Compiler = (config) => {
298
294
  });
299
295
  });
300
296
  source += `');`;
301
- source = `with(${SCOPE}){${source}}`;
297
+ source = `try{${source}}catch(e){console.info(e)}`;
298
+ if(withObject) {
299
+ source = `with(${SCOPE}){${source}}`;
300
+ }
302
301
  source = `${BUFFER}.start();${source}return ${BUFFER}.end();`;
303
302
  source += `\n//# sourceURL=${path}`;
304
303
  let result = null;
305
304
  try {
306
305
  result = new Function(SCOPE, BUFFER, SAFE, source);
307
306
  result.source = `(function(${SCOPE},${BUFFER},${SAFE}){\n${source}\n})`;
308
- //result.source = result.toString()
309
307
  } catch (e) {
308
+ console.log(e);
310
309
  e.filename = path;
311
310
  e.source = source;
312
311
  throw e
@@ -417,6 +416,9 @@ const Buffer = () => {
417
416
  array = store.pop();
418
417
  return resolve(result)
419
418
  };
419
+ buffer.error = function(e){
420
+ throw e
421
+ };
420
422
  buffer.end = function () {
421
423
  return resolve(array)
422
424
  };
@@ -424,27 +426,16 @@ const Buffer = () => {
424
426
  };
425
427
 
426
428
  /**
427
- *
428
- * @param {{}} instance
429
- * @method create
429
+ * @memberOf global
430
+ * @class
431
+ * @alias ejs
432
+ * @param config
433
+ * @param methods
434
+ * @return {Scope}
430
435
  */
431
- const Component = (instance) => {
432
- const defaults = extend({}, instance.props);
433
- const create = instance.create;
434
- return {
435
- element,
436
- create,
437
- render(props) {
438
- return this.create(extend({}, defaults, props))
439
- },
440
- }
441
- };
442
436
 
443
- const Scope = (config, methods) => {
444
- /**
445
- *
446
- */
447
- const { EXTEND, MACROS, LAYOUT, BLOCKS, BUFFER } = config.vars;
437
+ const configure = (config, methods) => {
438
+ const { EXTEND, LAYOUT, BLOCKS, BUFFER, MACRO } = config.vars;
448
439
 
449
440
  /**
450
441
  *
@@ -452,336 +443,201 @@ const Scope = (config, methods) => {
452
443
  * @constructor
453
444
  */
454
445
  function Scope(data = {}) {
455
- this.setBlocks({});
446
+ this.initBlocks();
447
+ this.initMacro();
456
448
  extend(this, data);
457
- this.setLayout(false);
458
- this.setExtend(false);
459
449
  }
460
-
461
- /**
462
- *
463
- */
464
- Object.defineProperties(Scope.prototype, {
465
- [BUFFER]: {
466
- value: Buffer(),
450
+ Scope.helpers = (methods) => {
451
+ extend(Scope.prototype, methods);
452
+ };
453
+ Scope.property = (name, descriptor) => {
454
+ Object.defineProperty(Scope.prototype, name, descriptor);
455
+ };
456
+ Scope.method = (name, method) => {
457
+ Object.defineProperty(Scope.prototype, name, {
458
+ value: method,
467
459
  writable: false,
468
460
  configurable: false,
469
461
  enumerable: false
470
- },
471
- // [BLOCKS]: {
472
- // value: {},
473
- // writable: true,
474
- // configurable: false,
475
- // enumerable: false
476
- // },
477
- // [EXTEND]: {
478
- // value: false,
479
- // writable: true,
480
- // configurable: false,
481
- // enumerable: false
482
- // },
483
- // [LAYOUT]: {
484
- // value: false,
485
- // writable: true,
486
- // configurable: false,
487
- // enumerable: false
488
- // },
489
- // setBuffer: {
490
- // value(value) {
491
- // this[BUFFER] = value
492
- // },
493
- // writable: false,
494
- // configurable: false
495
- // },
496
- getBuffer: {
497
- value() {
498
- return this[BUFFER]
499
- },
500
- writable: false,
501
- configurable: false
502
- },
503
- setBlocks: {
504
- value(value) {
505
- this[BLOCKS] = value;
506
- },
507
- writable: false,
508
- configurable: false
509
- },
510
- getBlocks: {
511
- value() {
512
- return this[BLOCKS]
513
- },
514
- writable: false,
515
- configurable: false
516
- },
517
- setExtend: {
518
- value(value) {
519
- this[EXTEND] = value;
520
- },
521
- writable: false,
522
- configurable: false
523
- },
524
- getExtend: {
525
- value() {
526
- return this[EXTEND]
527
- },
528
- writable: false,
529
- configurable: false
530
- },
531
- setLayout: {
532
- value(layout) {
533
- this[LAYOUT] = layout;
534
- },
535
- writable: false,
536
- configurable: false
537
- },
538
- getLayout: {
539
- value() {
540
- return this[LAYOUT]
541
- },
542
- writable: false,
543
- configurable: false
462
+ });
463
+ };
464
+ Scope.property(BUFFER, {
465
+ value: Buffer(),
466
+ writable: false,
467
+ configurable: false,
468
+ enumerable: false
469
+ });
470
+ Scope.property(BLOCKS, {
471
+ value: {},
472
+ writable: true,
473
+ configurable: false,
474
+ enumerable: false
475
+ });
476
+ Scope.property(MACRO, {
477
+ value: {},
478
+ writable: true,
479
+ configurable: false,
480
+ enumerable: false
481
+ });
482
+ Scope.property(LAYOUT, {
483
+ value: false,
484
+ writable: true,
485
+ configurable: false,
486
+ enumerable: false
487
+ });
488
+ Scope.property(EXTEND, {
489
+ value: false,
490
+ writable: true,
491
+ configurable: false,
492
+ enumerable: false
493
+ });
494
+ Scope.method('initBlocks', function() {
495
+ this[BLOCKS] = {};
496
+ });
497
+ Scope.method('initMacro', function() {
498
+ this[MACRO] = {};
499
+ });
500
+ Scope.method('getMacro', function() {
501
+ return this[MACRO]
502
+ });
503
+ Scope.method('getBuffer', function() {
504
+ return this[BUFFER]
505
+ });
506
+ Scope.method('getBlocks', function() {
507
+ return this[BLOCKS]
508
+ });
509
+ Scope.method('setExtend', function(value) {
510
+ this[EXTEND] = value;
511
+ });
512
+ Scope.method('getExtend', function() {
513
+ return this[EXTEND]
514
+ });
515
+ Scope.method('setLayout', function(layout) {
516
+ this[LAYOUT] = layout;
517
+ });
518
+ Scope.method('getLayout', function() {
519
+ return this[LAYOUT]
520
+ });
521
+ Scope.method('clone', function(exclude_blocks) {
522
+ const filter = [LAYOUT, EXTEND, BUFFER];
523
+ if (exclude_blocks === true) {
524
+ filter.push(BLOCKS);
544
525
  }
526
+ return omit(this, filter)
545
527
  });
546
-
547
- Scope.helpers = (methods) => {
548
- extend(Scope.prototype, methods);
549
- };
550
-
551
- /**
552
- * @lends Scope.prototype
553
- */
554
- Scope.helpers(methods);
555
- /**
556
- * @lends Scope.prototype
557
- */
558
- Scope.helpers({
559
- /**
560
- * @return {*}
561
- */
562
- clone(exclude_blocks) {
563
- const filter = [LAYOUT, EXTEND, MACROS, BUFFER];
564
- if (exclude_blocks === true) {
565
- filter.push(BLOCKS);
528
+ Scope.method('extend', function(layout) {
529
+ this.setExtend(true);
530
+ this.setLayout(layout);
531
+ });
532
+ Scope.method('echo', function() {
533
+ const buffer = this.getBuffer();
534
+ const params = [].slice.call(arguments);
535
+ params.forEach(function(item) {
536
+ buffer(item);
537
+ });
538
+ });
539
+ Scope.method('fn', function(callback) {
540
+ const buffer = this.getBuffer();
541
+ const context = this;
542
+ return function() {
543
+ buffer.backup();
544
+ if (isFunction(callback)) {
545
+ callback.apply(context, arguments);
566
546
  }
567
- return omit(this, filter)
568
- },
569
- /**
570
- * Join values to output buffer
571
- * @memberOf global
572
- * @type Function
573
- */
574
- echo() {
575
- const buffer = this.getBuffer();
576
- const params = [].slice.call(arguments);
577
- params.forEach(function(item) {
578
- buffer(item);
579
- });
580
- },
581
- /**
582
- * Buffered output callback
583
- * @type Function
584
- * @param {Function} callback
585
- * @param {Boolean} [echo]
586
- * @return {Function}
587
- */
588
- macro(callback, echo) {
589
- const buffer = this.getBuffer();
590
- const macro = function() {
591
- buffer.backup();
592
- if (isFunction(callback)) {
593
- callback.apply(this, arguments);
547
+ return buffer.restore()
548
+ }
549
+ });
550
+ Scope.method('get', function(name,defaults) {
551
+ const path = getPath(this, name);
552
+ const result = path.shift();
553
+ const prop = path.pop();
554
+ return hasProp(result, prop) ? result[prop] : defaults
555
+ });
556
+ Scope.method('set', function(name,value) {
557
+ const path = getPath(this, name);
558
+ const result = path.shift();
559
+ const prop = path.pop();
560
+ if (this.getExtend() && hasProp(result, prop)) {
561
+ return result[prop]
562
+ }
563
+ return result[prop] = value
564
+ });
565
+ Scope.method('macro', function(name, callback) {
566
+ const list = this.getMacro();
567
+ const macro = this.fn(callback);
568
+ const context = this;
569
+ list[name] = function() {
570
+ return context.echo(macro.apply(undefined, arguments))
571
+ };
572
+ });
573
+ Scope.method('call', function(name) {
574
+ const list = this.getMacro();
575
+ const macro = list[name];
576
+ const params = [].slice.call(arguments, 1);
577
+ if (isFunction(macro)) {
578
+ return macro.apply(macro, params)
579
+ }
580
+ });
581
+ Scope.method('block',function(name,callback){
582
+ const blocks = this.getBlocks();
583
+ blocks[name] = blocks[name] || [];
584
+ blocks[name].push(this.fn(callback));
585
+ if (this.getExtend()) return
586
+ const list = Object.assign([], blocks[name]);
587
+ const current = function() {
588
+ return list.shift()
589
+ };
590
+ const next = () => {
591
+ const parent = current();
592
+ if (parent) {
593
+ return () => {
594
+ this.echo(parent(next()));
594
595
  }
595
- const result = buffer.restore();
596
- return echo === true ? this.echo(result) : result
597
- }.bind(this);
598
- macro.__context = this;
599
- macro.__source = callback;
600
- macro.__layout = this.getLayout();
601
- return macro
602
- },
603
- /**
604
- * @memberOf global
605
- * @param value
606
- * @param callback
607
- * @return {Promise<unknown>}
608
- */
609
- resolve(value, callback) {
610
- return Promise.resolve(value).then(callback.bind(this))
611
- },
612
- /**
613
- * @memberOf global
614
- */
615
- async(promise, callback) {
616
- this.echo(
617
- this.resolve(promise, (data) => this.macro(callback)(data))
618
- );
619
- },
620
- /**
621
- * @memberOf global
622
- */
623
- node: element,
624
- /**
625
- * @memberOf global
626
- */
627
- element(tag, attr, content) {
596
+ } else {
597
+ return noop
598
+ }
599
+ };
600
+ this.echo(current()(next()));
601
+ });
602
+ Scope.method('include',function(path, data, cx){
603
+ const context = cx === false ? {} : this.clone(true);
604
+ const params = extend(context, data || {});
605
+ const promise = this.render(path, params);
606
+ this.echo(promise);
607
+ });
608
+ Scope.method('use',function(path, namespace){
609
+ const promise = this.require(path);
610
+ this.echo(resolve$1(promise,function(exports){
611
+ const list = this.getMacro();
612
+ each(exports, function(macro, name) {
613
+ list[[namespace, name].join('.')] = macro;
614
+ });
615
+ },this));
616
+ });
617
+ Scope.method('async',function(promise,callback){
618
+ this.echo(
619
+ resolve$1(promise, function(data) {
620
+ return this.fn(callback)(data)
621
+ }, this)
622
+ );
623
+ });
624
+ Scope.helpers(methods);
625
+ Scope.helpers({
626
+ el(tag, attr, content) {
628
627
  if (isFunction(content)) {
629
- content = this.macro(content)();
628
+ content = this.fn(content)();
630
629
  }
631
630
  this.echo(
632
- this.resolve(content, (content) => element(tag, attr, content))
631
+ resolve$1(content, function(content) {
632
+ return element(tag, attr, content)
633
+ }, this)
633
634
  );
634
635
  },
635
- /**
636
- * @memberOf global
637
- * @param {String} namespace
638
- * @param {Object} instance
639
- */
640
- component(namespace, instance) {
641
- instance = Component(instance);
642
- this.set(
643
- namespace,
644
- function(props) {
645
- this.echo(instance.render(props));
646
- }.bind(this)
647
- );
648
- },
649
- /**
650
- * @memberOf global
651
- * @param name
652
- * @param defaults
653
- */
654
- get(name, defaults) {
655
- const path = getPath(this, name);
656
- const result = path.shift();
657
- const prop = path.pop();
658
- return hasProp(result, prop) ? result[prop] : defaults
659
- },
660
- /**
661
- * @memberOf global
662
- * @param {String} name
663
- * @param value
664
- * @return
665
- */
666
- set(name, value) {
667
- const path = getPath(this, name);
668
- const result = path.shift();
669
- const prop = path.pop();
670
- if (this.getExtend()) {
671
- if (hasProp(result, prop)) {
672
- return result[prop]
673
- }
674
- }
675
- result[prop] = value;
676
- },
677
- /**
678
- * @memberOf global
679
- * @param name
680
- */
681
- call(name) {
682
- const params = [].slice.call(arguments, 1);
683
- const path = getPath(this, name);
684
- const result = path.shift();
685
- const prop = path.pop();
686
- if (isFunction(result[prop])) {
687
- return result[prop].apply(result, params)
688
- }
689
- },
690
- /**
691
- * @memberOf global
692
- * @param object
693
- * @param callback
694
- */
695
636
  each(object, callback) {
696
637
  if (isString(object)) {
697
638
  object = this.get(object, []);
698
639
  }
699
640
  each(object, callback);
700
- },
701
- /**
702
- * @memberOf global
703
- * @param {String} layout
704
- */
705
- extend(layout) {
706
- this.setExtend(true);
707
- this.setLayout(layout);
708
- },
709
- /**
710
- * @memberOf global
711
- * @param name
712
- * @param callback
713
- * @return {*}
714
- */
715
- block(name, callback) {
716
- const blocks = this.getBlocks();
717
- blocks[name] = blocks[name] || [];
718
- blocks[name].push(this.macro(callback));
719
- if (this.getExtend()) return
720
- const current = function(){
721
- return blocks[name].shift()
722
- };
723
- const next = function() {
724
- const parent = current();
725
- if (parent) {
726
- const context = parent.__context;
727
- return function() {
728
- context.echo(parent(next()));
729
- }
730
- } else {
731
- return function() {
732
- }
733
- }
734
- };
735
- this.echo(current()(next()));
736
- },
737
- /**
738
- * @memberOf global
739
- * @param {string} path
740
- * @param {object} [data]
741
- * @param {boolean} [cx]
742
- */
743
- include(path, data, cx) {
744
- const context = cx === false ? {} : this.clone(true);
745
- const params = extend(context, data || {});
746
- const promise = this.render(path, params);
747
- this.echo(promise);
748
- },
749
- /**
750
- * @memberOf global
751
- * @param {string} path
752
- */
753
- use(path) {
754
- const scope = this;
755
- const promise = this.require(path);
756
- this.echo(promise);
757
- return {
758
- as(namespace) {
759
- promise.then((exports) => {
760
- scope.set(namespace, exports);
761
- });
762
- return this
763
- }
764
- }
765
- },
766
- /**
767
- * @memberOf global
768
- * @param {string} path
769
- */
770
- from(path) {
771
- const scope = this;
772
- const promise = this.require(path);
773
- this.echo(promise);
774
- return {
775
- use() {
776
- const params = [].slice.call(arguments);
777
- promise.then((exports) => {
778
- params.forEach((name) => {
779
- scope.set(name, exports[name]);
780
- });
781
- });
782
- return this
783
- }
784
- }
785
641
  }
786
642
  });
787
643
  return Scope
@@ -842,7 +698,7 @@ function init(options) {
842
698
  })
843
699
  },
844
700
  render(name, data) {
845
- const filepath = ext(name, config.extension.template);
701
+ const filepath = ext(name, config.extension);
846
702
  const scope = new view.scope(data);
847
703
  return view.output(filepath, scope).then((content) => {
848
704
  if (scope.getExtend()) {
@@ -855,10 +711,10 @@ function init(options) {
855
711
  })
856
712
  },
857
713
  require(name) {
858
- const filepath = ext(name, config.extension.module);
714
+ const filepath = ext(name, config.extension);
859
715
  const scope = new view.scope({});
860
716
  return view.output(filepath, scope).then(() => {
861
- return scope.clone(true)
717
+ return scope.getMacro()
862
718
  })
863
719
  },
864
720
  helpers(methods) {
@@ -874,10 +730,14 @@ function init(options) {
874
730
  defaults.resolver,
875
731
  options.resolver
876
732
  );
877
- config.extension = extend({}, defaults.extension, options.extension);
733
+ config.extension = typeProp(
734
+ isString,
735
+ defaults.extension,
736
+ options.extension
737
+ );
878
738
  config.token = extend({}, defaults.token, options.token);
879
739
  config.vars = extend({}, defaults.vars, options.vars);
880
- view.scope = Scope(config, helpers);
740
+ view.scope = configure(config, helpers);
881
741
  view.compile = Compiler(config);
882
742
  view.wrapper = Wrapper(config);
883
743
  view.cache = Cache(config);