@kosatyi/ejs 0.0.107 → 0.0.108
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 +4 -7
- package/bin/bundler.js +21 -9
- package/dist/cjs/browser.js +532 -651
- package/dist/cjs/bundler.js +105 -66
- package/dist/cjs/element.js +28 -63
- package/dist/cjs/index.js +540 -668
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/worker.js +553 -976
- package/dist/esm/browser.js +511 -540
- package/dist/esm/bundler.js +104 -66
- package/dist/esm/element.js +13 -47
- package/dist/esm/index.js +514 -555
- package/dist/esm/worker.js +519 -565
- package/dist/kosatyi-ejs-0.0.107.tgz +0 -0
- package/dist/umd/browser.js +533 -652
- package/dist/umd/browser.js.map +7 -0
- package/dist/umd/browser.min.js +1 -1
- package/dist/umd/browser.min.js.map +7 -0
- package/dist/umd/element.js +28 -63
- package/dist/umd/element.min.js +1 -1
- package/dist/umd/index.js +541 -669
- package/dist/umd/index.min.js +1 -1
- package/dist/umd/worker.js +819 -1242
- package/dist/umd/worker.min.js +1 -3
- package/package.json +80 -71
- package/types/browser.d.ts +10 -0
- package/types/bundler.d.ts +11 -12
- package/types/context.d.ts +96 -0
- package/types/ejs.d.ts +111 -73
- package/types/element.d.ts +9 -0
- package/types/error.d.ts +14 -0
- package/types/global.d.ts +6 -6
- package/types/index.d.ts +16 -0
- package/types/worker.d.ts +31 -0
package/dist/cjs/index.js
CHANGED
|
@@ -1,75 +1,110 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var fs = require('node:fs');
|
|
4
3
|
var path = require('node:path');
|
|
4
|
+
var fs = require('node:fs/promises');
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @type {EjsConfig}
|
|
8
|
+
*/
|
|
9
|
+
const ejsDefaults = {
|
|
10
|
+
precompiled: 'ejsPrecompiled',
|
|
11
|
+
cache: true,
|
|
12
|
+
path: 'views',
|
|
13
|
+
extension: 'ejs',
|
|
14
|
+
rmWhitespace: true,
|
|
15
|
+
strict: true,
|
|
16
|
+
resolver: (path, template) => {
|
|
17
|
+
return Promise.resolve(['resolver is not defined', path, template].join(' '));
|
|
18
|
+
},
|
|
19
|
+
globals: [],
|
|
20
|
+
vars: {
|
|
21
|
+
SCOPE: 'ejs',
|
|
22
|
+
COMPONENT: 'ui',
|
|
23
|
+
ELEMENT: 'el',
|
|
24
|
+
EXTEND: '$$e',
|
|
25
|
+
BUFFER: '$$a',
|
|
26
|
+
LAYOUT: '$$l',
|
|
27
|
+
BLOCKS: '$$b',
|
|
28
|
+
MACRO: '$$m',
|
|
29
|
+
SAFE: '$$v'
|
|
30
|
+
},
|
|
31
|
+
token: {
|
|
32
|
+
start: '<%',
|
|
33
|
+
end: '%>',
|
|
34
|
+
regex: '([\\s\\S]+?)'
|
|
35
|
+
}
|
|
19
36
|
};
|
|
20
|
-
|
|
21
|
-
|
|
37
|
+
|
|
38
|
+
const jsVariableName = /^[a-zA-Z_$][0-9a-zA-Z_$]*$/;
|
|
39
|
+
const typeProp = function () {
|
|
40
|
+
const args = [].slice.call(arguments);
|
|
41
|
+
const callback = args.shift();
|
|
42
|
+
return args.filter(callback).pop();
|
|
22
43
|
};
|
|
23
|
-
|
|
24
|
-
|
|
44
|
+
const isArray = value => Array.isArray(value);
|
|
45
|
+
const isFunction = value => typeof value === 'function';
|
|
46
|
+
const isString = value => typeof value === 'string';
|
|
47
|
+
const isBoolean = value => typeof value === 'boolean';
|
|
48
|
+
const isArrayOfVariables = value => {
|
|
49
|
+
if (!isArray(value)) return false;
|
|
50
|
+
return value.filter(name => {
|
|
51
|
+
const valid = jsVariableName.test(name);
|
|
52
|
+
if (valid === false) console.log(`ejsConfig.globals: expected '${name}' to be valid variable name --> skipped`);
|
|
53
|
+
return valid;
|
|
54
|
+
});
|
|
25
55
|
};
|
|
26
56
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
57
|
+
const configSchema = (config, options) => {
|
|
58
|
+
return Object.assign(config, {
|
|
59
|
+
path: typeProp(isString, ejsDefaults.path, config.path, options.path),
|
|
60
|
+
precompiled: typeProp(isString, ejsDefaults.precompiled, config.export, options.export),
|
|
61
|
+
resolver: typeProp(isFunction, ejsDefaults.resolver, config.resolver, options.resolver),
|
|
62
|
+
extension: typeProp(isString, ejsDefaults.extension, config.extension, options.extension),
|
|
63
|
+
strict: typeProp(isBoolean, ejsDefaults.strict, config.strict, options.strict),
|
|
64
|
+
rmWhitespace: typeProp(isBoolean, ejsDefaults.rmWhitespace, config.rmWhitespace, options.rmWhitespace),
|
|
65
|
+
cache: typeProp(isBoolean, ejsDefaults.cache, config.cache, options.cache),
|
|
66
|
+
globals: typeProp(isArray, ejsDefaults.globals, config.globals, isArrayOfVariables(options.globals)),
|
|
67
|
+
token: Object.assign({}, ejsDefaults.token, config.token, options.token),
|
|
68
|
+
vars: Object.assign({}, ejsDefaults.vars, config.vars, options.vars)
|
|
69
|
+
});
|
|
30
70
|
};
|
|
31
|
-
|
|
71
|
+
|
|
72
|
+
const symbolEntities = {
|
|
32
73
|
"'": "'",
|
|
33
74
|
'\\': '\\',
|
|
34
75
|
'\r': 'r',
|
|
35
76
|
'\n': 'n',
|
|
36
77
|
'\t': 't',
|
|
37
|
-
|
|
38
|
-
|
|
78
|
+
'\u2028': 'u2028',
|
|
79
|
+
'\u2029': 'u2029'
|
|
39
80
|
};
|
|
40
|
-
|
|
81
|
+
const htmlEntities = {
|
|
41
82
|
'&': '&',
|
|
42
83
|
'<': '<',
|
|
43
84
|
'>': '>',
|
|
44
85
|
'"': '"',
|
|
45
86
|
"'": '''
|
|
46
87
|
};
|
|
47
|
-
|
|
48
|
-
|
|
88
|
+
const regexKeys = obj => new RegExp(['[', Object.keys(obj).join(''), ']'].join(''), 'g');
|
|
89
|
+
const htmlEntitiesMatch = regexKeys(htmlEntities);
|
|
90
|
+
const symbolEntitiesMatch = regexKeys(symbolEntities);
|
|
91
|
+
const entities = function () {
|
|
92
|
+
let string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
93
|
+
return ('' + string).replace(htmlEntitiesMatch, match => htmlEntities[match]);
|
|
49
94
|
};
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
var entities = function entities() {
|
|
53
|
-
var string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
54
|
-
return ('' + string).replace(htmlEntitiesMatch, function (match) {
|
|
55
|
-
return htmlEntities[match];
|
|
56
|
-
});
|
|
57
|
-
};
|
|
58
|
-
var symbols = function symbols(string) {
|
|
59
|
-
return ('' + string).replace(symbolEntitiesMatch, function (match) {
|
|
60
|
-
return '\\' + symbolEntities[match];
|
|
61
|
-
});
|
|
95
|
+
const symbols = string => {
|
|
96
|
+
return ('' + string).replace(symbolEntitiesMatch, match => '\\' + symbolEntities[match]);
|
|
62
97
|
};
|
|
63
|
-
|
|
64
|
-
|
|
98
|
+
const safeValue = (value, escape) => {
|
|
99
|
+
const check = value;
|
|
65
100
|
return check == null ? '' : Boolean(escape) === true ? entities(check) : check;
|
|
66
101
|
};
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
for (
|
|
72
|
-
|
|
102
|
+
const getPath = (context, name, strict) => {
|
|
103
|
+
let data = context;
|
|
104
|
+
let chunks = String(name).split('.');
|
|
105
|
+
let prop = chunks.pop();
|
|
106
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
107
|
+
const part = chunks[i];
|
|
73
108
|
if (isFunction(data['toJSON'])) {
|
|
74
109
|
data = data.toJSON();
|
|
75
110
|
}
|
|
@@ -84,344 +119,242 @@ var getPath = function getPath(context, name, strict) {
|
|
|
84
119
|
}
|
|
85
120
|
return [data, prop];
|
|
86
121
|
};
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (ext !== defaults) {
|
|
90
|
-
path = [path, defaults].join('.');
|
|
91
|
-
}
|
|
92
|
-
return path;
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* @type {<T extends {}, U, V, W,Y>(T,U,V,W,Y)=> T & U & V & W & Y}
|
|
97
|
-
*/
|
|
98
|
-
var extend = function extend(target) {
|
|
99
|
-
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
100
|
-
args[_key - 1] = arguments[_key];
|
|
101
|
-
}
|
|
102
|
-
return args.filter(function (source) {
|
|
103
|
-
return source;
|
|
104
|
-
}).reduce(function (target, source) {
|
|
105
|
-
return Object.assign(target, source);
|
|
106
|
-
}, target);
|
|
107
|
-
};
|
|
108
|
-
var noop = function noop() {};
|
|
109
|
-
var each = function each(object, callback) {
|
|
110
|
-
var prop;
|
|
122
|
+
const each = (object, callback) => {
|
|
123
|
+
let prop;
|
|
111
124
|
for (prop in object) {
|
|
112
125
|
if (hasProp(object, prop)) {
|
|
113
126
|
callback(object[prop], prop, object);
|
|
114
127
|
}
|
|
115
128
|
}
|
|
116
129
|
};
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
});
|
|
125
|
-
return result;
|
|
126
|
-
};
|
|
127
|
-
var filter = function filter(object, callback, context) {
|
|
128
|
-
var isArray = object instanceof Array;
|
|
129
|
-
var result = isArray ? [] : {};
|
|
130
|
-
each(object, function (value, key, object) {
|
|
131
|
-
var item = callback(value, key, object);
|
|
132
|
-
if (isUndefined(item) === false) {
|
|
133
|
-
if (isArray) {
|
|
134
|
-
result.push(item);
|
|
135
|
-
} else {
|
|
136
|
-
result[key] = item;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
});
|
|
130
|
+
const omit = (object, list) => {
|
|
131
|
+
const result = {
|
|
132
|
+
...object
|
|
133
|
+
};
|
|
134
|
+
for (const key of list) {
|
|
135
|
+
delete result[key];
|
|
136
|
+
}
|
|
140
137
|
return result;
|
|
141
138
|
};
|
|
142
|
-
|
|
143
|
-
return
|
|
144
|
-
if (list.indexOf(key) === -1) {
|
|
145
|
-
return value;
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
*
|
|
152
|
-
* @param object
|
|
153
|
-
* @param prop
|
|
154
|
-
* @return {boolean}
|
|
155
|
-
*/
|
|
156
|
-
var hasProp = function hasProp(object, prop) {
|
|
157
|
-
return object && object.hasOwnProperty(prop);
|
|
139
|
+
const hasProp = (object, prop) => {
|
|
140
|
+
return object && Object.hasOwn(object, prop);
|
|
158
141
|
};
|
|
159
|
-
|
|
142
|
+
const joinPath = (path, template) => {
|
|
160
143
|
template = [path, template].join('/');
|
|
161
144
|
template = template.replace(/\/\//g, '/');
|
|
162
145
|
return template;
|
|
163
146
|
};
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
return match;
|
|
173
|
-
});
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
var defaults = {};
|
|
177
|
-
defaults["export"] = 'ejsPrecompiled';
|
|
178
|
-
defaults.cache = true;
|
|
179
|
-
defaults.chokidar = null;
|
|
180
|
-
defaults.path = 'views';
|
|
181
|
-
defaults.resolver = function (path, template) {
|
|
182
|
-
return Promise.resolve(['resolver is not defined', path, template].join(' '));
|
|
183
|
-
};
|
|
184
|
-
defaults.extension = 'ejs';
|
|
185
|
-
defaults.rmWhitespace = true;
|
|
186
|
-
defaults.withObject = true;
|
|
187
|
-
defaults.globalHelpers = [];
|
|
188
|
-
defaults.vars = {
|
|
189
|
-
SCOPE: 'ejs',
|
|
190
|
-
COMPONENT: 'ui',
|
|
191
|
-
ELEMENT: 'el',
|
|
192
|
-
EXTEND: '$$e',
|
|
193
|
-
BUFFER: '$$a',
|
|
194
|
-
LAYOUT: '$$l',
|
|
195
|
-
BLOCKS: '$$b',
|
|
196
|
-
MACRO: '$$m',
|
|
197
|
-
SAFE: '$$v'
|
|
198
|
-
};
|
|
199
|
-
defaults.token = {
|
|
200
|
-
start: '<%',
|
|
201
|
-
end: '%>',
|
|
202
|
-
regex: '([\\s\\S]+?)'
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
var configSchema = function configSchema(config, options) {
|
|
206
|
-
return extend(config, {
|
|
207
|
-
path: typeProp(isString, defaults.path, config.path, options.path),
|
|
208
|
-
"export": typeProp(isString, defaults["export"], config["export"], options["export"]),
|
|
209
|
-
resolver: typeProp(isFunction, defaults.resolver, config.resolver, options.resolver),
|
|
210
|
-
extension: typeProp(isString, defaults.extension, config.extension, options.extension),
|
|
211
|
-
withObject: typeProp(isBoolean, defaults.withObject, config.withObject, options.withObject),
|
|
212
|
-
rmWhitespace: typeProp(isBoolean, defaults.rmWhitespace, config.rmWhitespace, options.rmWhitespace),
|
|
213
|
-
cache: typeProp(isBoolean, defaults.cache, config.cache, options.cache),
|
|
214
|
-
token: extend({}, defaults.token, config.token, options.token),
|
|
215
|
-
vars: extend({}, defaults.vars, config.vars, options.vars),
|
|
216
|
-
globalHelpers: typeProp(isArray, defaults.globalHelpers, config.globalHelpers, options.globalHelpers)
|
|
217
|
-
});
|
|
147
|
+
const bindContext = function (object) {
|
|
148
|
+
let methods = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
149
|
+
for (let i = 0, len = methods.length; i < len; i++) {
|
|
150
|
+
const name = methods[i];
|
|
151
|
+
if (name in object) {
|
|
152
|
+
object[name] = object[name].bind(object);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
218
155
|
};
|
|
219
156
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
return compiler.compile(content, template);
|
|
157
|
+
class Template {
|
|
158
|
+
#path;
|
|
159
|
+
#resolver;
|
|
160
|
+
#cache;
|
|
161
|
+
#compiler;
|
|
162
|
+
static exports = ['configure', 'get', 'compile'];
|
|
163
|
+
constructor(options, cache, compiler) {
|
|
164
|
+
bindContext(this, this.constructor.exports);
|
|
165
|
+
this.#cache = cache;
|
|
166
|
+
this.#compiler = compiler;
|
|
167
|
+
this.configure(options ?? {});
|
|
168
|
+
}
|
|
169
|
+
configure(options) {
|
|
170
|
+
this.#path = options.path;
|
|
171
|
+
if (isFunction(options.resolver)) {
|
|
172
|
+
this.#resolver = options.resolver;
|
|
237
173
|
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
174
|
+
}
|
|
175
|
+
#resolve(template) {
|
|
176
|
+
const cached = this.#cache.get(template);
|
|
177
|
+
if (cached instanceof Promise) return cached;
|
|
178
|
+
const result = Promise.resolve(this.#resolver(this.#path, template));
|
|
179
|
+
this.#cache.set(template, result);
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
compile(content, template) {
|
|
183
|
+
const cached = this.#cache.get(template);
|
|
184
|
+
if (typeof cached === 'function') return cached;
|
|
185
|
+
if (typeof content === 'string') {
|
|
186
|
+
content = this.#compiler.compile(content, template);
|
|
242
187
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
};
|
|
247
|
-
var configure = function configure(options) {
|
|
248
|
-
config.path = options.path;
|
|
249
|
-
if (isFunction(options.resolver)) {
|
|
250
|
-
config.resolver = options.resolver;
|
|
188
|
+
if (typeof content === 'function') {
|
|
189
|
+
this.#cache.set(template, content);
|
|
190
|
+
return content;
|
|
251
191
|
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
compile: compile
|
|
258
|
-
};
|
|
259
|
-
};
|
|
192
|
+
}
|
|
193
|
+
get(template) {
|
|
194
|
+
return this.#resolve(template).then(content => this.compile(content, template));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
260
197
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
config.
|
|
286
|
-
config.
|
|
287
|
-
config.
|
|
288
|
-
config.vars = options.vars;
|
|
289
|
-
config.globalHelpers = options.globalHelpers;
|
|
290
|
-
config.matches = [];
|
|
291
|
-
config.formats = [];
|
|
292
|
-
config.slurp = {
|
|
198
|
+
const tokenList = [['-', (v, b, s) => `')\n${b}(${s}(${v},1))\n${b}('`], ['=', (v, b, s) => `')\n${b}(${s}(${v}))\n${b}('`], ['#', (v, b) => `')\n/**${v}**/\n${b}('`], ['', (v, b) => `')\n${v}\n${b}('`]];
|
|
199
|
+
const tokensMatch = (regex, content, callback) => {
|
|
200
|
+
let index = 0;
|
|
201
|
+
content.replace(regex, function () {
|
|
202
|
+
const params = [].slice.call(arguments, 0, -1);
|
|
203
|
+
const offset = params.pop();
|
|
204
|
+
const match = params.shift();
|
|
205
|
+
callback(params, index, offset);
|
|
206
|
+
index = offset + match.length;
|
|
207
|
+
return match;
|
|
208
|
+
});
|
|
209
|
+
};
|
|
210
|
+
class Compiler {
|
|
211
|
+
#config = {};
|
|
212
|
+
static exports = ['compile'];
|
|
213
|
+
constructor(options) {
|
|
214
|
+
bindContext(this, this.constructor.exports);
|
|
215
|
+
this.configure(options);
|
|
216
|
+
}
|
|
217
|
+
configure(options) {
|
|
218
|
+
this.#config.strict = options.strict;
|
|
219
|
+
this.#config.rmWhitespace = options.rmWhitespace;
|
|
220
|
+
this.#config.token = options.token;
|
|
221
|
+
this.#config.vars = options.vars;
|
|
222
|
+
this.#config.globals = options.globals;
|
|
223
|
+
this.#config.legacy = options.legacy ?? true;
|
|
224
|
+
this.#config.slurp = {
|
|
293
225
|
match: '[s\t\n]*',
|
|
294
|
-
start: [config.token.start, '_'],
|
|
295
|
-
end: ['_', config.token.end]
|
|
226
|
+
start: [this.#config.token.start, '_'],
|
|
227
|
+
end: ['_', this.#config.token.end]
|
|
296
228
|
};
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
config.
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
229
|
+
this.#config.matches = [];
|
|
230
|
+
this.#config.formats = [];
|
|
231
|
+
for (const [symbol, format] of tokenList) {
|
|
232
|
+
this.#config.matches.push(this.#config.token.start.concat(symbol).concat(this.#config.token.regex).concat(this.#config.token.end));
|
|
233
|
+
this.#config.formats.push(format);
|
|
234
|
+
}
|
|
235
|
+
this.#config.regex = new RegExp(this.#config.matches.join('|').concat('|$'), 'g');
|
|
236
|
+
this.#config.slurpStart = new RegExp([this.#config.slurp.match, this.#config.slurp.start.join('')].join(''), 'gm');
|
|
237
|
+
this.#config.slurpEnd = new RegExp([this.#config.slurp.end.join(''), this.#config.slurp.match].join(''), 'gm');
|
|
238
|
+
if (this.#config.globals.length) {
|
|
239
|
+
if (this.#config.legacy) {
|
|
240
|
+
this.#config.globalVariables = `const ${this.#config.globals.map(name => `${name}=${this.#config.vars.SCOPE}.${name}`).join(',')};`;
|
|
241
|
+
} else {
|
|
242
|
+
this.#config.globalVariables = `const {${this.#config.globals.join(',')}} = ${this.#config.vars.SCOPE};`;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
compile(content, path) {
|
|
247
|
+
const GLOBALS = this.#config.globalVariables;
|
|
248
|
+
const {
|
|
249
|
+
SCOPE,
|
|
250
|
+
SAFE,
|
|
251
|
+
BUFFER,
|
|
252
|
+
COMPONENT,
|
|
253
|
+
ELEMENT
|
|
254
|
+
} = this.#config.vars;
|
|
255
|
+
if (this.#config.rmWhitespace) {
|
|
314
256
|
content = String(content).replace(/[\r\n]+/g, '\n').replace(/^\s+|\s+$/gm, '');
|
|
315
257
|
}
|
|
316
|
-
content = String(content).replace(config.slurpStart, config.token.start).replace(config.slurpEnd, config.token.end);
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
params.forEach(
|
|
258
|
+
content = String(content).replace(this.#config.slurpStart, this.#config.token.start).replace(this.#config.slurpEnd, this.#config.token.end);
|
|
259
|
+
let OUTPUT = `${BUFFER}('`;
|
|
260
|
+
tokensMatch(this.#config.regex, content, (params, index, offset) => {
|
|
261
|
+
OUTPUT += symbols(content.slice(index, offset));
|
|
262
|
+
params.forEach((value, index) => {
|
|
321
263
|
if (value) {
|
|
322
|
-
|
|
264
|
+
OUTPUT += this.#config.formats[index](value.trim(), BUFFER, SAFE);
|
|
323
265
|
}
|
|
324
266
|
});
|
|
325
267
|
});
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
if (config.
|
|
329
|
-
|
|
268
|
+
OUTPUT += `');`;
|
|
269
|
+
OUTPUT = `try{${OUTPUT}}catch(e){return ${BUFFER}.error(e,'${path}')}`;
|
|
270
|
+
if (this.#config.strict === false) {
|
|
271
|
+
OUTPUT = `with(${SCOPE}){${OUTPUT}}`;
|
|
272
|
+
}
|
|
273
|
+
OUTPUT = `${BUFFER}.start();${OUTPUT}return ${BUFFER}.end();`;
|
|
274
|
+
OUTPUT += `\n//# sourceURL=${path}`;
|
|
275
|
+
if (GLOBALS) {
|
|
276
|
+
OUTPUT = `${GLOBALS}\n${OUTPUT}`;
|
|
330
277
|
}
|
|
331
|
-
source = "".concat(BUFFER, ".start();").concat(source, "return ").concat(BUFFER, ".end();");
|
|
332
|
-
source += "\n//# sourceURL=".concat(path);
|
|
333
|
-
var result = null;
|
|
334
|
-
var params = [SCOPE, COMPONENT, ELEMENT, BUFFER, SAFE].concat(GLOBALS);
|
|
335
278
|
try {
|
|
336
|
-
|
|
337
|
-
result
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
279
|
+
const params = [SCOPE, COMPONENT, ELEMENT, BUFFER, SAFE];
|
|
280
|
+
const result = Function.apply(null, params.concat(OUTPUT));
|
|
281
|
+
result.source = `(function(${params.join(',')}){\n${OUTPUT}\n});`;
|
|
282
|
+
return result;
|
|
283
|
+
} catch (error) {
|
|
284
|
+
error.filename = path;
|
|
285
|
+
error.source = OUTPUT;
|
|
286
|
+
throw error;
|
|
342
287
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
configure(options);
|
|
346
|
-
return {
|
|
347
|
-
configure: configure,
|
|
348
|
-
compile: compile
|
|
349
|
-
};
|
|
350
|
-
};
|
|
288
|
+
}
|
|
289
|
+
}
|
|
351
290
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
291
|
+
class Cache {
|
|
292
|
+
static exports = ['load', 'set', 'get', 'exist', 'clear', 'remove', 'resolve'];
|
|
293
|
+
#cache = true;
|
|
294
|
+
#precompiled;
|
|
295
|
+
#list = {};
|
|
296
|
+
constructor(options) {
|
|
297
|
+
bindContext(this, this.constructor.exports);
|
|
298
|
+
this.configure(options);
|
|
299
|
+
}
|
|
300
|
+
get(key) {
|
|
301
|
+
if (this.#cache) {
|
|
302
|
+
return this.#list[key];
|
|
360
303
|
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
if (
|
|
364
|
-
|
|
304
|
+
}
|
|
305
|
+
set(key, value) {
|
|
306
|
+
if (this.#cache) {
|
|
307
|
+
this.#list[key] = value;
|
|
365
308
|
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
if (
|
|
369
|
-
list
|
|
309
|
+
}
|
|
310
|
+
exist(key) {
|
|
311
|
+
if (this.#cache) {
|
|
312
|
+
return this.#list.hasOwnProperty(key);
|
|
370
313
|
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
314
|
+
}
|
|
315
|
+
clear() {
|
|
316
|
+
Object.keys(this.#list).forEach(this.remove);
|
|
317
|
+
}
|
|
318
|
+
remove(key) {
|
|
319
|
+
delete this.#list[key];
|
|
320
|
+
}
|
|
321
|
+
resolve(key) {
|
|
322
|
+
return Promise.resolve(this.get(key));
|
|
323
|
+
}
|
|
324
|
+
load(data) {
|
|
325
|
+
if (this.#cache) {
|
|
326
|
+
Object.assign(this.#list, data || {});
|
|
375
327
|
}
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
};
|
|
383
|
-
var resolve = function resolve(key) {
|
|
384
|
-
return Promise.resolve(get(key));
|
|
385
|
-
};
|
|
386
|
-
var configure = function configure() {
|
|
387
|
-
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
388
|
-
config.enabled = options.cache;
|
|
389
|
-
config["export"] = options["export"];
|
|
390
|
-
if (isNode() === false) {
|
|
391
|
-
load(global[config["export"]]);
|
|
328
|
+
}
|
|
329
|
+
configure(options) {
|
|
330
|
+
this.#cache = options.cache;
|
|
331
|
+
this.#precompiled = options.precompiled;
|
|
332
|
+
if (typeof window === 'object') {
|
|
333
|
+
this.load(window[this.#precompiled]);
|
|
392
334
|
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
return {
|
|
396
|
-
configure: configure,
|
|
397
|
-
load: load,
|
|
398
|
-
set: set,
|
|
399
|
-
get: get,
|
|
400
|
-
exist: exist,
|
|
401
|
-
clear: clear,
|
|
402
|
-
remove: remove,
|
|
403
|
-
resolve: resolve
|
|
404
|
-
};
|
|
405
|
-
};
|
|
335
|
+
}
|
|
336
|
+
}
|
|
406
337
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
338
|
+
const selfClosed = ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'];
|
|
339
|
+
const space = ' ';
|
|
340
|
+
const quote = '"';
|
|
341
|
+
const equal = '=';
|
|
342
|
+
const slash = '/';
|
|
343
|
+
const lt = '<';
|
|
344
|
+
const gt = '>';
|
|
345
|
+
const eachAttribute = _ref => {
|
|
346
|
+
let [key, value] = _ref;
|
|
347
|
+
if (value !== null && value !== undefined) {
|
|
348
|
+
return [entities(key), [quote, entities(value), quote].join('')].join(equal);
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
const element = (tag, attrs, content) => {
|
|
352
|
+
const result = [];
|
|
353
|
+
const hasClosedTag = selfClosed.indexOf(tag) === -1;
|
|
354
|
+
const attributes = Object.entries(attrs ?? {}).map(eachAttribute).filter(e => e).join(space);
|
|
422
355
|
result.push([lt, tag, space, attributes, gt].join(''));
|
|
423
356
|
if (content && hasClosedTag) {
|
|
424
|
-
result.push(content
|
|
357
|
+
result.push(Array.isArray(content) ? content.join('') : content);
|
|
425
358
|
}
|
|
426
359
|
if (hasClosedTag) {
|
|
427
360
|
result.push([lt, slash, tag, gt].join(''));
|
|
@@ -429,237 +362,204 @@ var element = function element(tag, attrs, content) {
|
|
|
429
362
|
return result.join('');
|
|
430
363
|
};
|
|
431
364
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
code: 0,
|
|
442
|
-
getCode: function getCode() {
|
|
443
|
-
return this.code;
|
|
444
|
-
},
|
|
445
|
-
getMessage: function getMessage() {
|
|
446
|
-
return this.message;
|
|
447
|
-
},
|
|
448
|
-
toString: function toString() {
|
|
449
|
-
return this.getMessage();
|
|
365
|
+
class TemplateError extends Error {
|
|
366
|
+
name = 'TemplateError';
|
|
367
|
+
constructor(error) {
|
|
368
|
+
super(error);
|
|
369
|
+
if (error instanceof Error) {
|
|
370
|
+
this.stack = error.stack;
|
|
371
|
+
this.filename = error.filename;
|
|
372
|
+
this.lineno = error.lineno;
|
|
373
|
+
}
|
|
450
374
|
}
|
|
451
|
-
});
|
|
452
|
-
|
|
453
|
-
/**
|
|
454
|
-
*
|
|
455
|
-
* @constructor
|
|
456
|
-
*/
|
|
457
|
-
function TemplateNotFound() {
|
|
458
|
-
TemplateError.call(this);
|
|
459
|
-
}
|
|
460
|
-
Object.setPrototypeOf(TemplateNotFound.prototype, TemplateError.prototype);
|
|
461
|
-
Object.assign(TemplateNotFound.prototype, {
|
|
462
|
-
code: 404
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
/**
|
|
466
|
-
*
|
|
467
|
-
* @constructor
|
|
468
|
-
*/
|
|
469
|
-
function TemplateSyntaxError() {
|
|
470
|
-
TemplateError.call(this);
|
|
471
375
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
code
|
|
475
|
-
});
|
|
476
|
-
|
|
477
|
-
function resolve(list) {
|
|
478
|
-
return Promise.all(list || []).then(function (list) {
|
|
479
|
-
return list.join('');
|
|
480
|
-
})["catch"](function (e) {
|
|
481
|
-
return e;
|
|
482
|
-
});
|
|
376
|
+
class TemplateNotFound extends TemplateError {
|
|
377
|
+
name = 'TemplateNotFound';
|
|
378
|
+
code = 404;
|
|
483
379
|
}
|
|
484
|
-
|
|
485
|
-
|
|
380
|
+
class TemplateSyntaxError extends TemplateError {
|
|
381
|
+
name = 'TemplateSyntaxError';
|
|
382
|
+
code = 500;
|
|
486
383
|
}
|
|
487
384
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
385
|
+
const resolve = list => {
|
|
386
|
+
return Promise.all(list || []).then(list => list.join('')).catch(e => e);
|
|
387
|
+
};
|
|
388
|
+
const reject = error => {
|
|
389
|
+
return Promise.reject(new TemplateSyntaxError(error));
|
|
390
|
+
};
|
|
391
|
+
const EjsBuffer = () => {
|
|
392
|
+
let store = [];
|
|
393
|
+
let array = [];
|
|
394
|
+
/**
|
|
395
|
+
*
|
|
396
|
+
* @param value
|
|
397
|
+
* @constructor
|
|
398
|
+
*/
|
|
399
|
+
const EjsBuffer = value => {
|
|
496
400
|
array.push(value);
|
|
497
401
|
};
|
|
498
|
-
|
|
402
|
+
EjsBuffer.start = () => {
|
|
499
403
|
array = [];
|
|
500
404
|
};
|
|
501
|
-
|
|
405
|
+
EjsBuffer.backup = () => {
|
|
502
406
|
store.push(array.concat());
|
|
503
407
|
array = [];
|
|
504
408
|
};
|
|
505
|
-
|
|
506
|
-
|
|
409
|
+
EjsBuffer.restore = () => {
|
|
410
|
+
const result = array.concat();
|
|
507
411
|
array = store.pop();
|
|
508
412
|
return resolve(result);
|
|
509
413
|
};
|
|
510
|
-
|
|
414
|
+
EjsBuffer.error = (e, filename) => {
|
|
511
415
|
return reject(e);
|
|
512
416
|
};
|
|
513
|
-
|
|
417
|
+
EjsBuffer.end = () => {
|
|
514
418
|
return resolve(array);
|
|
515
419
|
};
|
|
516
|
-
return
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
var PARENT = Symbol('ContextScope.parentTemplate');
|
|
520
|
-
var createContextScope = function createContextScope(config, methods) {
|
|
521
|
-
var _config$vars = config.vars,
|
|
522
|
-
BLOCKS = _config$vars.BLOCKS,
|
|
523
|
-
MACRO = _config$vars.MACRO,
|
|
524
|
-
EXTEND = _config$vars.EXTEND,
|
|
525
|
-
LAYOUT = _config$vars.LAYOUT,
|
|
526
|
-
BUFFER = _config$vars.BUFFER,
|
|
527
|
-
SAFE = _config$vars.SAFE,
|
|
528
|
-
SCOPE = _config$vars.SCOPE,
|
|
529
|
-
COMPONENT = _config$vars.COMPONENT,
|
|
530
|
-
ELEMENT = _config$vars.ELEMENT;
|
|
531
|
-
/**
|
|
532
|
-
*
|
|
533
|
-
* @type {symbol}
|
|
534
|
-
*/
|
|
420
|
+
return EjsBuffer;
|
|
421
|
+
};
|
|
535
422
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
423
|
+
const PARENT = Symbol('EjsContext.parentTemplate');
|
|
424
|
+
const createContext$1 = (config, methods) => {
|
|
425
|
+
const {
|
|
426
|
+
BLOCKS,
|
|
427
|
+
MACRO,
|
|
428
|
+
EXTEND,
|
|
429
|
+
LAYOUT,
|
|
430
|
+
BUFFER,
|
|
431
|
+
SAFE,
|
|
432
|
+
SCOPE,
|
|
433
|
+
COMPONENT,
|
|
434
|
+
ELEMENT
|
|
435
|
+
} = config.vars;
|
|
436
|
+
const globals = config.globals || [];
|
|
437
|
+
function EjsContext(data) {
|
|
542
438
|
this[PARENT] = null;
|
|
543
439
|
this[BLOCKS] = {};
|
|
544
440
|
this[MACRO] = {};
|
|
545
441
|
Object.assign(this, omit(data, [SCOPE, BUFFER, SAFE, COMPONENT, ELEMENT]));
|
|
546
442
|
}
|
|
547
|
-
Object.
|
|
548
|
-
|
|
549
|
-
value
|
|
443
|
+
Object.entries(methods).forEach(_ref => {
|
|
444
|
+
let [name, value] = _ref;
|
|
445
|
+
if (isFunction(value) && globals.includes(name)) {
|
|
446
|
+
value = value.bind(EjsContext.prototype);
|
|
447
|
+
}
|
|
448
|
+
EjsContext.prototype[name] = value;
|
|
449
|
+
});
|
|
450
|
+
Object.defineProperty(EjsContext.prototype, BUFFER, {
|
|
451
|
+
value: EjsBuffer()
|
|
550
452
|
});
|
|
551
|
-
Object.defineProperty(
|
|
453
|
+
Object.defineProperty(EjsContext.prototype, BLOCKS, {
|
|
552
454
|
value: {},
|
|
553
455
|
writable: true
|
|
554
456
|
});
|
|
555
|
-
Object.defineProperty(
|
|
457
|
+
Object.defineProperty(EjsContext.prototype, MACRO, {
|
|
556
458
|
value: {},
|
|
557
459
|
writable: true
|
|
558
460
|
});
|
|
559
|
-
Object.defineProperty(
|
|
461
|
+
Object.defineProperty(EjsContext.prototype, LAYOUT, {
|
|
560
462
|
value: false,
|
|
561
463
|
writable: true
|
|
562
464
|
});
|
|
563
|
-
Object.defineProperty(
|
|
465
|
+
Object.defineProperty(EjsContext.prototype, EXTEND, {
|
|
564
466
|
value: false,
|
|
565
467
|
writable: true
|
|
566
468
|
});
|
|
567
|
-
Object.defineProperty(
|
|
469
|
+
Object.defineProperty(EjsContext.prototype, PARENT, {
|
|
568
470
|
value: null,
|
|
569
471
|
writable: true
|
|
570
472
|
});
|
|
571
|
-
Object.defineProperties(
|
|
473
|
+
Object.defineProperties(EjsContext.prototype, {
|
|
572
474
|
/** @type {function} */
|
|
573
475
|
setParentTemplate: {
|
|
574
|
-
value
|
|
575
|
-
this[PARENT] =
|
|
476
|
+
value(value) {
|
|
477
|
+
this[PARENT] = value;
|
|
576
478
|
return this;
|
|
577
479
|
}
|
|
578
480
|
},
|
|
579
481
|
/** @type {function} */
|
|
580
482
|
getParentTemplate: {
|
|
581
|
-
value
|
|
483
|
+
value() {
|
|
582
484
|
return this[PARENT];
|
|
583
485
|
}
|
|
584
486
|
},
|
|
585
487
|
/** @type {function} */
|
|
586
488
|
useSafeValue: {
|
|
587
|
-
get:
|
|
588
|
-
return safeValue;
|
|
589
|
-
}
|
|
489
|
+
get: () => safeValue
|
|
590
490
|
},
|
|
591
491
|
/** @type {function} */
|
|
592
492
|
useComponent: {
|
|
593
|
-
get
|
|
493
|
+
get() {
|
|
594
494
|
if (isFunction(this[COMPONENT])) {
|
|
595
495
|
return this[COMPONENT].bind(this);
|
|
596
496
|
} else {
|
|
597
|
-
return
|
|
598
|
-
throw new Error(
|
|
497
|
+
return () => {
|
|
498
|
+
throw new Error(`${COMPONENT} must be a function`);
|
|
599
499
|
};
|
|
600
500
|
}
|
|
601
501
|
}
|
|
602
502
|
},
|
|
603
503
|
/** @type {function} */
|
|
604
504
|
useElement: {
|
|
605
|
-
get
|
|
505
|
+
get() {
|
|
606
506
|
if (isFunction(this[ELEMENT])) {
|
|
607
507
|
return this[ELEMENT].bind(this);
|
|
608
508
|
} else {
|
|
609
|
-
return
|
|
610
|
-
throw new Error(
|
|
509
|
+
return () => {
|
|
510
|
+
throw new Error(`${ELEMENT} must be a function`);
|
|
611
511
|
};
|
|
612
512
|
}
|
|
613
513
|
}
|
|
614
514
|
},
|
|
615
|
-
/** @type {
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
return this[
|
|
515
|
+
/** @type {function} */
|
|
516
|
+
useBuffer: {
|
|
517
|
+
get() {
|
|
518
|
+
return this[BUFFER];
|
|
619
519
|
}
|
|
620
520
|
},
|
|
621
521
|
/** @type {function} */
|
|
622
|
-
|
|
623
|
-
value
|
|
624
|
-
return this[
|
|
522
|
+
getMacro: {
|
|
523
|
+
value() {
|
|
524
|
+
return this[MACRO];
|
|
625
525
|
}
|
|
626
526
|
},
|
|
627
527
|
/** @type {function} */
|
|
628
528
|
getBlocks: {
|
|
629
|
-
value
|
|
529
|
+
value() {
|
|
630
530
|
return this[BLOCKS];
|
|
631
531
|
}
|
|
632
532
|
},
|
|
633
533
|
/** @type {function} */
|
|
634
534
|
setExtend: {
|
|
635
|
-
value
|
|
636
|
-
this[EXTEND] =
|
|
535
|
+
value(value) {
|
|
536
|
+
this[EXTEND] = value;
|
|
637
537
|
return this;
|
|
638
538
|
}
|
|
639
539
|
},
|
|
640
540
|
/** @type {function} */
|
|
641
541
|
getExtend: {
|
|
642
|
-
value
|
|
542
|
+
value() {
|
|
643
543
|
return this[EXTEND];
|
|
644
544
|
}
|
|
645
545
|
},
|
|
646
546
|
/** @type {function} */
|
|
647
547
|
setLayout: {
|
|
648
|
-
value
|
|
548
|
+
value(layout) {
|
|
649
549
|
this[LAYOUT] = layout;
|
|
650
550
|
return this;
|
|
651
551
|
}
|
|
652
552
|
},
|
|
653
553
|
/** @type {function} */
|
|
654
554
|
getLayout: {
|
|
655
|
-
value
|
|
555
|
+
value() {
|
|
656
556
|
return this[LAYOUT];
|
|
657
557
|
}
|
|
658
558
|
},
|
|
659
559
|
/** @type {function} */
|
|
660
560
|
clone: {
|
|
661
|
-
value
|
|
662
|
-
|
|
561
|
+
value(exclude_blocks) {
|
|
562
|
+
const filter = [LAYOUT, EXTEND, BUFFER];
|
|
663
563
|
if (exclude_blocks === true) {
|
|
664
564
|
filter.push(BLOCKS);
|
|
665
565
|
}
|
|
@@ -668,39 +568,35 @@ var createContextScope = function createContextScope(config, methods) {
|
|
|
668
568
|
},
|
|
669
569
|
/** @type {function} */
|
|
670
570
|
extend: {
|
|
671
|
-
value
|
|
571
|
+
value(layout) {
|
|
672
572
|
this.setExtend(true);
|
|
673
573
|
this.setLayout(layout);
|
|
674
574
|
}
|
|
675
575
|
},
|
|
676
576
|
/** @type {function} */
|
|
677
577
|
echo: {
|
|
678
|
-
value
|
|
679
|
-
|
|
680
|
-
var params = [].slice.call(arguments);
|
|
681
|
-
params.forEach(buffer);
|
|
578
|
+
value() {
|
|
579
|
+
return [].slice.call(arguments).forEach(this.useBuffer);
|
|
682
580
|
}
|
|
683
581
|
},
|
|
684
582
|
/** @type {function} */
|
|
685
583
|
fn: {
|
|
686
|
-
value
|
|
687
|
-
|
|
688
|
-
var context = this;
|
|
689
|
-
return function () {
|
|
584
|
+
value(callback) {
|
|
585
|
+
return () => {
|
|
690
586
|
if (isFunction(callback)) {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
return
|
|
587
|
+
this.useBuffer.backup();
|
|
588
|
+
this.useBuffer(callback.apply(this, arguments));
|
|
589
|
+
return this.useBuffer.restore();
|
|
694
590
|
}
|
|
695
591
|
};
|
|
696
592
|
}
|
|
697
593
|
},
|
|
698
594
|
/** @type {function} */
|
|
699
595
|
macro: {
|
|
700
|
-
value
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
596
|
+
value(name, callback) {
|
|
597
|
+
const list = this.getMacro();
|
|
598
|
+
const macro = this.fn(callback);
|
|
599
|
+
const context = this;
|
|
704
600
|
list[name] = function () {
|
|
705
601
|
return context.echo(macro.apply(undefined, arguments));
|
|
706
602
|
};
|
|
@@ -708,10 +604,10 @@ var createContextScope = function createContextScope(config, methods) {
|
|
|
708
604
|
},
|
|
709
605
|
/** @type {function} */
|
|
710
606
|
call: {
|
|
711
|
-
value
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
607
|
+
value(name) {
|
|
608
|
+
const list = this.getMacro();
|
|
609
|
+
const macro = list[name];
|
|
610
|
+
const params = [].slice.call(arguments, 1);
|
|
715
611
|
if (isFunction(macro)) {
|
|
716
612
|
return macro.apply(macro, params);
|
|
717
613
|
}
|
|
@@ -719,51 +615,47 @@ var createContextScope = function createContextScope(config, methods) {
|
|
|
719
615
|
},
|
|
720
616
|
/** @type {function} */
|
|
721
617
|
block: {
|
|
722
|
-
value
|
|
723
|
-
|
|
724
|
-
var blocks = this.getBlocks();
|
|
618
|
+
value(name, callback) {
|
|
619
|
+
const blocks = this.getBlocks();
|
|
725
620
|
blocks[name] = blocks[name] || [];
|
|
726
621
|
blocks[name].push(this.fn(callback));
|
|
727
622
|
if (this.getExtend()) return;
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
var _next = function next() {
|
|
733
|
-
var parent = current();
|
|
623
|
+
const list = Object.assign([], blocks[name]);
|
|
624
|
+
const shift = () => list.shift();
|
|
625
|
+
const next = () => {
|
|
626
|
+
const parent = shift();
|
|
734
627
|
if (parent) {
|
|
735
|
-
return
|
|
736
|
-
|
|
628
|
+
return () => {
|
|
629
|
+
this.echo(parent(next()));
|
|
737
630
|
};
|
|
738
631
|
} else {
|
|
739
|
-
return
|
|
632
|
+
return () => {};
|
|
740
633
|
}
|
|
741
634
|
};
|
|
742
|
-
this.echo(
|
|
635
|
+
this.echo(shift()(next()));
|
|
743
636
|
}
|
|
744
637
|
},
|
|
745
638
|
/** @type {function} */
|
|
746
639
|
hasBlock: {
|
|
747
|
-
value
|
|
640
|
+
value(name) {
|
|
748
641
|
return this.getBlocks().hasOwnProperty(name);
|
|
749
642
|
}
|
|
750
643
|
},
|
|
751
644
|
/** @type {function} */
|
|
752
645
|
include: {
|
|
753
|
-
value
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
646
|
+
value(path, data, cx) {
|
|
647
|
+
const context = cx === false ? {} : this.clone(true);
|
|
648
|
+
const params = Object.assign(context, data || {});
|
|
649
|
+
const promise = this.render(path, params);
|
|
757
650
|
this.echo(promise);
|
|
758
651
|
}
|
|
759
652
|
},
|
|
760
653
|
/** @type {function} */
|
|
761
654
|
use: {
|
|
762
|
-
value
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
each(exports, function (macro, name) {
|
|
655
|
+
value(path, namespace) {
|
|
656
|
+
this.echo(Promise.resolve(this.require(path)).then(exports$1 => {
|
|
657
|
+
const list = this.getMacro();
|
|
658
|
+
each(exports$1, (macro, name) => {
|
|
767
659
|
list[[namespace, name].join('.')] = macro;
|
|
768
660
|
});
|
|
769
661
|
}));
|
|
@@ -771,34 +663,34 @@ var createContextScope = function createContextScope(config, methods) {
|
|
|
771
663
|
},
|
|
772
664
|
/** @type {function} */
|
|
773
665
|
async: {
|
|
774
|
-
value
|
|
666
|
+
value(promise, callback) {
|
|
775
667
|
this.echo(Promise.resolve(promise).then(callback));
|
|
776
668
|
}
|
|
777
669
|
},
|
|
778
670
|
/** @type {function} */
|
|
779
671
|
get: {
|
|
780
|
-
value
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
672
|
+
value(name, defaults) {
|
|
673
|
+
const path = getPath(this, name, true);
|
|
674
|
+
const result = path.shift();
|
|
675
|
+
const prop = path.pop();
|
|
784
676
|
return hasProp(result, prop) ? result[prop] : defaults;
|
|
785
677
|
}
|
|
786
678
|
},
|
|
787
679
|
/** @type {function} */
|
|
788
680
|
set: {
|
|
789
|
-
value
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
681
|
+
value(name, value) {
|
|
682
|
+
const path = getPath(this, name, false);
|
|
683
|
+
const result = path.shift();
|
|
684
|
+
const prop = path.pop();
|
|
793
685
|
if (this.getParentTemplate() && hasProp(result, prop)) {
|
|
794
686
|
return result[prop];
|
|
795
687
|
}
|
|
796
|
-
return result[prop] =
|
|
688
|
+
return result[prop] = value;
|
|
797
689
|
}
|
|
798
690
|
},
|
|
799
691
|
/** @type {function} */
|
|
800
692
|
each: {
|
|
801
|
-
value
|
|
693
|
+
value(object, callback) {
|
|
802
694
|
if (isString(object)) {
|
|
803
695
|
object = this.get(object, []);
|
|
804
696
|
}
|
|
@@ -808,143 +700,118 @@ var createContextScope = function createContextScope(config, methods) {
|
|
|
808
700
|
},
|
|
809
701
|
/** @type {function} */
|
|
810
702
|
el: {
|
|
811
|
-
value
|
|
703
|
+
value(tag, attr, content) {
|
|
812
704
|
content = isFunction(content) ? this.fn(content)() : content;
|
|
813
|
-
this.echo(Promise.resolve(content).then(
|
|
814
|
-
return element(tag, attr, content);
|
|
815
|
-
}));
|
|
705
|
+
this.echo(Promise.resolve(content).then(content => element(tag, attr, content)));
|
|
816
706
|
},
|
|
817
707
|
writable: true
|
|
818
708
|
},
|
|
819
709
|
/** @type {function} */
|
|
820
710
|
ui: {
|
|
821
|
-
value
|
|
711
|
+
value(layout) {},
|
|
822
712
|
writable: true
|
|
823
713
|
}
|
|
824
714
|
});
|
|
825
|
-
return
|
|
826
|
-
};
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
return new
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
return {
|
|
845
|
-
configure: configure,
|
|
846
|
-
create: create,
|
|
847
|
-
helpers: helpers
|
|
848
|
-
};
|
|
849
|
-
};
|
|
715
|
+
return EjsContext;
|
|
716
|
+
};
|
|
717
|
+
class Context {
|
|
718
|
+
#context;
|
|
719
|
+
static exports = ['create', 'globals', 'helpers'];
|
|
720
|
+
constructor(options, methods) {
|
|
721
|
+
bindContext(this, this.constructor.exports);
|
|
722
|
+
this.configure(options, methods);
|
|
723
|
+
}
|
|
724
|
+
create(data) {
|
|
725
|
+
return new this.#context(data);
|
|
726
|
+
}
|
|
727
|
+
helpers(methods) {
|
|
728
|
+
Object.assign(this.#context.prototype, methods);
|
|
729
|
+
}
|
|
730
|
+
configure(options, methods) {
|
|
731
|
+
this.#context = createContext$1(options, methods);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
850
734
|
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
var require = function require(name) {
|
|
872
|
-
var scope = createContext({});
|
|
873
|
-
return output(filePath(name), scope).then(function () {
|
|
874
|
-
return scope.getMacro();
|
|
735
|
+
class EjsInstance {
|
|
736
|
+
#cache;
|
|
737
|
+
#context;
|
|
738
|
+
#compiler;
|
|
739
|
+
#template;
|
|
740
|
+
#config = {};
|
|
741
|
+
#methods = {};
|
|
742
|
+
static exports = ['configure', 'create', 'createContext', 'render', 'require', 'preload', 'compile', 'helpers'];
|
|
743
|
+
constructor() {
|
|
744
|
+
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
745
|
+
bindContext(this, this.constructor.exports);
|
|
746
|
+
this.#methods = {};
|
|
747
|
+
this.#config = configSchema({}, options);
|
|
748
|
+
this.#context = new Context(this.#config, this.#methods);
|
|
749
|
+
this.#compiler = new Compiler(this.#config);
|
|
750
|
+
this.#cache = new Cache(this.#config);
|
|
751
|
+
this.#template = new Template(this.#config, this.#cache, this.#compiler);
|
|
752
|
+
this.helpers({
|
|
753
|
+
render: this.render,
|
|
754
|
+
require: this.require
|
|
875
755
|
});
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
756
|
+
}
|
|
757
|
+
create(options) {
|
|
758
|
+
return new this.constructor(options);
|
|
759
|
+
}
|
|
760
|
+
configure(options) {
|
|
761
|
+
if (options) {
|
|
762
|
+
configSchema(this.#config, options);
|
|
763
|
+
this.#context.configure(this.#config, this.#methods);
|
|
764
|
+
this.#compiler.configure(this.#config);
|
|
765
|
+
this.#cache.configure(this.#config);
|
|
766
|
+
this.#template.configure(this.#config);
|
|
767
|
+
}
|
|
768
|
+
return this.#config;
|
|
769
|
+
}
|
|
770
|
+
createContext(data) {
|
|
771
|
+
return this.#context.create(data);
|
|
772
|
+
}
|
|
773
|
+
preload(list) {
|
|
774
|
+
return this.#cache.load(list || {});
|
|
775
|
+
}
|
|
776
|
+
compile(content, path) {
|
|
777
|
+
return this.#compiler.compile(content, path);
|
|
778
|
+
}
|
|
779
|
+
helpers(methods) {
|
|
780
|
+
this.#context.helpers(Object.assign(this.#methods, methods));
|
|
781
|
+
}
|
|
782
|
+
async render(name, params) {
|
|
783
|
+
const data = this.createContext(params);
|
|
784
|
+
return this.#output(this.#path(name), data).then(this.#outputContent(name, data));
|
|
785
|
+
}
|
|
786
|
+
async require(name) {
|
|
787
|
+
const data = this.createContext({});
|
|
788
|
+
return this.#output(this.#path(name), data).then(() => data.getMacro());
|
|
789
|
+
}
|
|
790
|
+
#path(name) {
|
|
791
|
+
const ext = name.split('.').pop();
|
|
792
|
+
if (ext !== this.#config.extension) {
|
|
793
|
+
name = [name, this.#config.extension].join('.');
|
|
794
|
+
}
|
|
795
|
+
return name;
|
|
796
|
+
}
|
|
797
|
+
#output(path, data) {
|
|
798
|
+
return this.#template.get(path).then(callback => callback.apply(data, [data, data.useComponent, data.useElement, data.useBuffer, data.useSafeValue]));
|
|
799
|
+
}
|
|
800
|
+
#renderLayout(name, params, parentTemplate) {
|
|
801
|
+
const data = this.createContext(params);
|
|
802
|
+
if (parentTemplate) data.setParentTemplate(parentTemplate);
|
|
803
|
+
return this.#output(this.#path(name), data).then(this.#outputContent(name, data));
|
|
804
|
+
}
|
|
805
|
+
#outputContent(name, data) {
|
|
806
|
+
return content => {
|
|
807
|
+
if (data.getExtend()) {
|
|
808
|
+
data.setExtend(false);
|
|
809
|
+
return this.#renderLayout(data.getLayout(), data, name);
|
|
886
810
|
}
|
|
887
811
|
return content;
|
|
888
812
|
};
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
var scope = createContext(data);
|
|
892
|
-
if (parent) scope.setParentTemplate(parent);
|
|
893
|
-
return output(filePath(name), scope).then(outputContent(name, scope));
|
|
894
|
-
};
|
|
895
|
-
var helpers = function helpers(extendMethods) {
|
|
896
|
-
context.helpers(extend(methods, extendMethods));
|
|
897
|
-
};
|
|
898
|
-
var createContext = function createContext(data) {
|
|
899
|
-
return context.create(data);
|
|
900
|
-
};
|
|
901
|
-
var compile = function compile(content, path) {
|
|
902
|
-
return compiler.compile(content, path);
|
|
903
|
-
};
|
|
904
|
-
var preload = function preload(list) {
|
|
905
|
-
return cache.load(list || {});
|
|
906
|
-
};
|
|
907
|
-
var create = function create(config) {
|
|
908
|
-
return _EJS$1(config);
|
|
909
|
-
};
|
|
910
|
-
var output = function output(path, scope) {
|
|
911
|
-
var params = [scope, scope.useComponent, scope.useElement, scope.getBuffer(), scope.useSafeValue];
|
|
912
|
-
var globals = config.globalHelpers.filter(function (name) {
|
|
913
|
-
return isFunction(scope[name]);
|
|
914
|
-
}).map(function (name) {
|
|
915
|
-
return scope[name].bind(scope);
|
|
916
|
-
});
|
|
917
|
-
return template.get(path).then(function (callback) {
|
|
918
|
-
return callback.apply(scope, params.concat(globals));
|
|
919
|
-
});
|
|
920
|
-
};
|
|
921
|
-
helpers({
|
|
922
|
-
render: render,
|
|
923
|
-
require: require
|
|
924
|
-
});
|
|
925
|
-
return {
|
|
926
|
-
configure: configure,
|
|
927
|
-
create: create,
|
|
928
|
-
createContext: createContext,
|
|
929
|
-
render: render,
|
|
930
|
-
require: require,
|
|
931
|
-
preload: preload,
|
|
932
|
-
compile: compile,
|
|
933
|
-
helpers: helpers
|
|
934
|
-
};
|
|
935
|
-
};
|
|
936
|
-
|
|
937
|
-
var readFile = function readFile(path, template) {
|
|
938
|
-
return new Promise(function (resolve, reject) {
|
|
939
|
-
fs.readFile(joinPath(path, template), function (error, data) {
|
|
940
|
-
if (error) {
|
|
941
|
-
reject(new TemplateError());
|
|
942
|
-
} else {
|
|
943
|
-
resolve(data.toString());
|
|
944
|
-
}
|
|
945
|
-
});
|
|
946
|
-
});
|
|
947
|
-
};
|
|
813
|
+
}
|
|
814
|
+
}
|
|
948
815
|
|
|
949
816
|
/**
|
|
950
817
|
*
|
|
@@ -952,40 +819,45 @@ var readFile = function readFile(path, template) {
|
|
|
952
819
|
* @param {function(name: string, data?: object):Promise<string>} render
|
|
953
820
|
* @return {function(name:any, options:any, callback: any): Promise<void>}
|
|
954
821
|
*/
|
|
955
|
-
|
|
822
|
+
const expressRenderer = (configure, render) => {
|
|
956
823
|
return function (name, options, callback) {
|
|
957
824
|
if (isFunction(options)) {
|
|
958
825
|
callback = options;
|
|
959
826
|
options = {};
|
|
960
827
|
}
|
|
961
828
|
options = options || {};
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
829
|
+
const settings = Object.assign({}, options.settings);
|
|
830
|
+
const viewPath = typeProp(isString, ejsDefaults.path, settings['views']);
|
|
831
|
+
const viewCache = typeProp(isBoolean, ejsDefaults.cache, settings['view cache']);
|
|
832
|
+
const viewOptions = Object.assign({}, settings['view options']);
|
|
833
|
+
const filename = path.relative(viewPath, name);
|
|
967
834
|
viewOptions.path = viewPath;
|
|
968
835
|
viewOptions.cache = viewCache;
|
|
969
836
|
configure(viewOptions);
|
|
970
|
-
return render(filename, options).then(
|
|
837
|
+
return render(filename, options).then(content => {
|
|
971
838
|
callback(null, content);
|
|
972
|
-
})
|
|
839
|
+
}).catch(error => {
|
|
973
840
|
callback(error);
|
|
974
841
|
});
|
|
975
842
|
};
|
|
976
843
|
};
|
|
977
844
|
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
845
|
+
const readFile = (path, template) => {
|
|
846
|
+
return fs.readFile(joinPath(path, template)).then(contents => contents.toString()).then(text => String(text));
|
|
847
|
+
};
|
|
848
|
+
|
|
849
|
+
const {
|
|
850
|
+
render,
|
|
851
|
+
createContext,
|
|
852
|
+
compile,
|
|
853
|
+
helpers,
|
|
854
|
+
preload,
|
|
855
|
+
configure,
|
|
856
|
+
create
|
|
857
|
+
} = new EjsInstance({
|
|
858
|
+
resolver: readFile
|
|
859
|
+
});
|
|
860
|
+
const __express = expressRenderer(configure, render);
|
|
989
861
|
|
|
990
862
|
exports.TemplateError = TemplateError;
|
|
991
863
|
exports.TemplateNotFound = TemplateNotFound;
|