@kosatyi/ejs 0.0.76 → 0.0.78
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/README.md +1 -1
- package/bin/bundler.js +43 -0
- package/dist/cjs/browser.js +44 -11
- package/dist/cjs/bundler.js +171 -0
- package/dist/cjs/index.js +44 -11
- package/dist/cjs/worker.js +1278 -0
- package/dist/esm/browser.js +56 -21
- package/dist/esm/bundler.js +168 -0
- package/dist/esm/index.js +56 -21
- package/dist/esm/worker.js +1034 -0
- package/dist/umd/browser.js +44 -11
- package/dist/umd/browser.min.js +1 -1
- package/dist/umd/index.js +44 -11
- package/dist/umd/index.min.js +1 -1
- package/dist/umd/worker.js +1284 -0
- package/dist/umd/worker.min.js +1 -0
- package/package.json +23 -7
- package/types/bundler.d.ts +30 -0
- package/types/ejs.d.ts +86 -0
- package/types/global.d.ts +2 -87
- package/dist/cjs/package.json +0 -3
package/dist/esm/browser.js
CHANGED
|
@@ -369,6 +369,7 @@ function Compiler(config) {
|
|
|
369
369
|
this.compile = function (content, path) {
|
|
370
370
|
const { SCOPE, SAFE, BUFFER, COMPONENT } = compiler.vars;
|
|
371
371
|
const GLOBALS = compiler.globalHelpers;
|
|
372
|
+
content = String(content);
|
|
372
373
|
if (compiler.rmWhitespace) {
|
|
373
374
|
content = content
|
|
374
375
|
.replace(/[\r\n]+/g, '\n')
|
|
@@ -387,7 +388,7 @@ function Compiler(config) {
|
|
|
387
388
|
});
|
|
388
389
|
});
|
|
389
390
|
source += `');`;
|
|
390
|
-
source = `try{${source}}catch(e){
|
|
391
|
+
source = `try{${source}}catch(e){return ${BUFFER}.error(e)}`;
|
|
391
392
|
if (compiler.withObject) {
|
|
392
393
|
source = `with(${SCOPE}){${source}}`;
|
|
393
394
|
}
|
|
@@ -502,10 +503,40 @@ const element = (tag, attrs, content) => {
|
|
|
502
503
|
return result.join('')
|
|
503
504
|
};
|
|
504
505
|
|
|
506
|
+
function TemplateError(message) {
|
|
507
|
+
this.code = 1;
|
|
508
|
+
this.name = 'TemplateError';
|
|
509
|
+
this.message = message;
|
|
510
|
+
Error.call(this);
|
|
511
|
+
}
|
|
512
|
+
Object.setPrototypeOf(TemplateNotFound.prototype, Error.prototype);
|
|
513
|
+
|
|
514
|
+
function TemplateNotFound(message) {
|
|
515
|
+
TemplateError.call(this);
|
|
516
|
+
this.code = 404;
|
|
517
|
+
this.name = 'TemplateNotFound';
|
|
518
|
+
this.message = message;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
Object.setPrototypeOf(TemplateNotFound.prototype, TemplateError.prototype);
|
|
522
|
+
|
|
523
|
+
function TemplateSyntaxError(message) {
|
|
524
|
+
TemplateError.call(this);
|
|
525
|
+
this.code = 500;
|
|
526
|
+
this.name = 'TemplateSyntaxError';
|
|
527
|
+
this.message = message;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
Object.setPrototypeOf(TemplateSyntaxError.prototype, TemplateError.prototype);
|
|
531
|
+
|
|
505
532
|
function resolve(list) {
|
|
506
533
|
return Promise.all(list || []).then((list) => list.join(''))
|
|
507
534
|
}
|
|
508
535
|
|
|
536
|
+
function reject(error) {
|
|
537
|
+
return Promise.reject(new TemplateSyntaxError(error.message))
|
|
538
|
+
}
|
|
539
|
+
|
|
509
540
|
function createBuffer() {
|
|
510
541
|
let store = [],
|
|
511
542
|
array = [];
|
|
@@ -525,7 +556,7 @@ function createBuffer() {
|
|
|
525
556
|
return resolve(result)
|
|
526
557
|
};
|
|
527
558
|
buffer.error = function (e) {
|
|
528
|
-
|
|
559
|
+
return reject(e)
|
|
529
560
|
};
|
|
530
561
|
buffer.end = function () {
|
|
531
562
|
return resolve(array)
|
|
@@ -545,7 +576,11 @@ function Context(config) {
|
|
|
545
576
|
this.helpers = function (methods) {
|
|
546
577
|
extend(Scope.prototype, methods || {});
|
|
547
578
|
};
|
|
548
|
-
|
|
579
|
+
/**
|
|
580
|
+
* @name ContextScope
|
|
581
|
+
* @param data
|
|
582
|
+
* @constructor
|
|
583
|
+
*/
|
|
549
584
|
function Scope(data) {
|
|
550
585
|
this[BLOCKS] = {};
|
|
551
586
|
this[MACRO] = {};
|
|
@@ -711,8 +746,8 @@ function Context(config) {
|
|
|
711
746
|
const prop = path.pop();
|
|
712
747
|
return hasProp(result, prop) ? result[prop] : defaults
|
|
713
748
|
},
|
|
714
|
-
writable:
|
|
715
|
-
configurable:
|
|
749
|
+
writable: true,
|
|
750
|
+
configurable: true,
|
|
716
751
|
enumerable: false,
|
|
717
752
|
},
|
|
718
753
|
set: {
|
|
@@ -884,27 +919,27 @@ function EJS(options) {
|
|
|
884
919
|
const cache = new Cache();
|
|
885
920
|
const template = new Template(config, cache, compiler);
|
|
886
921
|
|
|
887
|
-
const output = (path,
|
|
922
|
+
const output = (path, scope) => {
|
|
923
|
+
const { globalHelpers } = config;
|
|
888
924
|
const params = [
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
925
|
+
scope,
|
|
926
|
+
scope.getComponent(),
|
|
927
|
+
scope.getBuffer(),
|
|
892
928
|
safeValue,
|
|
893
|
-
]
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
return template
|
|
899
|
-
|
|
900
|
-
|
|
929
|
+
].concat(
|
|
930
|
+
globalHelpers
|
|
931
|
+
.filter((name) => isFunction(scope[name]))
|
|
932
|
+
.map((name) => scope[name].bind(scope))
|
|
933
|
+
);
|
|
934
|
+
return template
|
|
935
|
+
.get(path)
|
|
936
|
+
.then((callback) => callback.apply(scope, params))
|
|
901
937
|
};
|
|
938
|
+
|
|
902
939
|
const require = (name) => {
|
|
903
940
|
const filepath = ext(name, config.extension);
|
|
904
941
|
const scope = context.create({});
|
|
905
|
-
return output(filepath, scope).then(() =>
|
|
906
|
-
return scope.getMacro()
|
|
907
|
-
})
|
|
942
|
+
return output(filepath, scope).then(() => scope.getMacro())
|
|
908
943
|
};
|
|
909
944
|
const render = (name, data) => {
|
|
910
945
|
const filepath = ext(name, config.extension);
|
|
@@ -953,7 +988,7 @@ function EJS(options) {
|
|
|
953
988
|
const httpRequest = (path, template) => {
|
|
954
989
|
return fetch(joinPath(path, template)).then(
|
|
955
990
|
(response) => response.text(),
|
|
956
|
-
(reason) =>
|
|
991
|
+
(reason) => new TemplateError(reason)
|
|
957
992
|
)
|
|
958
993
|
};
|
|
959
994
|
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { promises } from 'fs';
|
|
2
|
+
import { glob } from 'glob';
|
|
3
|
+
import { join, extname, dirname } from 'path';
|
|
4
|
+
import { minify } from 'terser';
|
|
5
|
+
import { configure, compile } from './index.js';
|
|
6
|
+
import babel from '@babel/core';
|
|
7
|
+
|
|
8
|
+
const isPlainObject = function (obj) {
|
|
9
|
+
return Object.prototype.toString.call(obj) === '[object Object]'
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const extend = (target, ...sources) => {
|
|
13
|
+
return Object.assign(target, ...sources.filter(isPlainObject))
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
class Bundler {
|
|
17
|
+
/**
|
|
18
|
+
* @type {BundlerOptions}
|
|
19
|
+
*/
|
|
20
|
+
options = {
|
|
21
|
+
target: [],
|
|
22
|
+
transform: true,
|
|
23
|
+
minify: true,
|
|
24
|
+
timestamp: true,
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* @type {EjsConfig}
|
|
28
|
+
*/
|
|
29
|
+
config = {}
|
|
30
|
+
constructor(options, config) {
|
|
31
|
+
extend(this.options, options || {});
|
|
32
|
+
this.config = configure(config || {});
|
|
33
|
+
this.templates = {};
|
|
34
|
+
}
|
|
35
|
+
stageRead(path) {
|
|
36
|
+
return promises
|
|
37
|
+
.readFile(join(this.config.path, path))
|
|
38
|
+
.then((response) => response.toString())
|
|
39
|
+
}
|
|
40
|
+
stageCompile(content, name) {
|
|
41
|
+
return compile(content, name).source
|
|
42
|
+
}
|
|
43
|
+
async stageMinify(content) {
|
|
44
|
+
if (this.options.minify === false) return content
|
|
45
|
+
const config = {
|
|
46
|
+
compress: {
|
|
47
|
+
dead_code: false,
|
|
48
|
+
side_effects: false,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
const response = await minify(content, config);
|
|
52
|
+
return response.code
|
|
53
|
+
}
|
|
54
|
+
async stageTransform(content) {
|
|
55
|
+
if (this.options.transform === false) return content
|
|
56
|
+
const config = {
|
|
57
|
+
presets: [['@babel/preset-env']],
|
|
58
|
+
sourceType: 'script',
|
|
59
|
+
};
|
|
60
|
+
const response = await babel.transformAsync(content, config);
|
|
61
|
+
return response.code
|
|
62
|
+
}
|
|
63
|
+
getBundle() {
|
|
64
|
+
const transform = this.options.transform;
|
|
65
|
+
const moduleId = this.config.export;
|
|
66
|
+
const useStrict = this.config.withObject === false;
|
|
67
|
+
const timestamp = this.options.timestamp;
|
|
68
|
+
const out = [];
|
|
69
|
+
if (transform) {
|
|
70
|
+
out.push('(function(global,factory){');
|
|
71
|
+
out.push(
|
|
72
|
+
'typeof exports === "object" && typeof module !== "undefined" ?'
|
|
73
|
+
);
|
|
74
|
+
out.push('module.exports = factory():');
|
|
75
|
+
out.push(
|
|
76
|
+
'typeof define === "function" && define.amd ? define(factory):'
|
|
77
|
+
);
|
|
78
|
+
out.push(
|
|
79
|
+
'(global = typeof globalThis !== "undefined" ? globalThis:'
|
|
80
|
+
);
|
|
81
|
+
out.push('global || self,global["' + moduleId + '"] = factory())');
|
|
82
|
+
out.push('})(this,(function(){');
|
|
83
|
+
}
|
|
84
|
+
if (useStrict) out.push("'use strict'");
|
|
85
|
+
if (timestamp) out.push('const timestamp = '.concat(String(Date.now())));
|
|
86
|
+
out.push('const templates = {}');
|
|
87
|
+
Object.entries(this.templates).forEach(([name, content]) => {
|
|
88
|
+
name = JSON.stringify(name);
|
|
89
|
+
content = String(content);
|
|
90
|
+
out.push(`templates[${name}] = ${content}`);
|
|
91
|
+
});
|
|
92
|
+
if (transform) {
|
|
93
|
+
out.push('return templates');
|
|
94
|
+
out.push('}))');
|
|
95
|
+
} else {
|
|
96
|
+
out.push('export default templates');
|
|
97
|
+
}
|
|
98
|
+
return out.join('\n')
|
|
99
|
+
}
|
|
100
|
+
async watch() {
|
|
101
|
+
console.log(`ejs-bundle: watching directory - ${this.config.path}`);
|
|
102
|
+
try {
|
|
103
|
+
const watcher = promises.watch(this.config.path, { recursive: true });
|
|
104
|
+
for await (const { filename } of watcher) {
|
|
105
|
+
if (extname(filename).slice(1) === this.config.extension) {
|
|
106
|
+
console.log(`ejs-bundle: file is changed - ${filename}`);
|
|
107
|
+
await this.build();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
} catch (err) {
|
|
111
|
+
throw err
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async build() {
|
|
115
|
+
if (this.buildInProgress === true) return false
|
|
116
|
+
this.buildInProgress = true;
|
|
117
|
+
await this.concat().catch(console.error);
|
|
118
|
+
await this.output().catch(console.error);
|
|
119
|
+
console.log(`ejs-bundle: bundle complete - ${this.options.target}`);
|
|
120
|
+
this.buildInProgress = false;
|
|
121
|
+
}
|
|
122
|
+
async concat() {
|
|
123
|
+
const pattern = '**/*.'.concat(this.config.extension);
|
|
124
|
+
const list = await glob(pattern, { cwd: this.config.path });
|
|
125
|
+
for (let template of list) {
|
|
126
|
+
let content = '';
|
|
127
|
+
content = await this.stageRead(template);
|
|
128
|
+
content = await this.stageCompile(content, template);
|
|
129
|
+
this.templates[template] = content;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async output() {
|
|
133
|
+
const target = [].concat(this.options.target);
|
|
134
|
+
let content = this.getBundle();
|
|
135
|
+
if (this.options.transform) {
|
|
136
|
+
content = await this.stageTransform(content);
|
|
137
|
+
}
|
|
138
|
+
if (this.options.minify) {
|
|
139
|
+
content = await this.stageMinify(content);
|
|
140
|
+
}
|
|
141
|
+
for (let file of target) {
|
|
142
|
+
const folderPath = dirname(file);
|
|
143
|
+
const folderExists = await promises
|
|
144
|
+
.stat(folderPath)
|
|
145
|
+
.then(() => true)
|
|
146
|
+
.catch(() => false);
|
|
147
|
+
if (folderExists === false) {
|
|
148
|
+
await promises.mkdir(folderPath, { recursive: true });
|
|
149
|
+
}
|
|
150
|
+
await promises.writeFile(file, content);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const ejsBundle = (options, config) => {
|
|
156
|
+
const bundler = new Bundler(options, config);
|
|
157
|
+
return {
|
|
158
|
+
name: 'ejs-bundle',
|
|
159
|
+
async buildStart() {
|
|
160
|
+
await bundler.concat();
|
|
161
|
+
},
|
|
162
|
+
async buildEnd() {
|
|
163
|
+
await bundler.output();
|
|
164
|
+
},
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export { Bundler, ejsBundle };
|
package/dist/esm/index.js
CHANGED
|
@@ -372,6 +372,7 @@ function Compiler(config) {
|
|
|
372
372
|
this.compile = function (content, path) {
|
|
373
373
|
const { SCOPE, SAFE, BUFFER, COMPONENT } = compiler.vars;
|
|
374
374
|
const GLOBALS = compiler.globalHelpers;
|
|
375
|
+
content = String(content);
|
|
375
376
|
if (compiler.rmWhitespace) {
|
|
376
377
|
content = content
|
|
377
378
|
.replace(/[\r\n]+/g, '\n')
|
|
@@ -390,7 +391,7 @@ function Compiler(config) {
|
|
|
390
391
|
});
|
|
391
392
|
});
|
|
392
393
|
source += `');`;
|
|
393
|
-
source = `try{${source}}catch(e){
|
|
394
|
+
source = `try{${source}}catch(e){return ${BUFFER}.error(e)}`;
|
|
394
395
|
if (compiler.withObject) {
|
|
395
396
|
source = `with(${SCOPE}){${source}}`;
|
|
396
397
|
}
|
|
@@ -505,10 +506,40 @@ const element = (tag, attrs, content) => {
|
|
|
505
506
|
return result.join('')
|
|
506
507
|
};
|
|
507
508
|
|
|
509
|
+
function TemplateError(message) {
|
|
510
|
+
this.code = 1;
|
|
511
|
+
this.name = 'TemplateError';
|
|
512
|
+
this.message = message;
|
|
513
|
+
Error.call(this);
|
|
514
|
+
}
|
|
515
|
+
Object.setPrototypeOf(TemplateNotFound.prototype, Error.prototype);
|
|
516
|
+
|
|
517
|
+
function TemplateNotFound(message) {
|
|
518
|
+
TemplateError.call(this);
|
|
519
|
+
this.code = 404;
|
|
520
|
+
this.name = 'TemplateNotFound';
|
|
521
|
+
this.message = message;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
Object.setPrototypeOf(TemplateNotFound.prototype, TemplateError.prototype);
|
|
525
|
+
|
|
526
|
+
function TemplateSyntaxError(message) {
|
|
527
|
+
TemplateError.call(this);
|
|
528
|
+
this.code = 500;
|
|
529
|
+
this.name = 'TemplateSyntaxError';
|
|
530
|
+
this.message = message;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
Object.setPrototypeOf(TemplateSyntaxError.prototype, TemplateError.prototype);
|
|
534
|
+
|
|
508
535
|
function resolve(list) {
|
|
509
536
|
return Promise.all(list || []).then((list) => list.join(''))
|
|
510
537
|
}
|
|
511
538
|
|
|
539
|
+
function reject(error) {
|
|
540
|
+
return Promise.reject(new TemplateSyntaxError(error.message))
|
|
541
|
+
}
|
|
542
|
+
|
|
512
543
|
function createBuffer() {
|
|
513
544
|
let store = [],
|
|
514
545
|
array = [];
|
|
@@ -528,7 +559,7 @@ function createBuffer() {
|
|
|
528
559
|
return resolve(result)
|
|
529
560
|
};
|
|
530
561
|
buffer.error = function (e) {
|
|
531
|
-
|
|
562
|
+
return reject(e)
|
|
532
563
|
};
|
|
533
564
|
buffer.end = function () {
|
|
534
565
|
return resolve(array)
|
|
@@ -548,7 +579,11 @@ function Context(config) {
|
|
|
548
579
|
this.helpers = function (methods) {
|
|
549
580
|
extend(Scope.prototype, methods || {});
|
|
550
581
|
};
|
|
551
|
-
|
|
582
|
+
/**
|
|
583
|
+
* @name ContextScope
|
|
584
|
+
* @param data
|
|
585
|
+
* @constructor
|
|
586
|
+
*/
|
|
552
587
|
function Scope(data) {
|
|
553
588
|
this[BLOCKS] = {};
|
|
554
589
|
this[MACRO] = {};
|
|
@@ -714,8 +749,8 @@ function Context(config) {
|
|
|
714
749
|
const prop = path.pop();
|
|
715
750
|
return hasProp(result, prop) ? result[prop] : defaults
|
|
716
751
|
},
|
|
717
|
-
writable:
|
|
718
|
-
configurable:
|
|
752
|
+
writable: true,
|
|
753
|
+
configurable: true,
|
|
719
754
|
enumerable: false,
|
|
720
755
|
},
|
|
721
756
|
set: {
|
|
@@ -887,27 +922,27 @@ function EJS(options) {
|
|
|
887
922
|
const cache = new Cache();
|
|
888
923
|
const template = new Template(config, cache, compiler);
|
|
889
924
|
|
|
890
|
-
const output = (path,
|
|
925
|
+
const output = (path, scope) => {
|
|
926
|
+
const { globalHelpers } = config;
|
|
891
927
|
const params = [
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
928
|
+
scope,
|
|
929
|
+
scope.getComponent(),
|
|
930
|
+
scope.getBuffer(),
|
|
895
931
|
safeValue,
|
|
896
|
-
]
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
return template
|
|
902
|
-
|
|
903
|
-
|
|
932
|
+
].concat(
|
|
933
|
+
globalHelpers
|
|
934
|
+
.filter((name) => isFunction(scope[name]))
|
|
935
|
+
.map((name) => scope[name].bind(scope))
|
|
936
|
+
);
|
|
937
|
+
return template
|
|
938
|
+
.get(path)
|
|
939
|
+
.then((callback) => callback.apply(scope, params))
|
|
904
940
|
};
|
|
941
|
+
|
|
905
942
|
const require = (name) => {
|
|
906
943
|
const filepath = ext(name, config.extension);
|
|
907
944
|
const scope = context.create({});
|
|
908
|
-
return output(filepath, scope).then(() =>
|
|
909
|
-
return scope.getMacro()
|
|
910
|
-
})
|
|
945
|
+
return output(filepath, scope).then(() => scope.getMacro())
|
|
911
946
|
};
|
|
912
947
|
const render = (name, data) => {
|
|
913
948
|
const filepath = ext(name, config.extension);
|
|
@@ -957,7 +992,7 @@ function readFile(path, template) {
|
|
|
957
992
|
return new Promise((resolve, reject) => {
|
|
958
993
|
fs.readFile(joinPath(path, template), (error, data) => {
|
|
959
994
|
if (error) {
|
|
960
|
-
reject(error);
|
|
995
|
+
reject(new TemplateError(error));
|
|
961
996
|
} else {
|
|
962
997
|
resolve(data.toString());
|
|
963
998
|
}
|