@kosatyi/ejs 0.0.105 → 0.0.106

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
@@ -67,15 +67,6 @@ const safeValue = (value, escape) => {
67
67
  : check
68
68
  };
69
69
 
70
- const instanceOf = (object, instance) => {
71
- return Boolean(object instanceof instance)
72
- };
73
-
74
- const assertInstanceOf = (object, instance) => {
75
- if (instanceOf(object, instance) === false)
76
- throw new TypeError(`${object} in not instance of ${instance}`)
77
- };
78
-
79
70
  const getPath = (context, name, strict) => {
80
71
  let data = context;
81
72
  let chunks = String(name).split('.');
@@ -97,14 +88,6 @@ const getPath = (context, name, strict) => {
97
88
  return [data, prop]
98
89
  };
99
90
 
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
-
108
91
  const ext = (path, defaults) => {
109
92
  const ext = path.split('.').pop();
110
93
  if (ext !== defaults) {
@@ -206,7 +189,7 @@ defaults.export = 'ejsPrecompiled';
206
189
  defaults.cache = true;
207
190
  defaults.chokidar = null;
208
191
  defaults.path = 'views';
209
- defaults.resolver = function (path, template) {
192
+ defaults.resolver = function(path, template) {
210
193
  return Promise.resolve(
211
194
  ['resolver is not defined', path, template].join(' ')
212
195
  )
@@ -224,16 +207,16 @@ defaults.vars = {
224
207
  LAYOUT: '$$l',
225
208
  BLOCKS: '$$b',
226
209
  MACRO: '$$m',
227
- SAFE: '$$v',
210
+ SAFE: '$$v'
228
211
  };
229
212
  defaults.token = {
230
213
  start: '<%',
231
214
  end: '%>',
232
- regex: '([\\s\\S]+?)',
215
+ regex: '([\\s\\S]+?)'
233
216
  };
234
217
 
235
218
  const configSchema = (config, options) => {
236
- extend(config, {
219
+ return extend(config, {
237
220
  path: typeProp(isString, defaults.path, config.path, options.path),
238
221
  export: typeProp(
239
222
  isString,
@@ -274,147 +257,141 @@ const configSchema = (config, options) => {
274
257
  config.globalHelpers,
275
258
  options.globalHelpers
276
259
  ),
277
- });
260
+ })
278
261
  };
279
262
 
280
- const global = typeof globalThis !== 'undefined' ? globalThis : window || self;
281
-
282
- class Cache {
283
- #enabled = true
284
- #list = {}
285
- constructor(config) {
286
- this.configure(config);
287
- }
288
- load(data) {
289
- if (this.#enabled) {
290
- extend(this.#list, data || {});
291
- }
292
- }
293
- get(key) {
294
- if (this.#enabled) {
295
- return this.#list[key]
296
- }
297
- }
298
- set(key, value) {
299
- if (this.#enabled) {
300
- this.#list[key] = value;
263
+ const Template = (options, cache, compiler) => {
264
+ const config = {
265
+ path: null,
266
+ resolver: null
267
+ };
268
+ const resolve = (path) => {
269
+ return config.resolver(config.path, path)
270
+ };
271
+ const result = (template, content) => {
272
+ cache.set(template, content);
273
+ return content
274
+ };
275
+ const compile = (content, template) => {
276
+ if (isFunction(content)) {
277
+ return content
278
+ } else {
279
+ return compiler.compile(content, template)
301
280
  }
302
- }
303
- exist(key) {
304
- if (this.#enabled) {
305
- return hasProp(this.#list, key)
281
+ };
282
+ const get = (template) => {
283
+ if (cache.exist(template)) {
284
+ return cache.resolve(template)
306
285
  }
307
- }
308
- clear() {
309
- this.#list = {};
310
- }
311
- remove(key) {
312
- delete this.#list[key];
313
- }
314
- resolve(key) {
315
- return Promise.resolve(this.get(key))
316
- }
317
- configure(config) {
318
- this.#enabled = config.cache;
319
- if (isNode() === false) {
320
- this.load(global[config.export]);
286
+ return resolve(template).then((content) =>
287
+ result(template, compile(content, template))
288
+ )
289
+ };
290
+ const configure = (options) => {
291
+ config.path = options.path;
292
+ if (isFunction(options.resolver)) {
293
+ config.resolver = options.resolver;
321
294
  }
295
+ };
296
+ configure(options);
297
+ return {
298
+ get,
299
+ configure,
300
+ compile
322
301
  }
323
- }
302
+ };
324
303
 
325
- class Compiler {
326
- #config = {}
327
- #symbols = [
328
- {
329
- symbol: '-',
330
- format(value) {
331
- return `')\n${this.BUFFER}(${this.SAFE}(${value},1))\n${this.BUFFER}('`
332
- },
304
+ const configSymbols = [
305
+ {
306
+ symbol: '-',
307
+ format(value) {
308
+ return `')\n${this.BUFFER}(${this.SAFE}(${value},1))\n${this.BUFFER}('`
333
309
  },
334
- {
335
- symbol: '=',
336
- format(value) {
337
- return `')\n${this.BUFFER}(${this.SAFE}(${value}))\n${this.BUFFER}('`
338
- },
310
+ },
311
+ {
312
+ symbol: '=',
313
+ format(value) {
314
+ return `')\n${this.BUFFER}(${this.SAFE}(${value}))\n${this.BUFFER}('`
339
315
  },
340
- {
341
- symbol: '#',
342
- format(value) {
343
- return `')\n/**${value}**/\n${this.BUFFER}('`
344
- },
316
+ },
317
+ {
318
+ symbol: '#',
319
+ format(value) {
320
+ return `')\n/**${value}**/\n${this.BUFFER}('`
345
321
  },
346
- {
347
- symbol: '',
348
- format(value) {
349
- return `')\n${value.trim()}\n${this.BUFFER}('`
350
- },
322
+ },
323
+ {
324
+ symbol: '',
325
+ format(value) {
326
+ return `')\n${value.trim()}\n${this.BUFFER}('`
351
327
  },
352
- ]
353
- constructor(config) {
354
- this.configure(config);
355
- }
356
- configure(config) {
357
- this.#config.withObject = config.withObject;
358
- this.#config.rmWhitespace = config.rmWhitespace;
359
- this.#config.token = config.token;
360
- this.#config.vars = config.vars;
361
- this.#config.globalHelpers = config.globalHelpers;
362
- this.#config.matches = [];
363
- this.#config.formats = [];
364
- this.#config.slurp = {
328
+ },
329
+ ];
330
+
331
+ const Compiler = (options) => {
332
+ const config = {};
333
+ const configure = (options) => {
334
+ config.withObject = options.withObject;
335
+ config.rmWhitespace = options.rmWhitespace;
336
+ config.token = options.token;
337
+ config.vars = options.vars;
338
+ config.globalHelpers = options.globalHelpers;
339
+ config.matches = [];
340
+ config.formats = [];
341
+ config.slurp = {
365
342
  match: '[s\t\n]*',
366
- start: [this.#config.token.start, '_'],
367
- end: ['_', this.#config.token.end],
343
+ start: [config.token.start, '_'],
344
+ end: ['_', config.token.end],
368
345
  };
369
- this.#symbols.forEach((item) => {
370
- this.#config.matches.push(
371
- this.#config.token.start
346
+ configSymbols.forEach((item) => {
347
+ config.matches.push(
348
+ config.token.start
372
349
  .concat(item.symbol)
373
- .concat(this.#config.token.regex)
374
- .concat(this.#config.token.end)
350
+ .concat(config.token.regex)
351
+ .concat(config.token.end)
375
352
  );
376
- this.#config.formats.push(item.format.bind(this.#config.vars));
353
+ config.formats.push(item.format.bind(config.vars));
377
354
  });
378
- this.#config.regex = new RegExp(
379
- this.#config.matches.join('|').concat('|$'),
355
+ config.regex = new RegExp(
356
+ config.matches.join('|').concat('|$'),
380
357
  'g'
381
358
  );
382
- this.#config.slurpStart = new RegExp(
383
- [this.#config.slurp.match, this.#config.slurp.start.join('')].join(
359
+ config.slurpStart = new RegExp(
360
+ [config.slurp.match, config.slurp.start.join('')].join(
384
361
  ''
385
362
  ),
386
363
  'gm'
387
364
  );
388
- this.#config.slurpEnd = new RegExp(
389
- [this.#config.slurp.end.join(''), this.#config.slurp.match].join(
365
+ config.slurpEnd = new RegExp(
366
+ [config.slurp.end.join(''), config.slurp.match].join(
390
367
  ''
391
368
  ),
392
369
  'gm'
393
370
  );
394
- }
395
- compile(content, path) {
396
- const { SCOPE, SAFE, BUFFER, COMPONENT, ELEMENT } = this.#config.vars;
397
- const GLOBALS = this.#config.globalHelpers;
398
- if (this.#config.rmWhitespace) {
371
+ };
372
+ const compile = (content, path) => {
373
+ const { SCOPE, SAFE, BUFFER, COMPONENT, ELEMENT } = config.vars;
374
+ const GLOBALS = config.globalHelpers;
375
+ if (config.rmWhitespace) {
399
376
  content = String(content)
400
377
  .replace(/[\r\n]+/g, '\n')
401
378
  .replace(/^\s+|\s+$/gm, '');
402
379
  }
403
380
  content = String(content)
404
- .replace(this.#config.slurpStart, this.#config.token.start)
405
- .replace(this.#config.slurpEnd, this.#config.token.end);
381
+ .replace(config.slurpStart, config.token.start)
382
+ .replace(config.slurpEnd, config.token.end);
406
383
  let source = `${BUFFER}('`;
407
- matchTokens(this.#config.regex, content, (params, index, offset) => {
384
+ matchTokens(config.regex, content, (params, index, offset) => {
408
385
  source += symbols(content.slice(index, offset));
409
386
  params.forEach((value, index) => {
410
387
  if (value) {
411
- source += this.#config.formats[index](value);
388
+ source += config.formats[index](value);
412
389
  }
413
390
  });
414
391
  });
415
392
  source += `');`;
416
393
  source = `try{${source}}catch(e){return ${BUFFER}.error(e)}`;
417
- if (this.#config.withObject) {
394
+ if (config.withObject) {
418
395
  source = `with(${SCOPE}){${source}}`;
419
396
  }
420
397
  source = `${BUFFER}.start();${source}return ${BUFFER}.end();`;
@@ -430,50 +407,67 @@ class Compiler {
430
407
  throw e
431
408
  }
432
409
  return result
410
+ };
411
+ configure(options);
412
+ return {
413
+ configure,
414
+ compile,
433
415
  }
434
- }
416
+ };
435
417
 
436
- class Template {
437
- #path
438
- #cache
439
- #compiler
440
- #resolver
441
- constructor(config, cache, compiler) {
442
- assertInstanceOf(cache, Cache);
443
- assertInstanceOf(compiler, Compiler);
444
- this.#cache = cache;
445
- this.#compiler = compiler;
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);
453
- return content
454
- }
455
- #compile(content, template) {
456
- if (isFunction(content)) {
457
- return content
458
- } else {
459
- return this.#compiler.compile(content, template)
418
+ const global = typeof globalThis !== 'undefined' ? globalThis : window || self;
419
+
420
+ const Cache = (options = {}) => {
421
+ const config = {};
422
+ const list = {};
423
+ const load = (data) => {
424
+ if (config.enabled) {
425
+ extend(list, data || {});
460
426
  }
461
- }
462
- configure(config) {
463
- this.#path = config.path;
464
- if (isFunction(config.resolver)) {
465
- this.#resolver = config.resolver;
427
+ };
428
+ const get = (key) => {
429
+ if (config.enabled) {
430
+ return list[key]
466
431
  }
467
- }
468
- get(template) {
469
- if (this.#cache.exist(template)) {
470
- return this.#cache.resolve(template)
432
+ };
433
+ const set = (key, value) => {
434
+ if (config.enabled) {
435
+ list[key] = value;
471
436
  }
472
- return this.#resolve(template).then((content) =>
473
- this.#result(template, this.#compile(content, template))
474
- )
437
+ };
438
+ const exist = (key) => {
439
+ if (config.enabled) {
440
+ return hasProp(list, key)
441
+ }
442
+ };
443
+ const clear = () => {
444
+ Object.keys(list).forEach(remove);
445
+ };
446
+ const remove = (key) => {
447
+ delete list[key];
448
+ };
449
+ const resolve = (key) => {
450
+ return Promise.resolve(get(key))
451
+ };
452
+ const configure = (options = {}) => {
453
+ config.enabled = options.cache;
454
+ config.export = options.export;
455
+ if (isNode() === false) {
456
+ load(global[config.export]);
457
+ }
458
+ };
459
+ configure(options);
460
+ return {
461
+ configure,
462
+ load,
463
+ set,
464
+ get,
465
+ exist,
466
+ clear,
467
+ remove,
468
+ resolve,
475
469
  }
476
- }
470
+ };
477
471
 
478
472
  const selfClosed = [
479
473
  'area',
@@ -520,30 +514,46 @@ const element = (tag, attrs, content) => {
520
514
  return result.join('')
521
515
  };
522
516
 
523
- class TemplateError extends Error {
524
- code = 0
525
- constructor(message) {
526
- super();
527
- this.message = message;
528
- }
517
+ /**
518
+ *
519
+ * @constructor
520
+ */
521
+ function TemplateError(){
522
+ TemplateError.call(this);
523
+ }
524
+ Object.setPrototypeOf(TemplateError.prototype, Error.prototype);
525
+ Object.assign(TemplateError.prototype, {
526
+ code: 0,
529
527
  getCode() {
530
528
  return this.code
531
- }
529
+ },
532
530
  getMessage() {
533
531
  return this.message
534
- }
532
+ },
535
533
  toString() {
536
534
  return this.getMessage()
537
535
  }
538
- }
536
+ });
539
537
 
540
- class TemplateNotFound extends TemplateError {
541
- code = 404
538
+ /**
539
+ *
540
+ * @constructor
541
+ */
542
+ function TemplateNotFound(){
543
+ TemplateError.call(this);
542
544
  }
545
+ Object.setPrototypeOf(TemplateNotFound.prototype, TemplateError.prototype);
546
+ Object.assign(TemplateNotFound.prototype, { code: 404 });
543
547
 
544
- class TemplateSyntaxError extends TemplateError {
545
- code = 500
548
+ /**
549
+ *
550
+ * @constructor
551
+ */
552
+ function TemplateSyntaxError(){
553
+ TemplateError.call(this);
546
554
  }
555
+ Object.setPrototypeOf(TemplateSyntaxError.prototype, TemplateError.prototype);
556
+ Object.assign(TemplateSyntaxError.prototype, { code: 500 });
547
557
 
548
558
  function resolve(list) {
549
559
  return Promise.all(list || [])
@@ -602,6 +612,7 @@ const createContextScope = (config, methods) => {
602
612
  COMPONENT,
603
613
  ELEMENT
604
614
  } = config.vars;
615
+
605
616
  /**
606
617
  *
607
618
  * @type {symbol}
@@ -621,6 +632,7 @@ const createContextScope = (config, methods) => {
621
632
  omit(data, [SCOPE, BUFFER, SAFE, COMPONENT, ELEMENT])
622
633
  );
623
634
  }
635
+
624
636
  Object.assign(ContextScope.prototype, methods);
625
637
  Object.defineProperty(ContextScope.prototype, BUFFER, {
626
638
  value: createBuffer()
@@ -647,15 +659,15 @@ const createContextScope = (config, methods) => {
647
659
  });
648
660
  Object.defineProperties(ContextScope.prototype, {
649
661
  /** @type {function} */
650
- setParentTemplate:{
651
- value(value){
662
+ setParentTemplate: {
663
+ value(value) {
652
664
  this[PARENT] = value;
653
665
  return this
654
666
  }
655
667
  },
656
668
  /** @type {function} */
657
669
  getParentTemplate: {
658
- value(){
670
+ value() {
659
671
  return this[PARENT]
660
672
  }
661
673
  },
@@ -863,7 +875,7 @@ const createContextScope = (config, methods) => {
863
875
  set: {
864
876
  value(name, value) {
865
877
  const path = getPath(this, name, false);
866
- const result= path.shift();
878
+ const result = path.shift();
867
879
  const prop = path.pop();
868
880
  if (this.getParentTemplate() && hasProp(result, prop)) {
869
881
  return result[prop]
@@ -903,128 +915,116 @@ const createContextScope = (config, methods) => {
903
915
  return ContextScope
904
916
  };
905
917
 
906
- class Context {
907
- #scope
908
-
909
- constructor(config, methods) {
910
- this.configure(config, methods);
911
- }
912
-
913
- create(data) {
914
- return new this.#scope(data)
915
- }
916
-
917
- configure(config, methods) {
918
- this.#scope = createContextScope(config, methods);
919
- }
920
-
921
- helpers(methods) {
922
- extend(this.#scope.prototype, methods || {});
923
- }
924
- }
925
-
926
- class EJS {
927
- #config = {}
928
- #extend = {}
929
- #context
930
- #compiler
931
- #cache
932
- #template
933
-
934
- constructor(options) {
935
- configSchema(this.#config, options || {});
936
- this.#context = new Context(this.#config, this.#extend);
937
- this.#compiler = new Compiler(this.#config);
938
- this.#cache = new Cache(this.#config);
939
- this.#template = new Template(this.#config, this.#cache, this.#compiler);
940
- //
941
- bindContext(this, ['configure', 'create', 'render', 'require', 'context', 'preload', 'compile', 'helpers']);
942
- //
943
- this.helpers({ require: this.require, render: this.render });
944
- }
945
-
946
- configure(options) {
947
- configSchema(this.#config, options || {});
948
- this.#context.configure(this.#config, this.#extend);
949
- this.#compiler.configure(this.#config);
950
- this.#cache.configure(this.#config);
951
- this.#template.configure(this.#config);
952
- return this.#config
953
- }
954
-
955
- filePath(name) {
956
- return ext(name, this.#config.extension)
957
- }
958
-
959
- require(name) {
960
- const scope = this.context({});
961
- return this.#output(this.filePath(name), scope).then(() => scope.getMacro())
962
- }
963
-
964
- render(name, data) {
965
- const scope = this.context(data);
966
- return this.#output(this.filePath(name), scope).then(this.outputContent(name, scope))
918
+ const Context = (options, methods) => {
919
+ /**
920
+ * @type {InstanceType<ContextScope>}
921
+ */
922
+ let Scope;
923
+ const create = (data) => {
924
+ return new Scope(data)
925
+ };
926
+ const helpers = (methods) => {
927
+ extend(Scope.prototype, methods || {});
928
+ };
929
+ const configure = (options, methods) => {
930
+ Scope = createContextScope(options, methods);
931
+ };
932
+ configure(options, methods);
933
+ return {
934
+ configure,
935
+ create,
936
+ helpers
967
937
  }
938
+ };
968
939
 
969
- outputContent(name, scope) {
940
+ const EJS = (options = {}) => {
941
+ const config = configSchema({}, options);
942
+ const methods = {};
943
+ const context = Context(config, methods);
944
+ const compiler = Compiler(config);
945
+ const cache = Cache(config);
946
+ const template = Template(config, cache, compiler);
947
+ const configure = (options = {}) => {
948
+ configSchema(config, options || {});
949
+ context.configure(config, methods);
950
+ compiler.configure(config);
951
+ cache.configure(config);
952
+ template.configure(config);
953
+ return config
954
+ };
955
+ const filePath = (name) => {
956
+ return ext(name, config.extension)
957
+ };
958
+ const require = (name) => {
959
+ const scope = createContext({});
960
+ return output(filePath(name), scope).then(() => scope.getMacro())
961
+ };
962
+ const render = (name, data) => {
963
+ const scope = createContext(data);
964
+ return output(filePath(name), scope).then(outputContent(name, scope))
965
+ };
966
+ const outputContent = (name, scope) => {
970
967
  return (content) => {
971
968
  if (scope.getExtend()) {
972
969
  scope.setExtend(false);
973
- return this.renderLayout(scope.getLayout(), scope, name)
970
+ return renderLayout(scope.getLayout(), scope, name)
974
971
  }
975
972
  return content
976
973
  }
977
- }
978
-
979
- renderLayout(name, data, parent) {
980
- const scope = this.context(data);
974
+ };
975
+ const renderLayout = (name, data, parent) => {
976
+ const scope = createContext(data);
981
977
  if (parent) scope.setParentTemplate(parent);
982
- return this.#output(this.filePath(name), scope).then(this.outputContent(name, scope))
983
- }
984
-
985
- helpers(methods) {
986
- this.#context.helpers(extend(this.#extend, methods));
987
- }
988
-
989
- context(data) {
990
- return this.#context.create(data)
991
- }
992
-
993
- compile(content, path) {
994
- return this.#compiler.compile(content, path)
995
- }
996
-
997
- preload(list) {
998
- return this.#cache.load(list || {})
999
- }
1000
-
1001
- create(options) {
1002
- return new this.constructor(options)
1003
- }
1004
-
1005
- #output(path, scope) {
1006
- const { globalHelpers } = this.#config;
978
+ return output(filePath(name), scope).then(outputContent(name, scope))
979
+ };
980
+ const helpers = (extendMethods) => {
981
+ context.helpers(extend(methods, extendMethods));
982
+ };
983
+ const createContext = (data) => {
984
+ return context.create(data)
985
+ };
986
+ const compile = (content, path) => {
987
+ return compiler.compile(content, path)
988
+ };
989
+ const preload = (list) => {
990
+ return cache.load(list || {})
991
+ };
992
+ const create = (config) => {
993
+ return EJS(config)
994
+ };
995
+ const output = (path, scope) => {
1007
996
  const params = [scope, scope.useComponent, scope.useElement, scope.getBuffer(), scope.useSafeValue];
1008
- const globals = globalHelpers
997
+ const globals = config.globalHelpers
1009
998
  .filter((name) => isFunction(scope[name]))
1010
999
  .map((name) => scope[name].bind(scope));
1011
- return this.#template
1000
+ return template
1012
1001
  .get(path)
1013
1002
  .then((callback) => callback.apply(scope, params.concat(globals)))
1003
+ };
1004
+ helpers({ render, require });
1005
+ return {
1006
+ configure,
1007
+ create,
1008
+ createContext,
1009
+ render,
1010
+ require,
1011
+ preload,
1012
+ compile,
1013
+ helpers
1014
1014
  }
1015
- }
1015
+ };
1016
1016
 
1017
- function readFile(path, template) {
1017
+ const readFile = (path, template) => {
1018
1018
  return new Promise((resolve, reject) => {
1019
1019
  fs.readFile(joinPath(path, template), (error, data) => {
1020
1020
  if (error) {
1021
- reject(new TemplateError(error));
1021
+ reject(new TemplateError());
1022
1022
  } else {
1023
1023
  resolve(data.toString());
1024
1024
  }
1025
1025
  });
1026
1026
  })
1027
- }
1027
+ };
1028
1028
 
1029
1029
  /**
1030
1030
  *
@@ -1032,7 +1032,7 @@ function readFile(path, template) {
1032
1032
  * @param {function(name: string, data?: object):Promise<string>} render
1033
1033
  * @return {function(name:any, options:any, callback: any): Promise<void>}
1034
1034
  */
1035
- function expressRenderer(configure, render) {
1035
+ const expressRenderer = (configure, render) => {
1036
1036
  return function (name, options, callback) {
1037
1037
  if (isFunction(options)) {
1038
1038
  callback = options;
@@ -1059,13 +1059,13 @@ function expressRenderer(configure, render) {
1059
1059
  callback(error);
1060
1060
  })
1061
1061
  }
1062
- }
1062
+ };
1063
1063
 
1064
- const { render, context, compile, helpers, preload, configure, create } =
1065
- new EJS({
1064
+ const { render, createContext, compile, helpers, preload, configure, create } =
1065
+ EJS({
1066
1066
  resolver: readFile,
1067
1067
  });
1068
1068
 
1069
1069
  const __express = expressRenderer(configure, render);
1070
1070
 
1071
- export { TemplateError, TemplateNotFound, TemplateSyntaxError, __express, compile, configure, context, create, helpers, preload, render };
1071
+ export { TemplateError, TemplateNotFound, TemplateSyntaxError, __express, compile, configure, create, createContext, helpers, preload, render };