@kosatyi/ejs 0.0.108 → 0.0.110

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/esm/index.js CHANGED
@@ -152,7 +152,7 @@ const symbols = (string) => {
152
152
  )
153
153
  };
154
154
 
155
- const safeValue = (value, escape) => {
155
+ const escapeValue = (value, escape) => {
156
156
  const check = value;
157
157
  return check == null
158
158
  ? ''
@@ -218,12 +218,27 @@ const bindContext = (object, methods = []) => {
218
218
  }
219
219
  };
220
220
 
221
- class Template {
221
+ class EjsError extends Error {
222
+ constructor(code, content) {
223
+ super(content);
224
+ this.code = code;
225
+ if (content instanceof Error) {
226
+ this.stack = content.stack;
227
+ this.message = content.message;
228
+ }
229
+ }
230
+ }
231
+
232
+ const error = (code, content) => {
233
+ throw new EjsError(code, content)
234
+ };
235
+
236
+ class EjsTemplate {
222
237
  #path
223
238
  #resolver
224
239
  #cache
225
240
  #compiler
226
- static exports = ['configure', 'get', 'compile']
241
+ static exports = ['configure', 'get']
227
242
  constructor(options, cache, compiler) {
228
243
  bindContext(this, this.constructor.exports);
229
244
  this.#cache = cache;
@@ -239,11 +254,13 @@ class Template {
239
254
  #resolve(template) {
240
255
  const cached = this.#cache.get(template);
241
256
  if (cached instanceof Promise) return cached
242
- const result = Promise.resolve(this.#resolver(this.#path, template));
257
+ const result = Promise.resolve(
258
+ this.#resolver(this.#path, template, error),
259
+ );
243
260
  this.#cache.set(template, result);
244
261
  return result
245
262
  }
246
- compile(content, template) {
263
+ #compile(content, template) {
247
264
  const cached = this.#cache.get(template);
248
265
  if (typeof cached === 'function') return cached
249
266
  if (typeof content === 'string') {
@@ -255,9 +272,9 @@ class Template {
255
272
  }
256
273
  }
257
274
  get(template) {
258
- return this.#resolve(template).then((content) =>
259
- this.compile(content, template),
260
- )
275
+ return this.#resolve(template).then((content) => {
276
+ return this.#compile(content, template)
277
+ })
261
278
  }
262
279
  }
263
280
 
@@ -280,15 +297,13 @@ const tokensMatch = (regex, content, callback) => {
280
297
  });
281
298
  };
282
299
 
283
- class Compiler {
300
+ class EjsCompiler {
284
301
  #config = {}
285
- static exports = ['compile']
286
-
302
+ static exports = ['configure', 'compile']
287
303
  constructor(options) {
288
304
  bindContext(this, this.constructor.exports);
289
305
  this.configure(options);
290
306
  }
291
-
292
307
  configure(options) {
293
308
  this.#config.strict = options.strict;
294
309
  this.#config.rmWhitespace = options.rmWhitespace;
@@ -363,7 +378,7 @@ class Compiler {
363
378
  });
364
379
  });
365
380
  OUTPUT += `');`;
366
- OUTPUT = `try{${OUTPUT}}catch(e){return ${BUFFER}.error(e,'${path}')}`;
381
+ OUTPUT = `try{${OUTPUT}}catch(e){return ${BUFFER}.error(e)}`;
367
382
  if (this.#config.strict === false) {
368
383
  OUTPUT = `with(${SCOPE}){${OUTPUT}}`;
369
384
  }
@@ -385,7 +400,7 @@ class Compiler {
385
400
  }
386
401
  }
387
402
 
