@kosatyi/ejs 0.0.104 → 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.
@@ -64,15 +64,6 @@ const safeValue = (value, escape) => {
64
64
  : check
65
65
  };
66
66
 
67
- const instanceOf = (object, instance) => {
68
- return Boolean(object instanceof instance)
69
- };
70
-
71
- const assertInstanceOf = (object, instance) => {
72
- if (instanceOf(object, instance) === false)
73
- throw new TypeError(`${object} in not instance of ${instance}`)
74
- };
75
-
76
67
  const getPath = (context, name, strict) => {
77
68
  let data = context;
78
69
  let chunks = String(name).split('.');
@@ -94,14 +85,6 @@ const getPath = (context, name, strict) => {
94
85
  return [data, prop]
95
86
  };
96
87
 
97
- const bindContext = (object, methods = []) => {
98
- methods.forEach((name) => {
99
- if (name in object) {
100
- object[name] = object[name].bind(object);
101
- }
102
- });
103
- };
104
-
105
88
  const ext = (path, defaults) => {
106
89
  const ext = path.split('.').pop();
107
90
  if (ext !== defaults) {
@@ -197,7 +180,7 @@ defaults.export = 'ejsPrecompiled';
197
180
  defaults.cache = true;
198
181
  defaults.chokidar = null;
199
182
  defaults.path = 'views';
200
- defaults.resolver = function (path, template) {
183
+ defaults.resolver = function(path, template) {
201
184
  return Promise.resolve(
202
185
  ['resolver is not defined', path, template].join(' ')
203
186
  )
@@ -215,16 +198,16 @@ defaults.vars = {
215
198
  LAYOUT: '$$l',
216
199
  BLOCKS: '$$b',
217
200
  MACRO: '$$m',
218
- SAFE: '$$v',
201
+ SAFE: '$$v'
219
202
  };
220
203
  defaults.token = {
221
204
  start: '<%',
222
205
  end: '%>',
223
- regex: '([\\s\\S]+?)',
206
+ regex: '([\\s\\S]+?)'
224
207
  };
225
208
 
226
209
  const configSchema = (config, options) => {
227
- extend(config, {
210
+ return extend(config, {
228
211
  path: typeProp(isString, defaults.path, config.path, options.path),
229
212
  export: typeProp(
230
213
  isString,
@@ -265,147 +248,141 @@ const configSchema = (config, options) => {
265
248
  config.globalHelpers,
266
249
  options.globalHelpers
267
250
  ),
268
- });
251
+ })
269
252
  };
270
253
 
271
- const global = typeof globalThis !== 'undefined' ? globalThis : window || self;
272
-
273
- class Cache {
274
- #enabled = true
275
- #list = {}
276
- constructor(config) {
277
- this.configure(config);
278
- }
279
- load(data) {
280
- if (this.#enabled) {
281
- extend(this.#list, data || {});
282
- }
283
- }
284
- get(key) {
285
- if (this.#enabled) {
286
- return this.#list[key]
287
- }
288
- }
289
- set(key, value) {
290
- if (this.#enabled) {
291
- this.#list[key] = value;
254
+ const Template = (options, cache, compiler) => {
255
+ const config = {
256
+ path: null,
257
+ resolver: null
258
+ };
259
+ const resolve = (path) => {
260
+ return config.resolver(config.path, path)
261
+ };
262
+ const result = (template, content) => {
263
+ cache.set(template, content);
264
+ return content
265
+ };
266
+ const compile = (content, template) => {
267
+ if (isFunction(content)) {
268
+ return content
269
+ } else {
270
+ return compiler.compile(content, template)
292
271
  }
293
- }
294
- exist(key) {
295
- if (this.#enabled) {
296
- return hasProp(this.#list, key)
272
+ };
273
+ const get = (template) => {
274
+ if (cache.exist(template)) {
275
+ return cache.resolve(template)
297
276
  }
298
- }
299
- clear() {
300
- this.#list = {};
301
- }
302
- remove(key) {
303
- delete this.#list[key];
304
- }
305
- resolve(key) {
306
- return Promise.resolve(this.get(key))
307
- }
308
- configure(config) {
309
- this.#enabled = config.cache;
310
- if (isNode() === false) {
311
- this.load(global[config.export]);
277
+ return resolve(template).then((content) =>
278
+ result(template, compile(content, template))
279
+ )
280
+ };
281
+ const configure = (options) => {
282
+ config.path = options.path;
283
+ if (isFunction(options.resolver)) {
284
+ config.resolver = options.resolver;
312
285
  }
286
+ };
287
+ configure(options);
288
+ return {
289
+ get,
290
+ configure,
291
+ compile
313
292
  }
314
- }
293
+ };
315
294
 
316
- class Compiler {
317
- #config = {}
318
- #symbols = [
319
- {
320
- symbol: '-',
321
- format(value) {
322
- return `')\n${this.BUFFER}(${this.SAFE}(${value},1))\n${this.BUFFER}('`
323
- },
295
+ const configSymbols = [
296
+ {
297
+ symbol: '-',
298
+ format(value) {
299
+ return `')\n${this.BUFFER}(${this.SAFE}(${value},1))\n${this.BUFFER}('`
324
300
  },
325
- {
326
- symbol: '=',
327
- format(value) {
328
- return `')\n${this.BUFFER}(${this.SAFE}(${value}))\n${this.BUFFER}('`
329
- },
301
+ },
302
+ {
303
+ symbol: '=',
304
+ format(value) {
305
+ return `')\n${this.BUFFER}(${this.SAFE}(${value}))\n${this.BUFFER}('`
330
306
  },
331
- {
332
- symbol: '#',
333
- format(value) {
334
- return `')\n/**${value}**/\n${this.BUFFER}('`
335
- },
307
+ },
308
+ {
309
+ symbol: '#',
310
+ format(value) {
311
+ return `')\n/**${value}**/\n${this.BUFFER}('`
336
312
  },
337
- {
338
- symbol: '',
339
- format(value) {
340
- return `')\n${value.trim()}\n${this.BUFFER}('`
341
- },
313
+ },
314
+ {
315
+ symbol: '',
316
+ format(value) {
317
+ return `')\n${value.trim()}\n${this.BUFFER}('`
342
318
  },
343
- ]
344
- constructor(config) {
345
- this.configure(config);
346
- }
347
- configure(config) {
348
- this.#config.withObject = config.withObject;
349
- this.#config.rmWhitespace = config.rmWhitespace;
350
- this.#config.token = config.token;
351
- this.#config.vars = config.vars;
352
- this.#config.globalHelpers = config.globalHelpers;
353
- this.#config.matches = [];
354
- this.#config.formats = [];
355
- this.#config.slurp = {
319
+ },
320
+ ];
321
+
322
+ const Compiler = (options) => {
323
+ const config = {};
324
+ const configure = (options) => {
325
+ config.withObject = options.withObject;
326
+ config.rmWhitespace = options.rmWhitespace;
327
+ config.token = options.token;
328
+ config.vars = options.vars;
329
+ config.globalHelpers = options.globalHelpers;
330
+ config.matches = [];
331
+ config.formats = [];
332
+ config.slurp = {
356
333
  match: '[s\t\n]*',
357
- start: [this.#config.token.start, '_'],
358
- end: ['_', this.#config.token.end],
334
+ start: [config.token.start, '_'],
335
+ end: ['_', config.token.end],
359
336
  };
360
- this.#symbols.forEach((item) => {
361
- this.#config.matches.push(
362
- this.#config.token.start
337
+ configSymbols.forEach((item) => {
338
+ config.matches.push(
339
+ config.token.start
363
340
  .concat(item.symbol)
364
- .concat(this.#config.token.regex)
365
- .concat(this.#config.token.end)
341
+ .concat(config.token.regex)
342
+ .concat(config.token.end)
366
343
  );
367
- this.#config.formats.push(item.format.bind(this.#config.vars));
344
+ config.formats.push(item.format.bind(config.vars));
368
345
  });
369
- this.#config.regex = new RegExp(
370
- this.#config.matches.join('|').concat('|$'),
346
+ config.regex = new RegExp(
347
+ config.matches.join('|').concat('|$'),
371
348
  'g'
372
349
  );
373
- this.#config.slurpStart = new RegExp(
374
- [this.#config.slurp.match, this.#config.slurp.start.join('')].join(
350
+ config.slurpStart = new RegExp(
351
+ [config.slurp.match, config.slurp.start.join('')].join(
375
352
  ''
376
353
  ),
377
354
  'gm'
378
355
  );
379
- this.#config.slurpEnd = new RegExp(
380
- [this.#config.slurp.end.join(''), this.#config.slurp.match].join(
356
+ config.slurpEnd = new RegExp(
357
+ [config.slurp.end.join(''), config.slurp.match].join(
381
358
  ''
382
359
  ),
383
360
  'gm'
384
361
  );
385
- }
386
- compile(content, path) {
387
- const { SCOPE, SAFE, BUFFER, COMPONENT, ELEMENT } = this.#config.vars;
388
- const GLOBALS = this.#config.globalHelpers;
389
- if (this.#config.rmWhitespace) {
362
+ };
363
+ const compile = (content, path) => {
364
+ const { SCOPE, SAFE, BUFFER, COMPONENT, ELEMENT } = config.vars;
365
+ const GLOBALS = config.globalHelpers;
366
+ if (config.rmWhitespace) {
390
367
  content = String(content)
391
368
  .replace(/[\r\n]+/g, '\n')
392
369
  .replace(/^\s+|\s+$/gm, '');
393
370
  }
394
371
  content = String(content)
395
- .replace(this.#config.slurpStart, this.#config.token.start)
396
- .replace(this.#config.slurpEnd, this.#config.token.end);
372
+ .replace(config.slurpStart, config.token.start)
373
+ .replace(config.slurpEnd, config.token.end);
397
374
  let source = `${BUFFER}('`;
398
- matchTokens(this.#config.regex, content, (params, index, offset) => {
375
+ matchTokens(config.regex, content, (params, index, offset) => {
399
376
  source += symbols(content.slice(index, offset));
400
377
  params.forEach((value, index) => {
401
378
  if (value) {
402
- source += this.#config.formats[index](value);
379
+ source += config.formats[index](value);
403
380
  }
404
381
  });
405
382
  });
406
383
  source += `');`;
407
384
  source = `try{${source}}catch(e){return ${BUFFER}.error(e)}`;
408
- if (this.#config.withObject) {
385
+ if (config.withObject) {
409
386
  source = `with(${SCOPE}){${source}}`;
410
387
  }
411
388
  source = `${BUFFER}.start();${source}return ${BUFFER}.end();`;
@@ -421,50 +398,67 @@ class Compiler {
421
398
  throw e
422
399
  }
423
400
  return result
401
+ };
402
+ configure(options);
403
+ return {
404
+ configure,
405
+ compile,
424
406
  }
425
- }
407
+ };
426
408
 
427
- class Template {
428
- #path
429
- #cache
430
- #compiler
431
- #resolver
432
- constructor(config, cache, compiler) {
433
- assertInstanceOf(cache, Cache);
434
- assertInstanceOf(compiler, Compiler);
435
- this.#cache = cache;
436
- this.#compiler = compiler;
437
- this.configure(config);
438
- }
439
- #resolve(path) {
440
- return this.#resolver(this.#path, path)
441
- }
442
- #result(template, content) {
443
- this.#cache.set(template, content);
444
- return content
445
- }
446
- #compile(content, template) {
447
- if (isFunction(content)) {
448
- return content
449
- } else {
450
- return this.#compiler.compile(content, template)
409
+ const global = typeof globalThis !== 'undefined' ? globalThis : window || self;
410
+
411
+ const Cache = (options = {}) => {
412
+ const config = {};
413
+ const list = {};
414
+ const load = (data) => {
415
+ if (config.enabled) {
416
+ extend(list, data || {});
451
417
  }
452
- }
453
- configure(config) {
454
- this.#path = config.path;
455
- if (isFunction(config.resolver)) {
456
- this.#resolver = config.resolver;
418
+ };
419
+ const get = (key) => {
420
+ if (config.enabled) {
421
+ return list[key]
457
422
  }
458
- }
459
- get(template) {
460
- if (this.#cache.exist(template)) {
461
- return this.#cache.resolve(template)
423
+ };
424
+ const set = (key, value) => {
425
+ if (config.enabled) {
426
+ list[key] = value;
462
427
  }
463
- return this.#resolve(template).then((content) =>
464
- this.#result(template, this.#compile(content, template))
465
- )
428
+ };
429
+ const exist = (key) => {
430
+ if (config.enabled) {
431
+ return hasProp(list, key)
432
+ }
433
+ };
434
+ const clear = () => {
435
+ Object.keys(list).forEach(remove);
436
+ };
437
+ const remove = (key) => {
438
+ delete list[key];
439
+ };
440
+ const resolve = (key) => {
441
+ return Promise.resolve(get(key))
442
+ };
443
+ const configure = (options = {}) => {
444
+ config.enabled = options.cache;
445
+ config.export = options.export;
446
+ if (isNode() === false) {
447
+ load(global[config.export]);
448
+ }
449
+ };
450
+ configure(options);
451
+ return {
452
+ configure,
453
+ load,
454
+ set,
455
+ get,
456
+ exist,
457
+ clear,
458
+ remove,
459
+ resolve,
466
460
  }
467
- }
461
+ };
468
462
 
469
463
  const selfClosed = [
470
464
  'area',
@@ -511,30 +505,46 @@ const element = (tag, attrs, content) => {
511
505
  return result.join('')
512
506
  };
513
507
 
514
- class TemplateError extends Error {
515
- code = 0
516
- constructor(message) {
517
- super();
518
- this.message = message;
519
- }
508
+ /**
509
+ *
510
+ * @constructor
511
+ */
512
+ function TemplateError(){
513
+ TemplateError.call(this);
514
+ }
515
+ Object.setPrototypeOf(TemplateError.prototype, Error.prototype);
516
+ Object.assign(TemplateError.prototype, {
517
+ code: 0,
520
518
  getCode() {
521
519
  return this.code
522
- }
520
+ },
523
521
  getMessage() {
524
522
  return this.message
525
- }
523
+ },
526
524
  toString() {
527
525
  return this.getMessage()
528
526
  }
529
- }
527
+ });
530
528
 
531
- class TemplateNotFound extends TemplateError {
532
- code = 404
529
+ /**
530
+ *
531
+ * @constructor
532
+ */
533
+ function TemplateNotFound(){
534
+ TemplateError.call(this);
533
535
  }
536
+ Object.setPrototypeOf(TemplateNotFound.prototype, TemplateError.prototype);
537
+ Object.assign(TemplateNotFound.prototype, { code: 404 });
534
538
 
535
- class TemplateSyntaxError extends TemplateError {
536
- code = 500
539
+ /**
540
+ *
541
+ * @constructor
542
+ */
543
+ function TemplateSyntaxError(){
544
+ TemplateError.call(this);
537
545
  }
546
+ Object.setPrototypeOf(TemplateSyntaxError.prototype, TemplateError.prototype);
547
+ Object.assign(TemplateSyntaxError.prototype, { code: 500 });
538
548
 
539
549
  function resolve(list) {
540
550
  return Promise.all(list || [])
@@ -593,6 +603,7 @@ const createContextScope = (config, methods) => {
593
603
  COMPONENT,
594
604
  ELEMENT
595
605
  } = config.vars;
606
+
596
607
  /**
597
608
  *
598
609
  * @type {symbol}
@@ -612,6 +623,7 @@ const createContextScope = (config, methods) => {
612
623
  omit(data, [SCOPE, BUFFER, SAFE, COMPONENT, ELEMENT])
613
624
  );
614
625
  }
626
+
615
627
  Object.assign(ContextScope.prototype, methods);
616
628
  Object.defineProperty(ContextScope.prototype, BUFFER, {
617
629
  value: createBuffer()
@@ -638,15 +650,15 @@ const createContextScope = (config, methods) => {
638
650
  });
639
651
  Object.defineProperties(ContextScope.prototype, {
640
652
  /** @type {function} */
641
- setParentTemplate:{
642
- value(value){
653
+ setParentTemplate: {
654
+ value(value) {
643
655
  this[PARENT] = value;
644
656
  return this
645
657
  }
646
658
  },
647
659
  /** @type {function} */
648
660
  getParentTemplate: {
649
- value(){
661
+ value() {
650
662
  return this[PARENT]
651
663
  }
652
664
  },
@@ -854,7 +866,7 @@ const createContextScope = (config, methods) => {
854
866
  set: {
855
867
  value(name, value) {
856
868
  const path = getPath(this, name, false);
857
- const result= path.shift();
869
+ const result = path.shift();
858
870
  const prop = path.pop();
859
871
  if (this.getParentTemplate() && hasProp(result, prop)) {
860
872
  return result[prop]
@@ -894,116 +906,104 @@ const createContextScope = (config, methods) => {
894
906
  return ContextScope
895
907
  };
896
908
 
897
- class Context {
898
- #scope
899
-
900
- constructor(config, methods) {
901
- this.configure(config, methods);
902
- }
903
-
904
- create(data) {
905
- return new this.#scope(data)
906
- }
907
-
908
- configure(config, methods) {
909
- this.#scope = createContextScope(config, methods);
910
- }
911
-
912
- helpers(methods) {
913
- extend(this.#scope.prototype, methods || {});
914
- }
915
- }
916
-
917
- class EJS {
918
- #config = {}
919
- #extend = {}
920
- #context
921
- #compiler
922
- #cache
923
- #template
924
-
925
- constructor(options) {
926
- configSchema(this.#config, options || {});
927
- this.#context = new Context(this.#config, this.#extend);
928
- this.#compiler = new Compiler(this.#config);
929
- this.#cache = new Cache(this.#config);
930
- this.#template = new Template(this.#config, this.#cache, this.#compiler);
931
- //
932
- bindContext(this, ['configure', 'create', 'render', 'require', 'context', 'preload', 'compile', 'helpers']);
933
- //
934
- this.helpers({ require: this.require, render: this.render });
935
- }
936
-
937
- configure(options) {
938
- configSchema(this.#config, options || {});
939
- this.#context.configure(this.#config, this.#extend);
940
- this.#compiler.configure(this.#config);
941
- this.#cache.configure(this.#config);
942
- this.#template.configure(this.#config);
943
- return this.#config
944
- }
945
-
946
- filePath(name) {
947
- return ext(name, this.#config.extension)
948
- }
949
-
950
- require(name) {
951
- const scope = this.context({});
952
- return this.#output(this.filePath(name), scope).then(() => scope.getMacro())
953
- }
954
-
955
- render(name, data) {
956
- const scope = this.context(data);
957
- return this.#output(this.filePath(name), scope).then(this.outputContent(name, scope))
909
+ const Context = (options, methods) => {
910
+ /**
911
+ * @type {InstanceType<ContextScope>}
912
+ */
913
+ let Scope;
914
+ const create = (data) => {
915
+ return new Scope(data)
916
+ };
917
+ const helpers = (methods) => {
918
+ extend(Scope.prototype, methods || {});
919
+ };
920
+ const configure = (options, methods) => {
921
+ Scope = createContextScope(options, methods);
922
+ };
923
+ configure(options, methods);
924
+ return {
925
+ configure,
926
+ create,
927
+ helpers
958
928
  }
929
+ };
959
930
 
960
- outputContent(name, scope) {
931
+ const EJS = (options = {}) => {
932
+ const config = configSchema({}, options);
933
+ const methods = {};
934
+ const context = Context(config, methods);
935
+ const compiler = Compiler(config);
936
+ const cache = Cache(config);
937
+ const template = Template(config, cache, compiler);
938
+ const configure = (options = {}) => {
939
+ configSchema(config, options || {});
940
+ context.configure(config, methods);
941
+ compiler.configure(config);
942
+ cache.configure(config);
943
+ template.configure(config);
944
+ return config
945
+ };
946
+ const filePath = (name) => {
947
+ return ext(name, config.extension)
948
+ };
949
+ const require = (name) => {
950
+ const scope = createContext({});
951
+ return output(filePath(name), scope).then(() => scope.getMacro())
952
+ };
953
+ const render = (name, data) => {
954
+ const scope = createContext(data);
955
+ return output(filePath(name), scope).then(outputContent(name, scope))
956
+ };
957
+ const outputContent = (name, scope) => {
961
958
  return (content) => {
962
959
  if (scope.getExtend()) {
963
960
  scope.setExtend(false);
964
- return this.renderLayout(scope.getLayout(), scope, name)
961
+ return renderLayout(scope.getLayout(), scope, name)
965
962
  }
966
963
  return content
967
964
  }
968
- }
969
-
970
- renderLayout(name, data, parent) {
971
- const scope = this.context(data);
965
+ };
966
+ const renderLayout = (name, data, parent) => {
967
+ const scope = createContext(data);
972
968
  if (parent) scope.setParentTemplate(parent);
973
- return this.#output(this.filePath(name), scope).then(this.outputContent(name, scope))
974
- }
975
-
976
- helpers(methods) {
977
- this.#context.helpers(extend(this.#extend, methods));
978
- }
979
-
980
- context(data) {
981
- return this.#context.create(data)
982
- }
983
-
984
- compile(content, path) {
985
- return this.#compiler.compile(content, path)
986
- }
987
-
988
- preload(list) {
989
- return this.#cache.load(list || {})
990
- }
991
-
992
- create(options) {
993
- return new this.constructor(options)
994
- }
995
-
996
- #output(path, scope) {
997
- const { globalHelpers } = this.#config;
969
+ return output(filePath(name), scope).then(outputContent(name, scope))
970
+ };
971
+ const helpers = (extendMethods) => {
972
+ context.helpers(extend(methods, extendMethods));
973
+ };
974
+ const createContext = (data) => {
975
+ return context.create(data)
976
+ };
977
+ const compile = (content, path) => {
978
+ return compiler.compile(content, path)
979
+ };
980
+ const preload = (list) => {
981
+ return cache.load(list || {})
982
+ };
983
+ const create = (config) => {
984
+ return EJS(config)
985
+ };
986
+ const output = (path, scope) => {
998
987
  const params = [scope, scope.useComponent, scope.useElement, scope.getBuffer(), scope.useSafeValue];
999
- const globals = globalHelpers
988
+ const globals = config.globalHelpers
1000
989
  .filter((name) => isFunction(scope[name]))
1001
990
  .map((name) => scope[name].bind(scope));
1002
- return this.#template
991
+ return template
1003
992
  .get(path)
1004
993
  .then((callback) => callback.apply(scope, params.concat(globals)))
994
+ };
995
+ helpers({ render, require });
996
+ return {
997
+ configure,
998
+ create,
999
+ createContext,
1000
+ render,
1001
+ require,
1002
+ preload,
1003
+ compile,
1004
+ helpers
1005
1005
  }
1006
- }
1006
+ };
1007
1007
 
1008
1008
  const templateCache = {};
1009
1009
 
@@ -1013,7 +1013,7 @@ const getOrigin = (url, secure) => {
1013
1013
  return url.origin
1014
1014
  };
1015
1015
 
1016
- const { render, context, helpers, configure } = new EJS({
1016
+ const { render, createContext, helpers, configure } = EJS({
1017
1017
  cache: false,
1018
1018
  withObject: false,
1019
1019
  resolver(path, name) {
@@ -1021,7 +1021,7 @@ const { render, context, helpers, configure } = new EJS({
1021
1021
  if (isFunction(templateCache[name])) {
1022
1022
  resolve(templateCache[name]);
1023
1023
  } else {
1024
- reject(new TemplateNotFound(`template ${name} not found`));
1024
+ reject(new TemplateNotFound());
1025
1025
  }
1026
1026
  })
1027
1027
  },
@@ -1057,7 +1057,7 @@ const setTemplates = useTemplates;
1057
1057
  function useRenderer({ templates = {}, version, secure = true } = {}) {
1058
1058
  useTemplates(templates);
1059
1059
  return async (c, next) => {
1060
- c.data = context({});
1060
+ c.data = createContext({});
1061
1061
  c.data.set('version', version);
1062
1062
  c.data.set('origin', getOrigin(c.req.url, secure));
1063
1063
  c.data.set('path', c.req.path);
@@ -1075,4 +1075,4 @@ function useRenderer({ templates = {}, version, secure = true } = {}) {
1075
1075
  */
1076
1076
  const setRenderer = useRenderer;
1077
1077
 
1078
- export { TemplateError, TemplateNotFound, TemplateSyntaxError, configure, context, helpers, render, setRenderer, setTemplates, useRenderer, useTemplates };
1078
+ export { TemplateError, TemplateNotFound, TemplateSyntaxError, configure, createContext, helpers, render, setRenderer, setTemplates, useRenderer, useTemplates };