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