388
- class Cache {
403
+ class EjsCache {
389
404
  static exports = [
390
405
  'load',
391
406
  'set',
@@ -426,13 +441,11 @@ class Cache {
426
441
  resolve(key) {
427
442
  return Promise.resolve(this.get(key))
428
443
  }
429
-
430
444
  load(data) {
431
445
  if (this.#cache) {
432
446
  Object.assign(this.#list, data || {});
433
447
  }
434
448
  }
435
-
436
449
  configure(options) {
437
450
  this.#cache = options.cache;
438
451
  this.#precompiled = options.precompiled;
@@ -491,36 +504,16 @@ const element = (tag, attrs, content) => {
491
504
  return result.join('')
492
505
  };
493
506
 
494
- class TemplateError extends Error {
495
- name = 'TemplateError'
496
- constructor(error) {
497
- super(error);
498
- if (error instanceof Error) {
499
- this.stack = error.stack;
500
- this.filename = error.filename;
501
- this.lineno = error.lineno;
502
- }
503
- }
504
- }
505
-
506
- class TemplateNotFound extends TemplateError {
507
- name = 'TemplateNotFound'
508
- code = 404
509
- }
510
-
511
- class TemplateSyntaxError extends TemplateError {
512
- name = 'TemplateSyntaxError'
513
- code = 500
514
- }
515
-
516
507
  const resolve = (list) => {
517
508
  return Promise.all(list || [])
518
509
  .then((list) => list.join(''))
519
- .catch((e) => e)
510
+ .catch((e) => {
511
+ return error(500, e)
512
+ })
520
513
  };
521
514
 
522
- const reject = (error) => {
523
- return Promise.reject(new TemplateSyntaxError(error))
515
+ const reject = (e) => {
516
+ return Promise.reject(error(500, e))
524
517
  };
525
518
 
526
519
  const EjsBuffer = () => {
@@ -546,7 +539,7 @@ const EjsBuffer = () => {
546
539
  array = store.pop();
547
540
  return resolve(result)
548
541
  };
549
- EjsBuffer.error = (e, filename) => {
542
+ EjsBuffer.error = (e) => {
550
543
  return reject(e)
551
544
  };
552
545
  EjsBuffer.end = () => {
@@ -579,12 +572,6 @@ const createContext$1 = (config, methods) => {
579
572
  omit(data, [SCOPE, BUFFER, SAFE, COMPONENT, ELEMENT]),
580
573
  );
581
574
  }
582
- Object.entries(methods).forEach(([name, value]) => {
583
- if (isFunction(value) && globals.includes(name)) {
584
- value = value.bind(EjsContext.prototype);
585
- }
586
- EjsContext.prototype[name] = value;
587
- });
588
575
  Object.defineProperty(EjsContext.prototype, BUFFER, {
589
576
  value: EjsBuffer(),
590
577
  });
@@ -609,36 +596,31 @@ const createContext$1 = (config, methods) => {
609
596
  writable: true,
610
597
  });
611
598
  Object.defineProperties(EjsContext.prototype, {
612
- /** @type {function} */
613
599
  setParentTemplate: {
614
600
  value(value) {
615
601
  this[PARENT] = value;
616
602
  return this
617
603
  },
618
604
  },
619
- /** @type {function} */
620
605
  getParentTemplate: {
621
606
  value() {
622
607
  return this[PARENT]
623
608
  },
624
609
  },
625
- /** @type {function} */
626
- useSafeValue: {
627
- get: () => safeValue,
610
+ useEscapeValue: {
611
+ get: () => escapeValue,
628
612
  },
629
- /** @type {function} */
630
613
  useComponent: {
631
614
  get() {
632
615
  if (isFunction(this[COMPONENT])) {
633
616
  return this[COMPONENT].bind(this)
634
617
  } else {
635
- return () => {
618
+ return function () {
636
619
  throw new Error(`${COMPONENT} must be a function`)
637
620
  }
638
621
  }
639
622
  },
640
623
  },
641
- /** @type {function} */
642
624
  useElement: {
643
625
  get() {
644
626
  if (isFunction(this[ELEMENT])) {
@@ -650,51 +632,43 @@ const createContext$1 = (config, methods) => {
650
632
  }
651
633
  },
652
634
  },
653
- /** @type {function} */
654
635
  useBuffer: {
655
636
  get() {
656
637
  return this[BUFFER]
657
638
  },
658
639
  },
659
- /** @type {function} */
660
640
  getMacro: {
661
641
  value() {
662
642
  return this[MACRO]
663
643
  },
664
644
  },
665
- /** @type {function} */
666
645
  getBlocks: {
667
646
  value() {
668
647
  return this[BLOCKS]
669
648
  },
670
649
  },
671
- /** @type {function} */
672
650
  setExtend: {
673
651
  value(value) {
674
652
  this[EXTEND] = value;
675
653
  return this
676
654
  },
677
655
  },
678
- /** @type {function} */
679
656
  getExtend: {
680
657
  value() {
681
658
  return this[EXTEND]
682
659
  },
683
660
  },
684
- /** @type {function} */
685
661
  setLayout: {
686
662
  value(layout) {
687
663
  this[LAYOUT] = layout;
688
664
  return this
689
665
  },
690
666
  },
691
- /** @type {function} */
692
667
  getLayout: {
693
668
  value() {
694
669
  return this[LAYOUT]
695
670
  },
696
671
  },
697
- /** @type {function} */
698
672
  clone: {
699
673
  value(exclude_blocks) {
700
674
  const filter = [LAYOUT, EXTEND, BUFFER];
@@ -704,32 +678,29 @@ const createContext$1 = (config, methods) => {
704
678
  return omit(this, filter)
705
679
  },
706
680
  },
707
- /** @type {function} */
708
681
  extend: {
709
682
  value(layout) {
710
683
  this.setExtend(true);
711
684
  this.setLayout(layout);
712
685
  },
713
686
  },
714
- /** @type {function} */
715
687
  echo: {
716
688
  value() {
717
689
  return [].slice.call(arguments).forEach(this.useBuffer)
718
690
  },
719
691
  },
720
- /** @type {function} */
721
692
  fn: {
722
693
  value(callback) {
723
- return () => {
694
+ const context = this;
695
+ return function () {
724
696
  if (isFunction(callback)) {
725
- this.useBuffer.backup();
726
- this.useBuffer(callback.apply(this, arguments));
727
- return this.useBuffer.restore()
697
+ context.useBuffer.backup();
698
+ context.useBuffer(callback.apply(context, arguments));
699
+ return context.useBuffer.restore()
728
700
  }
729
701
  }
730
702
  },
731
703
  },
732
- /** @type {function} */
733
704
  macro: {
734
705
  value(name, callback) {
735
706
  const list = this.getMacro();
@@ -740,7 +711,6 @@ const createContext$1 = (config, methods) => {
740
711
  };
741
712
  },
742
713
  },
743
- /** @type {function} */
744
714
  call: {
745
715
  value(name) {
746
716
  const list = this.getMacro();
@@ -751,35 +721,35 @@ const createContext$1 = (config, methods) => {
751
721
  }
752
722
  },
753
723
  },
754
- /** @type {function} */
755
724
  block: {
756
725
  value(name, callback) {
757
726
  const blocks = this.getBlocks();
758
727
  blocks[name] = blocks[name] || [];
759
728
  blocks[name].push(this.fn(callback));
760
729
  if (this.getExtend()) return
730
+ const context = this;
761
731
  const list = Object.assign([], blocks[name]);
762
- const shift = () => list.shift();
763
- const next = () => {
732
+ const shift = function () {
733
+ return list.shift()
734
+ };
735
+ const next = function () {
764
736
  const parent = shift();
765
737
  if (parent) {
766
- return () => {
767
- this.echo(parent(next()));
738
+ return function () {
739
+ context.echo(parent(next()));
768
740
  }
769
741
  } else {
770
- return () => {}
742
+ return function () {}
771
743
  }
772
744
  };
773
745
  this.echo(shift()(next()));
774
746
  },
775
747
  },
776
- /** @type {function} */
777
748
  hasBlock: {
778
749
  value(name) {
779
750
  return this.getBlocks().hasOwnProperty(name)
780
751
  },
781
752
  },
782
- /** @type {function} */
783
753
  include: {
784
754
  value(path, data, cx) {
785
755
  const context = cx === false ? {} : this.clone(true);
@@ -788,7 +758,6 @@ const createContext$1 = (config, methods) => {
788
758
  this.echo(promise);
789
759
  },
790
760
  },
791
- /** @type {function} */
792
761
  use: {
793
762
  value(path, namespace) {
794
763
  this.echo(
@@ -801,13 +770,6 @@ const createContext$1 = (config, methods) => {
801
770
  );
802
771
  },
803
772
  },
804
- /** @type {function} */
805
- async: {
806
- value(promise, callback) {
807
- this.echo(Promise.resolve(promise).then(callback));
808
- },
809
- },
810
- /** @type {function} */
811
773
  get: {
812
774
  value(name, defaults) {
813
775
  const path = getPath(this, name, true);
@@ -816,7 +778,6 @@ const createContext$1 = (config, methods) => {
816
778
  return hasProp(result, prop) ? result[prop] : defaults
817
779
  },
818
780
  },
819
- /** @type {function} */
820
781
  set: {
821
782
  value(name, value) {
822
783
  const path = getPath(this, name, false);
@@ -828,7 +789,6 @@ const createContext$1 = (config, methods) => {
828
789
  return (result[prop] = value)
829
790
  },
830
791
  },
831
- /** @type {function} */
832
792
  each: {
833
793
  value(object, callback) {
834
794
  if (isString(object)) {
@@ -838,7 +798,6 @@ const createContext$1 = (config, methods) => {
838
798
  },
839
799
  writable: true,
840
800
  },
841
- /** @type {function} */
842
801
  el: {
843
802
  value(tag, attr, content) {
844
803
  content = isFunction(content) ? this.fn(content)() : content;
@@ -850,16 +809,21 @@ const createContext$1 = (config, methods) => {
850
809
  },
851
810
  writable: true,
852
811
  },
853
- /** @type {function} */
854
812
  ui: {
855
- value(layout) {},
813
+ value() {},
856
814
  writable: true,
857
815
  },
858
816
  });
817
+ Object.entries(methods).forEach(([name, value]) => {
818
+ if (isFunction(value) && globals.includes(name)) {
819
+ value = value.bind(EjsContext.prototype);
820
+ }
821
+ EjsContext.prototype[name] = value;
822
+ });
859
823
  return EjsContext
860
824
  };
861
825
 
862
- class Context {
826
+ class EjsContext {
863
827
  #context
864
828
  static exports = ['create', 'globals', 'helpers']
865
829
  constructor(options, methods) {
@@ -898,10 +862,14 @@ class EjsInstance {
898
862
  bindContext(this, this.constructor.exports);
899
863
  this.#methods = {};
900
864
  this.#config = configSchema({}, options);
901
- this.#context = new Context(this.#config, this.#methods);
902
- this.#compiler = new Compiler(this.#config);
903
- this.#cache = new Cache(this.#config);
904
- this.#template = new Template(this.#config, this.#cache, this.#compiler);
865
+ this.#context = new EjsContext(this.#config, this.#methods);
866
+ this.#compiler = new EjsCompiler(this.#config);
867
+ this.#cache = new EjsCache(this.#config);
868
+ this.#template = new EjsTemplate(
869
+ this.#config,
870
+ this.#cache,
871
+ this.#compiler,
872
+ );
905
873
  this.helpers({ render: this.render, require: this.require });
906
874
  }
907
875
  create(options) {
@@ -955,7 +923,7 @@ class EjsInstance {
955
923
  data.useComponent,
956
924
  data.useElement,
957
925
  data.useBuffer,
958
- data.useSafeValue,
926
+ data.useEscapeValue,
959
927
  ]),
960
928
  )
961
929
  }
@@ -1012,25 +980,31 @@ const expressRenderer = (configure, render) => {
1012
980
  }
1013
981
  };
1014
982
 
1015
- const readFile = (path, template) => {
983
+ const readFile = (path, template, error) => {
1016
984
  return fs
1017
985
  .readFile(joinPath(path, template))
1018
986
  .then((contents) => contents.toString())
1019
- .then((text) => String(text))
987
+ .catch((reason) => {
988
+ if (reason.code === 'ENOENT') {
989
+ error(404, `template ${template} not found`);
990
+ } else {
991
+ error(500, reason);
992
+ }
993
+ })
1020
994
  };
1021
995
 
1022
996
  const {
1023
997
  render,
1024
- createContext,
1025
- compile,
1026
998
  helpers,
1027
- preload,
1028
999
  configure,
1029
1000
  create,
1001
+ createContext,
1002
+ compile,
1003
+ preload,
1030
1004
  } = new EjsInstance({
1031
1005
  resolver: readFile,
1032
1006
  });
1033
1007
 
1034
1008
  const __express = expressRenderer(configure, render);
1035
1009
 
1036
- export { TemplateError, TemplateNotFound, TemplateSyntaxError, __express, compile, configure, create, createContext, helpers, preload, render };
1010
+ export { __express, compile, configure, create, createContext, helpers, preload, render };