@kosatyi/ejs 0.0.54 → 0.0.56

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
@@ -1,38 +1,5 @@
1
- import path from 'path';
2
1
  import fs from 'fs';
3
-
4
- const defaults = {};
5
-
6
- defaults.export = 'ejsPrecompiled';
7
-
8
- defaults.watch = false;
9
-
10
- defaults.path = 'views';
11
-
12
- defaults.resolver = null;
13
-
14
- defaults.extension = 'ejs';
15
-
16
- defaults.rmWhitespace = true;
17
-
18
- defaults.withObject = true;
19
-
20
- defaults.vars = {
21
- SCOPE: 'ejs',
22
- COMPONENT: 'ui',
23
- EXTEND: '$$e',
24
- BUFFER: '$$a',
25
- LAYOUT: '$$l',
26
- BLOCKS: '$$b',
27
- MACRO: '$$m',
28
- SAFE: '$$v',
29
- };
30
-
31
- defaults.token = {
32
- start: '<%',
33
- end: '%>',
34
- regex: '([\\s\\S]+?)',
35
- };
2
+ import path from 'path';
36
3
 
37
4
  const typeProp = function () {
38
5
  const args = [].slice.call(arguments);
@@ -105,6 +72,14 @@ const getPath = (context, name) => {
105
72
  return [data, prop]
106
73
  };
107
74
 
75
+ const bindContext = (object, context, methods = []) => {
76
+ methods.forEach((name) => {
77
+ if (name in object) {
78
+ object[name] = object[name].bind(context);
79
+ }
80
+ });
81
+ };
82
+
108
83
  const ext = (path, defaults) => {
109
84
  const ext = path.split('.').pop();
110
85
  if (ext !== defaults) {
@@ -179,50 +154,165 @@ const hasProp = (object, prop) => {
179
154
  return object && object.hasOwnProperty(prop)
180
155
  };
181
156
 
182
- const selfClosed = [
183
- 'area',
184
- 'base',
185
- 'br',
186
- 'col',
187
- 'embed',
188
- 'hr',
189
- 'img',
190
- 'input',
191
- 'link',
192
- 'meta',
193
- 'param',
194
- 'source',
195
- 'track',
196
- 'wbr',
197
- ];
157
+ const defaults = {};
198
158
 
199
- const space = ' ';
200
- const quote = '"';
201
- const equal = '=';
202
- const slash = '/';
203
- const lt = '<';
204
- const gt = '>';
159
+ defaults.export = 'ejsPrecompiled';
205
160
 
206
- const element = (tag, attrs, content) => {
207
- const result = [];
208
- const hasClosedTag = selfClosed.indexOf(tag) === -1;
209
- const attributes = map(attrs, (value, key) => {
210
- if (value !== null && value !== undefined) {
211
- return [
212
- entities(key),
213
- [quote, entities(value), quote].join(''),
214
- ].join(equal)
161
+ defaults.watch = false;
162
+
163
+ defaults.chokidar = null;
164
+
165
+ defaults.path = 'views';
166
+
167
+ defaults.resolver = null;
168
+
169
+ defaults.extension = 'ejs';
170
+
171
+ defaults.rmWhitespace = true;
172
+
173
+ defaults.withObject = true;
174
+
175
+ defaults.vars = {
176
+ SCOPE: 'ejs',
177
+ COMPONENT: 'ui',
178
+ EXTEND: '$$e',
179
+ BUFFER: '$$a',
180
+ LAYOUT: '$$l',
181
+ BLOCKS: '$$b',
182
+ MACRO: '$$m',
183
+ SAFE: '$$v',
184
+ };
185
+
186
+ defaults.token = {
187
+ start: '<%',
188
+ end: '%>',
189
+ regex: '([\\s\\S]+?)',
190
+ };
191
+
192
+ const configSchema = (config, options) => {
193
+ extend(config, {
194
+ path: typeProp(isString, defaults.path, config.path, options.path),
195
+ export: typeProp(
196
+ isString,
197
+ defaults.export,
198
+ config.export,
199
+ options.export
200
+ ),
201
+ resolver: typeProp(
202
+ isFunction,
203
+ defaults.resolver,
204
+ config.resolver,
205
+ options.resolver
206
+ ),
207
+ extension: typeProp(
208
+ isString,
209
+ defaults.extension,
210
+ config.extension,
211
+ options.extension
212
+ ),
213
+ withObject: typeProp(
214
+ isBoolean,
215
+ defaults.withObject,
216
+ config.withObject,
217
+ options.withObject
218
+ ),
219
+ rmWhitespace: typeProp(
220
+ isBoolean,
221
+ defaults.rmWhitespace,
222
+ config.rmWhitespace,
223
+ options.rmWhitespace
224
+ ),
225
+ watch: typeProp(isBoolean, defaults.watch, config.watch, options.watch),
226
+ chokidar: typeProp(
227
+ isObject,
228
+ defaults.export,
229
+ config.export,
230
+ options.export
231
+ ),
232
+ token: extend({}, defaults.token, config.token, options.token),
233
+ vars: extend({}, defaults.vars, config.vars, options.vars),
234
+ });
235
+ };
236
+
237
+ const resolvePath = (path, template) => {
238
+ template = [path, template].join('/');
239
+ template = template.replace(/\/\//g, '/');
240
+ return template
241
+ };
242
+
243
+ const httpRequest = (path, template) => {
244
+ return fetch(resolvePath(path, template)).then((response) =>
245
+ response.text()
246
+ )
247
+ };
248
+
249
+ const fileSystem = (path, template) => {
250
+ return new Promise((resolve, reject) => {
251
+ fs.readFile(resolvePath(path, template), (error, data) => {
252
+ if (error) {
253
+ reject(error);
254
+ } else {
255
+ resolve(data.toString());
256
+ }
257
+ });
258
+ })
259
+ };
260
+
261
+ class Template {
262
+ constructor(config, cache, compiler) {
263
+ this.cache = cache;
264
+ this.watcher = {
265
+ unwatch() {},
266
+ on() {},
267
+ };
268
+ this.compiler = compiler;
269
+ this.configure(config);
270
+ }
271
+ configure(config) {
272
+ this.path = config.path;
273
+ this.chokidar = config.chokidar;
274
+ this.resolver = isFunction(config.resolver)
275
+ ? config.resolver
276
+ : isNode()
277
+ ? fileSystem
278
+ : httpRequest;
279
+ if (config.watch && isNode()) {
280
+ if (this.watcher) {
281
+ this.watcher.unwatch('.');
282
+ }
283
+ if (this.chokidar) {
284
+ this.watcher = this.chokidar
285
+ .watch('.', { cwd: this.path })
286
+ .on('change', (name) => {
287
+ this.cache.remove(name);
288
+ });
289
+ }
215
290
  }
216
- }).join(space);
217
- result.push([lt, tag, space, attributes, gt].join(''));
218
- if (content) {
219
- result.push(content instanceof Array ? content.join('') : content);
220
291
  }
221
- if (hasClosedTag) {
222
- result.push([lt, slash, tag, gt].join(''));
292
+ resolve(template) {
293
+ return this.resolver(this.path, template)
223
294
  }
224
- return result.join('')
225
- };
295
+ result(template, content) {
296
+ this.cache.set(template, content);
297
+ return content
298
+ }
299
+ compile(content, template) {
300
+ if (isFunction(content)) {
301
+ return content
302
+ } else {
303
+ return this.compiler.compile(content, template)
304
+ }
305
+ }
306
+ get(template) {
307
+ if (this.cache.exist(template)) {
308
+ return this.cache.resolve(template)
309
+ }
310
+ const content = this.resolve(template).then((content) =>
311
+ this.result(template, this.compile(content, template))
312
+ );
313
+ return this.result(template, content)
314
+ }
315
+ }
226
316
 
227
317
  const tagList = [
228
318
  {
@@ -343,84 +433,87 @@ class Compiler {
343
433
  }
344
434
  }
345
435
 
346
- const resolvePath = (path, template) => {
347
- template = [path, template].join('/');
348
- template = template.replace(/\/\//g, '/');
349
- return template
350
- };
351
-
352
- const httpRequest = (path, template) => {
353
- return fetch(resolvePath(path, template)).then((response) =>
354
- response.text()
355
- )
356
- };
357
-
358
- const fileSystem = (path, template) => {
359
- return new Promise((resolve, reject) => {
360
- fs.readFile(resolvePath(path, template), (error, data) => {
361
- if (error) {
362
- reject(error);
363
- } else {
364
- resolve(data.toString());
365
- }
366
- });
367
- })
368
- };
436
+ const global = typeof globalThis !== 'undefined' ? globalThis : window || self;
369
437
 
370
- class Template {
371
- constructor(config, cache, compiler) {
372
- this.cache = cache;
373
- this.watcher = null;
374
- this.compiler = compiler;
438
+ class Cache {
439
+ list = {}
440
+ constructor(config) {
375
441
  this.configure(config);
442
+ if (isNode() === false) {
443
+ this.load(global[this.namespace]);
444
+ }
376
445
  }
377
446
  configure(config) {
378
- this.path = config.path;
379
- this.chokidar = config.chokidar;
380
- this.resolver = isFunction(config.resolver)
381
- ? config.resolver
382
- : isNode()
383
- ? fileSystem
384
- : httpRequest;
385
- if (config.watch && config.chokidar && isNode()) {
386
- if (this.watcher) {
387
- this.watcher.unwatch('.');
388
- }
389
- this.watcher = this.chokidar
390
- .watch('.', { cwd: this.path })
391
- .on('change', (name) => {
392
- this.cache.remove(name);
393
- })
394
- .on('error', (error) => {
395
- console.log('watcher error: ' + error);
396
- });
397
- }
447
+ this.list = {};
448
+ this.namespace = config.export;
398
449
  }
399
- resolve(template) {
400
- return this.resolver(this.path, template)
450
+ load(data) {
451
+ extend(this.list, data);
452
+ return this
401
453
  }
402
- result(template, content) {
403
- this.cache.set(template, content);
404
- return content
454
+ exist(key) {
455
+ return hasProp(this.list, key)
405
456
  }
406
- compile(content, template) {
407
- if (isFunction(content)) {
408
- return content
409
- } else {
410
- return this.compiler.compile(content, template)
411
- }
457
+ get(key) {
458
+ return this.list[key]
412
459
  }
413
- get(template) {
414
- if (this.cache.exist(template)) {
415
- return this.cache.resolve(template)
416
- }
417
- const content = this.resolve(template).then((content) =>
418
- this.result(template, this.compile(content, template))
419
- );
420
- return this.result(template, content)
460
+ remove(key) {
461
+ delete this.list[key];
462
+ }
463
+ resolve(key) {
464
+ return Promise.resolve(this.get(key))
465
+ }
466
+ set(key, value) {
467
+ this.list[key] = value;
468
+ return this
421
469
  }
422
470
  }
423
471
 
472
+ const selfClosed = [
473
+ 'area',
474
+ 'base',
475
+ 'br',
476
+ 'col',
477
+ 'embed',
478
+ 'hr',
479
+ 'img',
480
+ 'input',
481
+ 'link',
482
+ 'meta',
483
+ 'param',
484
+ 'source',
485
+ 'track',
486
+ 'wbr',
487
+ ];
488
+
489
+ const space = ' ';
490
+ const quote = '"';
491
+ const equal = '=';
492
+ const slash = '/';
493
+ const lt = '<';
494
+ const gt = '>';
495
+
496
+ const element = (tag, attrs, content) => {
497
+ const result = [];
498
+ const hasClosedTag = selfClosed.indexOf(tag) === -1;
499
+ const attributes = map(attrs, (value, key) => {
500
+ if (value !== null && value !== undefined) {
501
+ return [
502
+ entities(key),
503
+ [quote, entities(value), quote].join(''),
504
+ ].join(equal)
505
+ }
506
+ }).join(space);
507
+ result.push([lt, tag, space, attributes, gt].join(''));
508
+ if (content) {
509
+ result.push(content instanceof Array ? content.join('') : content);
510
+ }
511
+ if (hasClosedTag) {
512
+ result.push([lt, slash, tag, gt].join(''));
513
+ }
514
+ return result.join('')
515
+ };
516
+
424
517
  const resolve = (list) => Promise.all(list).then((list) => list.join(''));
425
518
 
426
519
  const createBuffer = () => {
@@ -699,109 +792,38 @@ class Context {
699
792
  }
700
793
  }
701
794
 
702
- const global = typeof globalThis !== 'undefined' ? globalThis : window || self;
703
-
704
- class Cache {
705
- list = {}
706
- constructor(config) {
707
- this.configure(config);
708
- if (isNode() === false) {
709
- this.load(global[this.namespace]);
710
- }
711
- }
712
- configure(config) {
713
- this.list = {};
714
- this.namespace = config.export;
715
- }
716
- load(data) {
717
- extend(this.list, data);
718
- return this
719
- }
720
- exist(key) {
721
- return hasProp(this.list, key)
722
- }
723
- get(key) {
724
- return this.list[key]
795
+ class EJS {
796
+ export = [
797
+ 'cache',
798
+ 'render',
799
+ 'require',
800
+ 'helpers',
801
+ 'configure',
802
+ 'preload',
803
+ 'compiler',
804
+ '__express',
805
+ ]
806
+ constructor(options = {}) {
807
+ this.config = {};
808
+ this.scope = {};
809
+ configSchema(this.config, options);
810
+ bindContext(this, this, this.export);
811
+ this.context = new Context(this.config);
812
+ this.compiler = new Compiler(this.config);
813
+ this.cache = new Cache(this.config);
814
+ this.template = new Template(this.config, this.cache, this.compiler);
815
+ this.helpers({ require: this.require, render: this.render });
725
816
  }
726
- remove(key) {
727
- delete this.list[key];
817
+ configure(options = {}) {
818
+ configSchema(this.config, options);
819
+ this.context.configure(this.config, this.scope);
820
+ this.compiler.configure(this.config);
821
+ this.cache.configure(this.config);
822
+ this.template.configure(this.config);
823
+ return this.config
728
824
  }
729
- resolve(key) {
730
- return Promise.resolve(this.get(key))
731
- }
732
- set(key, value) {
733
- this.list[key] = value;
734
- return this
735
- }
736
- }
737
-
738
- const configSchema = (config, options) => {
739
- extend(config, {
740
- path: typeProp(isString, defaults.path, config.path, options.path),
741
- export: typeProp(
742
- isString,
743
- defaults.export,
744
- config.export,
745
- options.export
746
- ),
747
- resolver: typeProp(
748
- isFunction,
749
- defaults.resolver,
750
- config.resolver,
751
- options.resolver
752
- ),
753
- extension: typeProp(
754
- isString,
755
- defaults.extension,
756
- config.extension,
757
- options.extension
758
- ),
759
- withObject: typeProp(
760
- isBoolean,
761
- defaults.withObject,
762
- config.withObject,
763
- options.withObject
764
- ),
765
- rmWhitespace: typeProp(
766
- isBoolean,
767
- defaults.rmWhitespace,
768
- config.rmWhitespace,
769
- options.rmWhitespace
770
- ),
771
- watch: typeProp(isBoolean, defaults.watch, config.watch, options.watch),
772
- chokidar: typeProp(
773
- isObject,
774
- defaults.export,
775
- config.export,
776
- options.export
777
- ),
778
- token: extend({}, defaults.token, config.token, options.token),
779
- vars: extend({}, defaults.vars, config.vars, options.vars),
780
- });
781
- };
782
-
783
- const create = (options) => {
784
- const config = {};
785
- const scope = {};
786
-
787
- configSchema(config, options || {});
788
-
789
- const context = new Context(config);
790
- const compiler = new Compiler(config);
791
- const cache = new Cache(config);
792
- const template = new Template(config, cache, compiler);
793
-
794
- const configure = (options) => {
795
- configSchema(config, options);
796
- context.configure(config, scope);
797
- compiler.configure(config);
798
- cache.configure(config);
799
- template.configure(config);
800
- return config
801
- };
802
-
803
- const output = (path, scope) => {
804
- return template.get(path).then(function (callback) {
825
+ output(path, scope) {
826
+ return this.template.get(path).then(function (callback) {
805
827
  return callback.call(
806
828
  scope,
807
829
  scope,
@@ -810,35 +832,40 @@ const create = (options) => {
810
832
  safeValue
811
833
  )
812
834
  })
813
- };
814
-
815
- const require = (name) => {
816
- const filepath = ext(name, config.extension);
817
- const scope = context.create({});
818
- return output(filepath, scope).then(() => {
819
- return scope.getMacro()
820
- })
821
- };
822
-
823
- const render = (name, data) => {
824
- const filepath = ext(name, config.extension);
825
- const scope = context.create(data);
826
- return output(filepath, scope).then((content) => {
835
+ }
836
+ render(name, data) {
837
+ const filepath = ext(name, this.config.extension);
838
+ const scope = this.context.create(data);
839
+ return this.output(filepath, scope).then((content) => {
827
840
  if (scope.getExtend()) {
828
841
  scope.setExtend(false);
829
842
  const layout = scope.getLayout();
830
843
  const data = scope.clone();
831
- return render(layout, data)
844
+ return this.render(layout, data)
832
845
  }
833
846
  return content
834
847
  })
835
- };
836
-
837
- const helpers = (methods) => {
838
- context.helpers(extend(scope, methods || {}));
839
- };
840
-
841
- const __express = (name, options, callback) => {
848
+ }
849
+ require(name) {
850
+ const filepath = ext(name, this.config.extension);
851
+ const scope = this.context.create({});
852
+ return this.output(filepath, scope).then(() => {
853
+ return scope.getMacro()
854
+ })
855
+ }
856
+ create(options = {}) {
857
+ return new EJS(options)
858
+ }
859
+ helpers(methods = {}) {
860
+ this.context.helpers(extend(this.scope, methods));
861
+ }
862
+ preload(list = {}) {
863
+ return this.cache.load(list)
864
+ }
865
+ compile(content, path) {
866
+ return this.compiler.compile(content, path)
867
+ }
868
+ __express(name, options, callback) {
842
869
  if (isFunction(options)) {
843
870
  callback = options;
844
871
  options = {};
@@ -855,42 +882,30 @@ const create = (options) => {
855
882
  const filename = path.relative(viewPath, name);
856
883
  viewOptions.path = viewPath;
857
884
  viewOptions.cache = viewCache;
858
- configure(viewOptions);
859
- return render(filename, options)
885
+ this.configure(viewOptions);
886
+ return this.render(filename, options)
860
887
  .then((content) => {
861
888
  callback(null, content);
862
889
  })
863
890
  .catch((error) => {
864
891
  callback(error);
865
892
  })
866
- };
867
-
868
- const preload = (list) => cache.load(list);
869
-
870
- const compile = (content, path) => compiler.compile(content, path);
871
-
872
- helpers({ require, render });
873
-
874
- return {
875
- context,
876
- render,
877
- helpers,
878
- configure,
879
- compile,
880
- create,
881
- preload,
882
- __express,
883
893
  }
884
- };
894
+ }
895
+
896
+ const ejs = new EJS({
897
+ /** defaults options **/
898
+ });
885
899
 
886
900
  const {
887
- context,
901
+ __express,
888
902
  render,
889
- helpers,
890
- configure,
903
+ context,
891
904
  compile,
905
+ helpers,
892
906
  preload,
893
- __express,
894
- } = create({});
907
+ configure,
908
+ create,
909
+ } = ejs;
895
910
 
896
- export { __express, compile, configure, context, create, element, helpers, preload, render, safeValue };
911
+ export { EJS, __express, compile, configure, context, create, element, helpers, preload, render, safeValue };