@cloudpss/template 0.5.37 → 0.5.39
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/parser.d.ts +6 -5
- package/dist/parser.js +23 -19
- package/dist/parser.js.map +1 -1
- package/dist/template/compiler.js +6 -3
- package/dist/template/compiler.js.map +1 -1
- package/dist/template/index.d.ts +1 -1
- package/dist/template/index.js +3 -2
- package/dist/template/index.js.map +1 -1
- package/package.json +1 -1
- package/src/parser.ts +24 -19
- package/src/template/compiler.ts +7 -3
- package/src/template/index.ts +4 -3
- package/tests/parser.js +34 -18
- package/tests/template.js +6 -6
package/dist/parser.d.ts
CHANGED
|
@@ -15,18 +15,19 @@ export type Template = string | FormulaTemplate | InterpolationTemplate;
|
|
|
15
15
|
export type TemplateType = (Template & object)['type'];
|
|
16
16
|
/**
|
|
17
17
|
* 解析字符串插值模板
|
|
18
|
-
* @example parseInterpolation("hello $name! I am $age years old. I'll be ${age+1} next year.
|
|
18
|
+
* @example parseInterpolation("hello $name! I am $age years old. I'll be ${age+1} next year. And $(2*age) after $<age> years.")
|
|
19
19
|
* // {
|
|
20
20
|
* // type: 'interpolation',
|
|
21
|
-
* // templates: ['hello ', '! I am ', ' years old. I\'ll be ', ' next year.
|
|
22
|
-
* // values: ['name', 'age', 'age+1']
|
|
21
|
+
* // templates: ['hello ', '! I am ', ' years old. I\'ll be ', ' next year. And ', ' after ', ' years.'],
|
|
22
|
+
* // values: ['name', 'age', 'age+1', '2*age', 'age']
|
|
23
23
|
* // }
|
|
24
24
|
*/
|
|
25
25
|
export declare function parseInterpolation(template: string, start?: number, length?: number): InterpolationTemplate;
|
|
26
26
|
/**
|
|
27
27
|
* 解析字符串模板
|
|
28
|
-
* -
|
|
29
|
-
*
|
|
28
|
+
* - 长度大于 1
|
|
29
|
+
* - 如果模板以 `=` 开头,则表示是一个公式
|
|
30
|
+
* - 如果模板以 `$` 开头,则表示是一个插值模板
|
|
30
31
|
* - 否则表示是一个普通字符串
|
|
31
32
|
*/
|
|
32
33
|
export declare function parseTemplate(template: string): Template;
|
package/dist/parser.js
CHANGED
|
@@ -9,12 +9,17 @@ function isIdentifierChar(char) {
|
|
|
9
9
|
(charCode >= 48 && charCode <= 57) ||
|
|
10
10
|
charCode === 95);
|
|
11
11
|
}
|
|
12
|
+
/** 检查字符满足 [a-zA-Z_] */
|
|
13
|
+
function isIdentifierFirstChar(char) {
|
|
14
|
+
const charCode = char.charCodeAt(0);
|
|
15
|
+
return (charCode >= 97 && charCode <= 122) || (charCode >= 65 && charCode <= 90) || charCode === 95;
|
|
16
|
+
}
|
|
12
17
|
/** 字符串插值模板标识符 */
|
|
13
18
|
const INTERPOLATION_CHAR = '$';
|
|
14
19
|
/** 字符串插值模板表达式开始标识符 */
|
|
15
|
-
const INTERPOLATION_EXPRESSION_START = '{';
|
|
20
|
+
const INTERPOLATION_EXPRESSION_START = ['{', '[', '<', '('];
|
|
16
21
|
/** 字符串插值模板表达式结束标识符 */
|
|
17
|
-
const INTERPOLATION_EXPRESSION_END = '}';
|
|
22
|
+
const INTERPOLATION_EXPRESSION_END = ['}', ']', '>', ')'];
|
|
18
23
|
/**
|
|
19
24
|
* 解析字符串插值模板
|
|
20
25
|
* @example parseInterpolationImpl("hello $name! I am $age years old. I'll be ${age+1} next year. Give me $$100.")
|
|
@@ -31,6 +36,7 @@ function parseInterpolationImpl(template, start, length) {
|
|
|
31
36
|
let currentValue = '';
|
|
32
37
|
let expressionComplexDepth = 0;
|
|
33
38
|
let status = PARSER_STATUS_TEXT;
|
|
39
|
+
let complexExpressionStartType = -1;
|
|
34
40
|
const end = start + length - 1;
|
|
35
41
|
for (let i = start; i <= end; i++) {
|
|
36
42
|
if (status === PARSER_STATUS_TEXT) {
|
|
@@ -41,15 +47,10 @@ function parseInterpolationImpl(template, start, length) {
|
|
|
41
47
|
break;
|
|
42
48
|
}
|
|
43
49
|
currentTemplate += template.slice(i, nextInterpolationChar);
|
|
44
|
-
const nextChar = template.charAt(nextInterpolationChar + 1);
|
|
45
50
|
i = nextInterpolationChar;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
i++;
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
if (nextChar === INTERPOLATION_EXPRESSION_START) {
|
|
51
|
+
const nextChar = template.charAt(nextInterpolationChar + 1);
|
|
52
|
+
complexExpressionStartType = INTERPOLATION_EXPRESSION_START.indexOf(nextChar);
|
|
53
|
+
if (complexExpressionStartType >= 0) {
|
|
53
54
|
// Start of complex expression
|
|
54
55
|
templates.push(currentTemplate);
|
|
55
56
|
currentTemplate = '';
|
|
@@ -58,7 +59,7 @@ function parseInterpolationImpl(template, start, length) {
|
|
|
58
59
|
i++;
|
|
59
60
|
continue;
|
|
60
61
|
}
|
|
61
|
-
if (
|
|
62
|
+
if (isIdentifierFirstChar(nextChar)) {
|
|
62
63
|
// Start of simple expression
|
|
63
64
|
templates.push(currentTemplate);
|
|
64
65
|
currentTemplate = '';
|
|
@@ -85,10 +86,10 @@ function parseInterpolationImpl(template, start, length) {
|
|
|
85
86
|
continue;
|
|
86
87
|
}
|
|
87
88
|
if (status === PARSER_STATUS_EXPRESSION_COMPLEX) {
|
|
88
|
-
if (char === INTERPOLATION_EXPRESSION_START) {
|
|
89
|
+
if (char === INTERPOLATION_EXPRESSION_START[complexExpressionStartType]) {
|
|
89
90
|
expressionComplexDepth++;
|
|
90
91
|
}
|
|
91
|
-
else if (char === INTERPOLATION_EXPRESSION_END) {
|
|
92
|
+
else if (char === INTERPOLATION_EXPRESSION_END[complexExpressionStartType]) {
|
|
92
93
|
expressionComplexDepth--;
|
|
93
94
|
if (expressionComplexDepth === 0) {
|
|
94
95
|
// End of expression
|
|
@@ -120,11 +121,11 @@ function parseInterpolationImpl(template, start, length) {
|
|
|
120
121
|
}
|
|
121
122
|
/**
|
|
122
123
|
* 解析字符串插值模板
|
|
123
|
-
* @example parseInterpolation("hello $name! I am $age years old. I'll be ${age+1} next year.
|
|
124
|
+
* @example parseInterpolation("hello $name! I am $age years old. I'll be ${age+1} next year. And $(2*age) after $<age> years.")
|
|
124
125
|
* // {
|
|
125
126
|
* // type: 'interpolation',
|
|
126
|
-
* // templates: ['hello ', '! I am ', ' years old. I\'ll be ', ' next year.
|
|
127
|
-
* // values: ['name', 'age', 'age+1']
|
|
127
|
+
* // templates: ['hello ', '! I am ', ' years old. I\'ll be ', ' next year. And ', ' after ', ' years.'],
|
|
128
|
+
* // values: ['name', 'age', 'age+1', '2*age', 'age']
|
|
128
129
|
* // }
|
|
129
130
|
*/
|
|
130
131
|
export function parseInterpolation(template, start, length) {
|
|
@@ -140,17 +141,20 @@ export function parseInterpolation(template, start, length) {
|
|
|
140
141
|
}
|
|
141
142
|
/**
|
|
142
143
|
* 解析字符串模板
|
|
143
|
-
* -
|
|
144
|
-
*
|
|
144
|
+
* - 长度大于 1
|
|
145
|
+
* - 如果模板以 `=` 开头,则表示是一个公式
|
|
146
|
+
* - 如果模板以 `$` 开头,则表示是一个插值模板
|
|
145
147
|
* - 否则表示是一个普通字符串
|
|
146
148
|
*/
|
|
147
149
|
export function parseTemplate(template) {
|
|
148
150
|
if (!template)
|
|
149
151
|
return '';
|
|
152
|
+
if (template.length <= 1)
|
|
153
|
+
return template;
|
|
150
154
|
if (template.startsWith('=')) {
|
|
151
155
|
return {
|
|
152
156
|
type: 'formula',
|
|
153
|
-
value: template.slice(1)
|
|
157
|
+
value: template.slice(1),
|
|
154
158
|
};
|
|
155
159
|
}
|
|
156
160
|
if (template.startsWith('$')) {
|
package/dist/parser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAmBA,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAC7B,MAAM,+BAA+B,GAAG,CAAC,CAAC;AAC1C,MAAM,gCAAgC,GAAG,CAAC,CAAC;AAO3C,0BAA0B;AAC1B,SAAS,gBAAgB,CAAC,IAAY;IAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACpC,OAAO,CACH,CAAC,QAAQ,IAAI,EAAE,IAAI,QAAQ,IAAI,GAAG,CAAC;QACnC,CAAC,QAAQ,IAAI,EAAE,IAAI,QAAQ,IAAI,EAAE,CAAC;QAClC,CAAC,QAAQ,IAAI,EAAE,IAAI,QAAQ,IAAI,EAAE,CAAC;QAClC,QAAQ,KAAK,EAAE,CAClB,CAAC;AACN,CAAC;AAED,iBAAiB;AACjB,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAC/B,sBAAsB;AACtB,MAAM,8BAA8B,GAAG,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,9 @@ function isError(value) {
|
|
|
12
12
|
return value instanceof Error || (typeof DOMException == 'function' && value instanceof DOMException);
|
|
13
13
|
}
|
|
14
14
|
const KNOWN_ERRORS = [EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError];
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
16
|
+
const toString = Function.call.bind(Object.prototype.toString);
|
|
17
|
+
const { hasOwn, defineProperty } = Object;
|
|
15
18
|
/** 模板序列号 */
|
|
16
19
|
let seq = 0;
|
|
17
20
|
/** 创建模板 */
|
|
@@ -81,7 +84,7 @@ export class TemplateCompiler {
|
|
|
81
84
|
buildObject(obj) {
|
|
82
85
|
let result = '';
|
|
83
86
|
for (const key in obj) {
|
|
84
|
-
if (!
|
|
87
|
+
if (!hasOwn(obj, key))
|
|
85
88
|
continue;
|
|
86
89
|
const value = obj[key];
|
|
87
90
|
if (result)
|
|
@@ -125,7 +128,7 @@ export class TemplateCompiler {
|
|
|
125
128
|
return this.buildString(value)[0];
|
|
126
129
|
/* c8 ignore next */
|
|
127
130
|
if (typeof value != 'object')
|
|
128
|
-
throw new Error(`Unsupported value: ${
|
|
131
|
+
throw new Error(`Unsupported value: ${toString(value)}`);
|
|
129
132
|
if (value instanceof Date)
|
|
130
133
|
return `new Date(${value.getTime()})`;
|
|
131
134
|
if (value instanceof RegExp)
|
|
@@ -155,7 +158,7 @@ export class TemplateCompiler {
|
|
|
155
158
|
? `return async (context = {}) => (${source});`
|
|
156
159
|
: `return (context = {}) => (${source});`,
|
|
157
160
|
].join('\n'))(...params.map(([, value]) => value));
|
|
158
|
-
|
|
161
|
+
defineProperty(result, 'source', { value: source, configurable: true });
|
|
159
162
|
return result;
|
|
160
163
|
/* c8 ignore next 3 */
|
|
161
164
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../src/template/compiler.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../src/template/compiler.ts"],"names":[],"mappings":"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"}
|
package/dist/template/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export type TemplateEvaluator = {
|
|
|
5
5
|
inject?: unknown;
|
|
6
6
|
/** 求值代码是否为异步 @default false */
|
|
7
7
|
async?: boolean;
|
|
8
|
-
/**
|
|
8
|
+
/** 生成求值 JS 代码,可用变量:`evaluator` `context` */
|
|
9
9
|
compile: (expression: string, type: TemplateType) => string;
|
|
10
10
|
};
|
|
11
11
|
/** 模板选项 */
|
package/dist/template/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { TemplateCompiler } from './compiler.js';
|
|
2
2
|
export const defaultEvaluator = {
|
|
3
3
|
compile: (expression, type) => {
|
|
4
|
+
const key = JSON.stringify(expression.trim());
|
|
4
5
|
switch (type) {
|
|
5
6
|
case 'formula':
|
|
6
|
-
return `context[${
|
|
7
|
+
return `context[${key}]`;
|
|
7
8
|
case 'interpolation':
|
|
8
|
-
return `(context[${
|
|
9
|
+
return `(context[${key}] ?? '')`;
|
|
9
10
|
/* c8 ignore next 2 */
|
|
10
11
|
default:
|
|
11
12
|
throw new Error(`Unsupported type: ${type}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/template/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AA4BjD,MAAM,CAAC,MAAM,gBAAgB,GAAsB;IAC/C,OAAO,EAAE,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE;QAC1B,QAAQ,IAAI,EAAE,CAAC;YACX,KAAK,SAAS;gBACV,OAAO,WAAW,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/template/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AA4BjD,MAAM,CAAC,MAAM,gBAAgB,GAAsB;IAC/C,OAAO,EAAE,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9C,QAAQ,IAAI,EAAE,CAAC;YACX,KAAK,SAAS;gBACV,OAAO,WAAW,GAAG,GAAG,CAAC;YAC7B,KAAK,eAAe;gBAChB,OAAO,YAAY,GAAG,UAAU,CAAC;YACrC,sBAAsB;YACtB;gBACI,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAA8B,EAAE,CAAC,CAAC;QAC/E,CAAC;IACL,CAAC;CACJ,CAAC;AAiBF,WAAW;AACX,MAAM,UAAU,QAAQ,CACpB,QAAW,EACX,UAA2B,EAAE;IAE7B,MAAM,GAAG,GAAG;QACR,aAAa,EAAE,UAAU;QACzB,SAAS,EAAE,gBAAgB;QAC3B,GAAG,OAAO;KACb,CAAC;IACF,OAAO,IAAI,gBAAgB,CAAC,QAAQ,EAAE,GAAgC,CAAC,CAAC,KAAK,EAA4B,CAAC;AAC9G,CAAC"}
|
package/package.json
CHANGED
package/src/parser.ts
CHANGED
|
@@ -37,12 +37,18 @@ function isIdentifierChar(char: string): boolean {
|
|
|
37
37
|
);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/** 检查字符满足 [a-zA-Z_] */
|
|
41
|
+
function isIdentifierFirstChar(char: string): boolean {
|
|
42
|
+
const charCode = char.charCodeAt(0);
|
|
43
|
+
return (charCode >= 97 && charCode <= 122) || (charCode >= 65 && charCode <= 90) || charCode === 95;
|
|
44
|
+
}
|
|
45
|
+
|
|
40
46
|
/** 字符串插值模板标识符 */
|
|
41
47
|
const INTERPOLATION_CHAR = '$';
|
|
42
48
|
/** 字符串插值模板表达式开始标识符 */
|
|
43
|
-
const INTERPOLATION_EXPRESSION_START = '{';
|
|
49
|
+
const INTERPOLATION_EXPRESSION_START = ['{', '[', '<', '('];
|
|
44
50
|
/** 字符串插值模板表达式结束标识符 */
|
|
45
|
-
const INTERPOLATION_EXPRESSION_END = '}';
|
|
51
|
+
const INTERPOLATION_EXPRESSION_END = ['}', ']', '>', ')'];
|
|
46
52
|
|
|
47
53
|
/**
|
|
48
54
|
* 解析字符串插值模板
|
|
@@ -60,6 +66,7 @@ function parseInterpolationImpl(template: string, start: number, length: number)
|
|
|
60
66
|
let currentValue = '';
|
|
61
67
|
let expressionComplexDepth = 0;
|
|
62
68
|
let status: ParserStatus = PARSER_STATUS_TEXT;
|
|
69
|
+
let complexExpressionStartType = -1;
|
|
63
70
|
|
|
64
71
|
const end = start + length - 1;
|
|
65
72
|
for (let i = start; i <= end; i++) {
|
|
@@ -71,15 +78,11 @@ function parseInterpolationImpl(template: string, start: number, length: number)
|
|
|
71
78
|
break;
|
|
72
79
|
}
|
|
73
80
|
currentTemplate += template.slice(i, nextInterpolationChar);
|
|
74
|
-
const nextChar = template.charAt(nextInterpolationChar + 1);
|
|
75
81
|
i = nextInterpolationChar;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
if (nextChar === INTERPOLATION_EXPRESSION_START) {
|
|
82
|
+
const nextChar = template.charAt(nextInterpolationChar + 1);
|
|
83
|
+
|
|
84
|
+
complexExpressionStartType = INTERPOLATION_EXPRESSION_START.indexOf(nextChar);
|
|
85
|
+
if (complexExpressionStartType >= 0) {
|
|
83
86
|
// Start of complex expression
|
|
84
87
|
templates.push(currentTemplate);
|
|
85
88
|
currentTemplate = '';
|
|
@@ -88,7 +91,7 @@ function parseInterpolationImpl(template: string, start: number, length: number)
|
|
|
88
91
|
i++;
|
|
89
92
|
continue;
|
|
90
93
|
}
|
|
91
|
-
if (
|
|
94
|
+
if (isIdentifierFirstChar(nextChar)) {
|
|
92
95
|
// Start of simple expression
|
|
93
96
|
templates.push(currentTemplate);
|
|
94
97
|
currentTemplate = '';
|
|
@@ -115,9 +118,9 @@ function parseInterpolationImpl(template: string, start: number, length: number)
|
|
|
115
118
|
continue;
|
|
116
119
|
}
|
|
117
120
|
if (status === PARSER_STATUS_EXPRESSION_COMPLEX) {
|
|
118
|
-
if (char === INTERPOLATION_EXPRESSION_START) {
|
|
121
|
+
if (char === INTERPOLATION_EXPRESSION_START[complexExpressionStartType]) {
|
|
119
122
|
expressionComplexDepth++;
|
|
120
|
-
} else if (char === INTERPOLATION_EXPRESSION_END) {
|
|
123
|
+
} else if (char === INTERPOLATION_EXPRESSION_END[complexExpressionStartType]) {
|
|
121
124
|
expressionComplexDepth--;
|
|
122
125
|
if (expressionComplexDepth === 0) {
|
|
123
126
|
// End of expression
|
|
@@ -149,11 +152,11 @@ function parseInterpolationImpl(template: string, start: number, length: number)
|
|
|
149
152
|
|
|
150
153
|
/**
|
|
151
154
|
* 解析字符串插值模板
|
|
152
|
-
* @example parseInterpolation("hello $name! I am $age years old. I'll be ${age+1} next year.
|
|
155
|
+
* @example parseInterpolation("hello $name! I am $age years old. I'll be ${age+1} next year. And $(2*age) after $<age> years.")
|
|
153
156
|
* // {
|
|
154
157
|
* // type: 'interpolation',
|
|
155
|
-
* // templates: ['hello ', '! I am ', ' years old. I\'ll be ', ' next year.
|
|
156
|
-
* // values: ['name', 'age', 'age+1']
|
|
158
|
+
* // templates: ['hello ', '! I am ', ' years old. I\'ll be ', ' next year. And ', ' after ', ' years.'],
|
|
159
|
+
* // values: ['name', 'age', 'age+1', '2*age', 'age']
|
|
157
160
|
* // }
|
|
158
161
|
*/
|
|
159
162
|
export function parseInterpolation(template: string, start?: number, length?: number): InterpolationTemplate {
|
|
@@ -166,16 +169,18 @@ export function parseInterpolation(template: string, start?: number, length?: nu
|
|
|
166
169
|
|
|
167
170
|
/**
|
|
168
171
|
* 解析字符串模板
|
|
169
|
-
* -
|
|
170
|
-
*
|
|
172
|
+
* - 长度大于 1
|
|
173
|
+
* - 如果模板以 `=` 开头,则表示是一个公式
|
|
174
|
+
* - 如果模板以 `$` 开头,则表示是一个插值模板
|
|
171
175
|
* - 否则表示是一个普通字符串
|
|
172
176
|
*/
|
|
173
177
|
export function parseTemplate(template: string): Template {
|
|
174
178
|
if (!template) return '';
|
|
179
|
+
if (template.length <= 1) return template;
|
|
175
180
|
if (template.startsWith('=')) {
|
|
176
181
|
return {
|
|
177
182
|
type: 'formula',
|
|
178
|
-
value: template.slice(1)
|
|
183
|
+
value: template.slice(1),
|
|
179
184
|
};
|
|
180
185
|
}
|
|
181
186
|
if (template.startsWith('$')) {
|
package/src/template/compiler.ts
CHANGED
|
@@ -15,6 +15,10 @@ function isError(value: unknown): value is Error {
|
|
|
15
15
|
|
|
16
16
|
const KNOWN_ERRORS = [EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError] as const;
|
|
17
17
|
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
19
|
+
const toString = Function.call.bind(Object.prototype.toString) as (value: unknown) => string;
|
|
20
|
+
const { hasOwn, defineProperty } = Object;
|
|
21
|
+
|
|
18
22
|
/** 模板序列号 */
|
|
19
23
|
let seq = 0;
|
|
20
24
|
|
|
@@ -80,7 +84,7 @@ export class TemplateCompiler {
|
|
|
80
84
|
private buildObject(obj: Record<string, unknown>): string {
|
|
81
85
|
let result = '';
|
|
82
86
|
for (const key in obj) {
|
|
83
|
-
if (!
|
|
87
|
+
if (!hasOwn(obj, key)) continue;
|
|
84
88
|
const value = obj[key];
|
|
85
89
|
if (result) result += ',\n';
|
|
86
90
|
if (this.options.objectKeyMode === 'ignore') {
|
|
@@ -110,7 +114,7 @@ export class TemplateCompiler {
|
|
|
110
114
|
if (typeof value == 'number') return String(value);
|
|
111
115
|
if (typeof value == 'string') return this.buildString(value)[0];
|
|
112
116
|
/* c8 ignore next */
|
|
113
|
-
if (typeof value != 'object') throw new Error(`Unsupported value: ${
|
|
117
|
+
if (typeof value != 'object') throw new Error(`Unsupported value: ${toString(value)}`);
|
|
114
118
|
if (value instanceof Date) return `new Date(${value.getTime()})`;
|
|
115
119
|
if (value instanceof RegExp) return value.toString();
|
|
116
120
|
if (isError(value)) return this.buildError(value);
|
|
@@ -137,7 +141,7 @@ export class TemplateCompiler {
|
|
|
137
141
|
: `return (context = {}) => (${source});`,
|
|
138
142
|
].join('\n'),
|
|
139
143
|
)(...params.map(([, value]) => value)) as TemplateFunction;
|
|
140
|
-
|
|
144
|
+
defineProperty(result, 'source', { value: source, configurable: true });
|
|
141
145
|
return result;
|
|
142
146
|
/* c8 ignore next 3 */
|
|
143
147
|
} catch (e) {
|
package/src/template/index.ts
CHANGED
|
@@ -7,7 +7,7 @@ export type TemplateEvaluator = {
|
|
|
7
7
|
inject?: unknown;
|
|
8
8
|
/** 求值代码是否为异步 @default false */
|
|
9
9
|
async?: boolean;
|
|
10
|
-
/**
|
|
10
|
+
/** 生成求值 JS 代码,可用变量:`evaluator` `context` */
|
|
11
11
|
compile: (expression: string, type: TemplateType) => string;
|
|
12
12
|
};
|
|
13
13
|
|
|
@@ -29,11 +29,12 @@ export interface TemplateOptions {
|
|
|
29
29
|
|
|
30
30
|
export const defaultEvaluator: TemplateEvaluator = {
|
|
31
31
|
compile: (expression, type) => {
|
|
32
|
+
const key = JSON.stringify(expression.trim());
|
|
32
33
|
switch (type) {
|
|
33
34
|
case 'formula':
|
|
34
|
-
return `context[${
|
|
35
|
+
return `context[${key}]`;
|
|
35
36
|
case 'interpolation':
|
|
36
|
-
return `(context[${
|
|
37
|
+
return `(context[${key}] ?? '')`;
|
|
37
38
|
/* c8 ignore next 2 */
|
|
38
39
|
default:
|
|
39
40
|
throw new Error(`Unsupported type: ${type satisfies never as string}`);
|
package/tests/parser.js
CHANGED
|
@@ -19,8 +19,8 @@ describe('parseInterpolation', () => {
|
|
|
19
19
|
});
|
|
20
20
|
expect(parseInterpolation('$$name')).toEqual({
|
|
21
21
|
type: 'interpolation',
|
|
22
|
-
templates: ['$
|
|
23
|
-
values: [],
|
|
22
|
+
templates: ['$', ''],
|
|
23
|
+
values: ['name'],
|
|
24
24
|
});
|
|
25
25
|
expect(parseInterpolation('$name_is_long')).toEqual({
|
|
26
26
|
type: 'interpolation',
|
|
@@ -32,15 +32,15 @@ describe('parseInterpolation', () => {
|
|
|
32
32
|
templates: ['', ''],
|
|
33
33
|
values: ['_001'],
|
|
34
34
|
});
|
|
35
|
-
expect(parseInterpolation('$001$a')).toEqual({
|
|
35
|
+
expect(parseInterpolation('$001$a$')).toEqual({
|
|
36
36
|
type: 'interpolation',
|
|
37
|
-
templates: ['', ''
|
|
38
|
-
values: ['
|
|
37
|
+
templates: ['$001', '$'],
|
|
38
|
+
values: ['a'],
|
|
39
39
|
});
|
|
40
40
|
expect(parseInterpolation('$$name$a')).toEqual({
|
|
41
41
|
type: 'interpolation',
|
|
42
|
-
templates: ['$
|
|
43
|
-
values: ['a'],
|
|
42
|
+
templates: ['$', '', ''],
|
|
43
|
+
values: ['name', 'a'],
|
|
44
44
|
});
|
|
45
45
|
expect(parseInterpolation('$ $ $ $')).toEqual({
|
|
46
46
|
type: 'interpolation',
|
|
@@ -103,6 +103,8 @@ describe('parseTemplate', () => {
|
|
|
103
103
|
expect(parseTemplate('\uDC00')).toEqual('\uDC00');
|
|
104
104
|
});
|
|
105
105
|
it('template like (but not)', () => {
|
|
106
|
+
expect(parseTemplate('$')).toBe('$');
|
|
107
|
+
expect(parseTemplate('=')).toBe('=');
|
|
106
108
|
expect(parseTemplate(' = 1+1')).toEqual(' = 1+1');
|
|
107
109
|
expect(parseTemplate(' =1+1')).toEqual(' =1+1');
|
|
108
110
|
expect(parseTemplate(' =1+1 ')).toEqual(' =1+1 ');
|
|
@@ -112,20 +114,19 @@ describe('parseTemplate', () => {
|
|
|
112
114
|
});
|
|
113
115
|
|
|
114
116
|
it('should parse formulas', () => {
|
|
115
|
-
expect(parseTemplate('= 1+1')).toEqual({ type: 'formula', value: '1+1' });
|
|
116
|
-
expect(parseTemplate('= 1+1 ')).toEqual({ type: 'formula', value: '1+1' });
|
|
117
|
+
expect(parseTemplate('= 1+1')).toEqual({ type: 'formula', value: ' 1+1' });
|
|
118
|
+
expect(parseTemplate('= 1+1 ')).toEqual({ type: 'formula', value: ' 1+1 ' });
|
|
117
119
|
expect(parseTemplate('=arg')).toEqual({ type: 'formula', value: 'arg' });
|
|
118
120
|
expect(parseTemplate('=arg1+arg2')).toEqual({ type: 'formula', value: 'arg1+arg2' });
|
|
119
121
|
});
|
|
120
122
|
|
|
121
123
|
describe('should parse interpolation', () => {
|
|
122
124
|
it('optimize for no interpolation', () => {
|
|
123
|
-
expect(parseTemplate('$')).toBe('');
|
|
124
125
|
expect(parseTemplate('$not')).toBe('not');
|
|
125
126
|
expect(parseTemplate('$not interpolation')).toBe('not interpolation');
|
|
126
127
|
expect(parseTemplate('$$')).toBe('$');
|
|
127
|
-
expect(parseTemplate('$$$')).toBe('
|
|
128
|
-
expect(parseTemplate('$$$$')).toBe('
|
|
128
|
+
expect(parseTemplate('$$$')).toBe('$$');
|
|
129
|
+
expect(parseTemplate('$$$$')).toBe('$$$');
|
|
129
130
|
});
|
|
130
131
|
|
|
131
132
|
it('should parse simple interpolation', () => {
|
|
@@ -151,8 +152,8 @@ describe('parseTemplate', () => {
|
|
|
151
152
|
});
|
|
152
153
|
expect(parseTemplate('$$001$a')).toEqual({
|
|
153
154
|
type: 'interpolation',
|
|
154
|
-
templates: ['', ''
|
|
155
|
-
values: ['
|
|
155
|
+
templates: ['$001', ''],
|
|
156
|
+
values: ['a'],
|
|
156
157
|
});
|
|
157
158
|
expect(parseTemplate('$$name$a')).toEqual({
|
|
158
159
|
type: 'interpolation',
|
|
@@ -206,11 +207,13 @@ describe('parseTemplate', () => {
|
|
|
206
207
|
values: ['name', 'a'],
|
|
207
208
|
});
|
|
208
209
|
expect(
|
|
209
|
-
|
|
210
|
+
parseInterpolation(
|
|
211
|
+
"hello $name! I am $age years old. I'll be ${age+1} next year. And $(2*age) after $<age> years. $100",
|
|
212
|
+
),
|
|
210
213
|
).toEqual({
|
|
211
214
|
type: 'interpolation',
|
|
212
|
-
templates: ['hello ', '! I am ', " years old. I'll be ", ' next year.
|
|
213
|
-
values: ['name', 'age', 'age+1'],
|
|
215
|
+
templates: ['hello ', '! I am ', " years old. I'll be ", ' next year. And ', ' after ', ' years. $100'],
|
|
216
|
+
values: ['name', 'age', 'age+1', '2*age', 'age'],
|
|
214
217
|
});
|
|
215
218
|
});
|
|
216
219
|
|
|
@@ -230,15 +233,23 @@ describe('parseTemplate', () => {
|
|
|
230
233
|
templates: ['', '{}'],
|
|
231
234
|
values: ['aa'],
|
|
232
235
|
});
|
|
236
|
+
expect(parseTemplate('$$aa<xx>')).toEqual({
|
|
237
|
+
type: 'interpolation',
|
|
238
|
+
templates: ['', '<xx>'],
|
|
239
|
+
values: ['aa'],
|
|
240
|
+
});
|
|
233
241
|
expect(parseTemplate('$$$$aa{}')).toEqual({
|
|
234
242
|
type: 'interpolation',
|
|
235
|
-
templates: ['
|
|
243
|
+
templates: ['$$', '{}'],
|
|
236
244
|
values: ['aa'],
|
|
237
245
|
});
|
|
238
246
|
});
|
|
239
247
|
|
|
240
248
|
it('should throw on invalid interpolation', () => {
|
|
241
249
|
expect(() => parseTemplate('$${')).toThrow('Unexpected end of input');
|
|
250
|
+
expect(() => parseTemplate('$$<')).toThrow('Unexpected end of input');
|
|
251
|
+
expect(() => parseTemplate('$$[')).toThrow('Unexpected end of input');
|
|
252
|
+
expect(() => parseTemplate('$$(')).toThrow('Unexpected end of input');
|
|
242
253
|
expect(() => parseTemplate('$${123')).toThrow('Unexpected end of input');
|
|
243
254
|
expect(() => parseTemplate('$${{123}')).toThrow('Unexpected end of input');
|
|
244
255
|
});
|
|
@@ -249,6 +260,11 @@ describe('parseTemplate', () => {
|
|
|
249
260
|
templates: ['', ''],
|
|
250
261
|
values: ['n{am}e'],
|
|
251
262
|
});
|
|
263
|
+
expect(parseTemplate('$$(n{a(m)e)')).toEqual({
|
|
264
|
+
type: 'interpolation',
|
|
265
|
+
templates: ['', ''],
|
|
266
|
+
values: ['n{a(m)e'],
|
|
267
|
+
});
|
|
252
268
|
expect(parseTemplate('$${n{{a}m}e}')).toEqual({
|
|
253
269
|
type: 'interpolation',
|
|
254
270
|
templates: ['', ''],
|
package/tests/template.js
CHANGED
|
@@ -132,7 +132,7 @@ describe('template', () => {
|
|
|
132
132
|
});
|
|
133
133
|
describe('should copy ArrayBuffers', () => {
|
|
134
134
|
it('ArrayBuffer', () => {
|
|
135
|
-
const buffer = randomBytes(16)
|
|
135
|
+
const { buffer } = randomBytes(16);
|
|
136
136
|
const t = template(buffer);
|
|
137
137
|
const result1 = t();
|
|
138
138
|
const result2 = t();
|
|
@@ -153,7 +153,7 @@ describe('template', () => {
|
|
|
153
153
|
});
|
|
154
154
|
describe('should copy ArrayBufferViews', () => {
|
|
155
155
|
it('DataView', () => {
|
|
156
|
-
const buffer = randomBytes(64)
|
|
156
|
+
const { buffer } = randomBytes(64);
|
|
157
157
|
const view = new DataView(buffer, 32, 16);
|
|
158
158
|
const result = template(view)();
|
|
159
159
|
expect(result).toEqual(view);
|
|
@@ -162,7 +162,7 @@ describe('template', () => {
|
|
|
162
162
|
expect(result.buffer).not.toBe(buffer);
|
|
163
163
|
});
|
|
164
164
|
it('Uint8Array', () => {
|
|
165
|
-
const buffer = randomBytes(64)
|
|
165
|
+
const { buffer } = randomBytes(64);
|
|
166
166
|
const view = new Uint8Array(buffer, 32, 16);
|
|
167
167
|
const result = template(view)();
|
|
168
168
|
expect(result).toEqual(view);
|
|
@@ -171,7 +171,7 @@ describe('template', () => {
|
|
|
171
171
|
expect(result.buffer).not.toBe(buffer);
|
|
172
172
|
});
|
|
173
173
|
it('Float64Array', () => {
|
|
174
|
-
const buffer = randomBytes(64)
|
|
174
|
+
const { buffer } = randomBytes(64);
|
|
175
175
|
const view = new Float64Array(buffer, 32, 1);
|
|
176
176
|
const result = template(view)();
|
|
177
177
|
expect(result).toEqual(view);
|
|
@@ -180,7 +180,7 @@ describe('template', () => {
|
|
|
180
180
|
expect(result.buffer).not.toBe(buffer);
|
|
181
181
|
});
|
|
182
182
|
it('BigInt64Array', () => {
|
|
183
|
-
const buffer = randomBytes(64)
|
|
183
|
+
const { buffer } = randomBytes(64);
|
|
184
184
|
const view = new BigInt64Array(buffer, 32, 1);
|
|
185
185
|
const t = template(view);
|
|
186
186
|
const result1 = t();
|
|
@@ -229,7 +229,7 @@ describe('template', () => {
|
|
|
229
229
|
const obj = { $: 1, _: 2, '=x': 3, $$y: 4 };
|
|
230
230
|
const result = template(obj, { objectKeyMode: 'template' })({ x: 11n, y: 12 });
|
|
231
231
|
expect(result).toEqual({
|
|
232
|
-
|
|
232
|
+
$: 1,
|
|
233
233
|
_: 2,
|
|
234
234
|
11: 3,
|
|
235
235
|
12: 4,
|