@cloudpss/template 0.6.14 → 0.6.16
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 +16 -1
- package/dist/builder.d.ts +3 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +14 -0
- package/dist/builder.js.map +1 -0
- package/dist/{template/compiler.d.ts → compiler.d.ts} +5 -8
- package/dist/compiler.d.ts.map +1 -0
- package/dist/compiler.js +126 -0
- package/dist/compiler.js.map +1 -0
- package/dist/index.d.ts +16 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/dist/parser.d.ts +6 -23
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +27 -151
- package/dist/parser.js.map +1 -1
- package/dist/utils.d.ts +27 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +37 -0
- package/dist/utils.js.map +1 -0
- package/package.json +5 -1
- package/src/builder.ts +15 -0
- package/src/compiler.ts +121 -0
- package/src/index.ts +60 -4
- package/src/parser.ts +34 -172
- package/src/utils.ts +50 -0
- package/tests/template.ts +21 -60
- package/dist/template/compiler.d.ts.map +0 -1
- package/dist/template/compiler.js +0 -168
- package/dist/template/compiler.js.map +0 -1
- package/dist/template/index.d.ts +0 -42
- package/dist/template/index.d.ts.map +0 -1
- package/dist/template/index.js +0 -25
- package/dist/template/index.js.map +0 -1
- package/src/template/compiler.ts +0 -151
- package/src/template/index.ts +0 -74
- package/tests/parser.ts +0 -285
package/README.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
1
|
# @cloudpss/template
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Lightweight string and object templating utilities with interpolation and formula support.
|
|
4
|
+
|
|
5
|
+
Use `=` prefix for formula evaluation and `$` prefix for string interpolation.
|
|
6
|
+
|
|
7
|
+
## Example
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { template } from '@cloudpss/template';
|
|
11
|
+
|
|
12
|
+
const greet = template({
|
|
13
|
+
message: '$Hello, ${name}',
|
|
14
|
+
type: '=type',
|
|
15
|
+
});
|
|
16
|
+
console.log(greet({ name: 'World', type: 'text' }));
|
|
17
|
+
// { message: 'Hello, World', type: 'text' }
|
|
18
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAIA,eAAe;AACf,wBAAgB,UAAU,CAAC,GAAG,EAAE,KAAK,GAAG,MAAM,CAS7C"}
|
package/dist/builder.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { stringify } from './utils.js';
|
|
2
|
+
const KNOWN_ERRORS = [EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError];
|
|
3
|
+
/** 构建 Error */
|
|
4
|
+
export function buildError(err) {
|
|
5
|
+
if (typeof DOMException == 'function' && err instanceof DOMException) {
|
|
6
|
+
return `new DOMException(${stringify(err.message)}, ${stringify(err.name)})`;
|
|
7
|
+
}
|
|
8
|
+
const constructor = KNOWN_ERRORS.find((type) => err instanceof type)?.name ?? 'Error';
|
|
9
|
+
if (err.name === constructor) {
|
|
10
|
+
return `new ${constructor}(${stringify(err.message)})`;
|
|
11
|
+
}
|
|
12
|
+
return `Object.assign(new ${constructor}(${stringify(err.message)}), {name: ${stringify(err.name)}})`;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,YAAY,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAC;AAExG,eAAe;AACf,MAAM,UAAU,UAAU,CAAC,GAAU;IACjC,IAAI,OAAO,YAAY,IAAI,UAAU,IAAI,GAAG,YAAY,YAAY,EAAE,CAAC;QACnE,OAAO,oBAAoB,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;IACjF,CAAC;IACD,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,YAAY,IAAI,CAAC,EAAE,IAAI,IAAI,OAAO,CAAC;IACtF,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC3B,OAAO,OAAO,WAAW,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC;IAC3D,CAAC;IACD,OAAO,qBAAqB,WAAW,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;AAC1G,CAAC"}
|
|
@@ -4,20 +4,17 @@ export declare class TemplateCompiler {
|
|
|
4
4
|
readonly template: unknown;
|
|
5
5
|
readonly options: Required<TemplateOptions>;
|
|
6
6
|
constructor(template: unknown, options: Required<TemplateOptions>);
|
|
7
|
-
private readonly
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
private buildEval;
|
|
11
|
-
/** 构建字符串 */
|
|
12
|
-
private buildString;
|
|
13
|
-
/** 构建 Error */
|
|
14
|
-
private buildError;
|
|
7
|
+
private readonly $;
|
|
8
|
+
/** 放入 $,返回索引 */
|
|
9
|
+
private use;
|
|
15
10
|
/** 构建数组 */
|
|
16
11
|
private buildArray;
|
|
17
12
|
/** 构建 ArrayBuffer */
|
|
18
13
|
private buildArrayBuffer;
|
|
19
14
|
/** 构建 ArrayBufferView */
|
|
20
15
|
private buildArrayBufferView;
|
|
16
|
+
/** 构建可能为模板的字符串 */
|
|
17
|
+
private buildTemplate;
|
|
21
18
|
/** 构建对象 */
|
|
22
19
|
private buildObject;
|
|
23
20
|
/** 构建值 */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAmBpE,WAAW;AACX,qBAAa,gBAAgB;IAErB,QAAQ,CAAC,QAAQ,EAAE,OAAO;IAC1B,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,eAAe,CAAC;gBADlC,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,QAAQ,CAAC,eAAe,CAAC;IAE/C,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAyB;IAC3C,gBAAgB;IAChB,OAAO,CAAC,GAAG;IAIX,WAAW;IACX,OAAO,CAAC,UAAU;IASlB,qBAAqB;IACrB,OAAO,CAAC,gBAAgB;IAIxB,yBAAyB;IACzB,OAAO,CAAC,oBAAoB;IAI5B,kBAAkB;IAClB,OAAO,CAAC,aAAa;IAQrB,WAAW;IACX,OAAO,CAAC,WAAW;IAkBnB,UAAU;IACV,OAAO,CAAC,UAAU;IAoBlB,WAAW;IACX,KAAK,IAAI,gBAAgB;CAiB5B"}
|
package/dist/compiler.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { unwrapFromVmValue } from '@mirascript/mirascript';
|
|
2
|
+
import { buildError } from './builder.js';
|
|
3
|
+
import { parseTemplate } from './parser.js';
|
|
4
|
+
import { hasOwn, isError, isArrayBuffer, copyArrayBuffer, stringify, toString, isArrayBufferView, isArray, } from './utils.js';
|
|
5
|
+
/** 模板序列号 */
|
|
6
|
+
let seq = 0;
|
|
7
|
+
const $init = [unwrapFromVmValue];
|
|
8
|
+
const $unwrapFromVmValue = 0;
|
|
9
|
+
/** 创建模板 */
|
|
10
|
+
export class TemplateCompiler {
|
|
11
|
+
constructor(template, options) {
|
|
12
|
+
this.template = template;
|
|
13
|
+
this.options = options;
|
|
14
|
+
this.$ = [...$init];
|
|
15
|
+
}
|
|
16
|
+
/** 放入 $,返回索引 */
|
|
17
|
+
use(value) {
|
|
18
|
+
this.$.push(value);
|
|
19
|
+
return this.$.length - 1;
|
|
20
|
+
}
|
|
21
|
+
/** 构建数组 */
|
|
22
|
+
buildArray(arr) {
|
|
23
|
+
let result = '[';
|
|
24
|
+
for (let i = 0, len = arr.length; i < len; i++) {
|
|
25
|
+
result += this.buildValue(arr[i]);
|
|
26
|
+
result += ',\n';
|
|
27
|
+
}
|
|
28
|
+
result += ']';
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
/** 构建 ArrayBuffer */
|
|
32
|
+
buildArrayBuffer(buffer) {
|
|
33
|
+
const copy = copyArrayBuffer(buffer, 0);
|
|
34
|
+
return `$[${this.use(copy)}].slice(0)`;
|
|
35
|
+
}
|
|
36
|
+
/** 构建 ArrayBufferView */
|
|
37
|
+
buildArrayBufferView(view) {
|
|
38
|
+
const copy = copyArrayBuffer(view.buffer, view.byteOffset, view.byteLength);
|
|
39
|
+
return `new ${view.constructor.name}($[${this.use(copy)}].slice(0))`;
|
|
40
|
+
}
|
|
41
|
+
/** 构建可能为模板的字符串 */
|
|
42
|
+
buildTemplate(value) {
|
|
43
|
+
const template = parseTemplate(value);
|
|
44
|
+
if (typeof template == 'string') {
|
|
45
|
+
return stringify(template);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
return `$[${$unwrapFromVmValue}]($[${this.use(template.value)}](context))`;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** 构建对象 */
|
|
52
|
+
buildObject(obj) {
|
|
53
|
+
let result = '{';
|
|
54
|
+
for (const key in obj) {
|
|
55
|
+
if (!hasOwn(obj, key))
|
|
56
|
+
continue;
|
|
57
|
+
result += '[';
|
|
58
|
+
if (this.options.objectKeyMode === 'ignore') {
|
|
59
|
+
result += stringify(key);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
result += this.buildTemplate(key);
|
|
63
|
+
}
|
|
64
|
+
result += ']:';
|
|
65
|
+
const value = obj[key];
|
|
66
|
+
result += this.buildValue(value);
|
|
67
|
+
result += ',\n';
|
|
68
|
+
}
|
|
69
|
+
result += '}';
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
/** 构建值 */
|
|
73
|
+
buildValue(value) {
|
|
74
|
+
if (value === null)
|
|
75
|
+
return 'null';
|
|
76
|
+
if (value === undefined)
|
|
77
|
+
return 'undefined';
|
|
78
|
+
if (value === true)
|
|
79
|
+
return 'true';
|
|
80
|
+
if (value === false)
|
|
81
|
+
return 'false';
|
|
82
|
+
if (typeof value == 'function')
|
|
83
|
+
return 'undefined';
|
|
84
|
+
if (typeof value == 'symbol')
|
|
85
|
+
return 'undefined';
|
|
86
|
+
if (typeof value == 'bigint')
|
|
87
|
+
return `${value}n`;
|
|
88
|
+
if (typeof value == 'number')
|
|
89
|
+
return String(value);
|
|
90
|
+
if (typeof value == 'string')
|
|
91
|
+
return this.buildTemplate(value);
|
|
92
|
+
/* c8 ignore next */
|
|
93
|
+
if (typeof value != 'object')
|
|
94
|
+
throw new Error(`Unsupported value: ${toString(value)}`);
|
|
95
|
+
if (value instanceof Date)
|
|
96
|
+
return `new Date(${value.getTime()})`;
|
|
97
|
+
if (value instanceof RegExp)
|
|
98
|
+
return value.toString();
|
|
99
|
+
if (isError(value))
|
|
100
|
+
return buildError(value);
|
|
101
|
+
if (isArray(value))
|
|
102
|
+
return this.buildArray(value);
|
|
103
|
+
if (isArrayBuffer(value))
|
|
104
|
+
return this.buildArrayBuffer(value);
|
|
105
|
+
if (isArrayBufferView(value))
|
|
106
|
+
return this.buildArrayBufferView(value);
|
|
107
|
+
return this.buildObject(value);
|
|
108
|
+
}
|
|
109
|
+
/** 构建模板 */
|
|
110
|
+
build() {
|
|
111
|
+
const source = this.buildValue(this.template);
|
|
112
|
+
try {
|
|
113
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval, @typescript-eslint/no-unsafe-call
|
|
114
|
+
const result = new Function('$', [
|
|
115
|
+
`//# sourceURL=cloudpss-template[${seq++}]`, // sourceURL 用于调试
|
|
116
|
+
`return (context) => (${source});`,
|
|
117
|
+
].join('\n'))(this.$);
|
|
118
|
+
return result;
|
|
119
|
+
/* c8 ignore next 3 */
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
throw new Error(`Failed to compile template: ${source}\n${e.message}`, { cause: e });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=compiler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
export type
|
|
3
|
-
|
|
4
|
-
export
|
|
1
|
+
import type { VmContext } from '@mirascript/mirascript';
|
|
2
|
+
export { type VmContext, VmError, VmExtern, VmModule, VmFunction, type VmAny, type VmArray, type VmConst, type VmImmutable, type VmPrimitive, type VmScript, type VmRecord, type VmUninitialized, type VmValue, createVmContext, isVmContext, isVmExtern, isVmModule, isVmFunction, isVmValue, isVmAny, isVmArray, isVmCallable, isVmConst, isVmImmutable, isVmPrimitive, isVmRecord, isVmScript, isVmWrapper, wrapToVmValue, unwrapFromVmValue, configCheckpoint, } from '@mirascript/mirascript';
|
|
3
|
+
/** 模板选项 */
|
|
4
|
+
export interface TemplateOptions {
|
|
5
|
+
/**
|
|
6
|
+
* 对 object key 的处理方式
|
|
7
|
+
* - `template` 使用模板进行插值
|
|
8
|
+
* - `ignore` 原样输出
|
|
9
|
+
* @default 'template'
|
|
10
|
+
*/
|
|
11
|
+
objectKeyMode?: 'template' | 'ignore';
|
|
12
|
+
}
|
|
13
|
+
/** 已编译的模板函数 */
|
|
14
|
+
export type TemplateFunction<T = unknown> = (context?: VmContext) => T;
|
|
15
|
+
/** 创建模板 */
|
|
16
|
+
export declare function template<T = unknown>(template: T, options?: TemplateOptions): TemplateFunction<T>;
|
|
5
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGxD,OAAO,EACH,KAAK,SAAS,EACd,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,KAAK,KAAK,EACV,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,eAAe,EACf,WAAW,EACX,UAAU,EACV,UAAU,EACV,YAAY,EACZ,SAAS,EACT,OAAO,EACP,SAAS,EACT,YAAY,EACZ,SAAS,EACT,aAAa,EACb,aAAa,EACb,UAAU,EACV,UAAU,EACV,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,gBAAgB,GACnB,MAAM,wBAAwB,CAAC;AAEhC,WAAW;AACX,MAAM,WAAW,eAAe;IAC5B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;CACzC;AAED,eAAe;AACf,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,SAAS,KAAK,CAAC,CAAC;AAEvE,WAAW;AACX,wBAAgB,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,GAAE,eAAoB,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAMrG"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
1
|
+
import { TemplateCompiler } from './compiler.js';
|
|
2
|
+
export { VmError, VmExtern, VmModule, VmFunction, createVmContext, isVmContext, isVmExtern, isVmModule, isVmFunction, isVmValue, isVmAny, isVmArray, isVmCallable, isVmConst, isVmImmutable, isVmPrimitive, isVmRecord, isVmScript, isVmWrapper, wrapToVmValue, unwrapFromVmValue, configCheckpoint, } from '@mirascript/mirascript';
|
|
3
|
+
/** 创建模板 */
|
|
4
|
+
export function template(template, options = {}) {
|
|
5
|
+
const opt = {
|
|
6
|
+
objectKeyMode: 'template',
|
|
7
|
+
...options,
|
|
8
|
+
};
|
|
9
|
+
return new TemplateCompiler(template, opt).build();
|
|
10
|
+
}
|
|
3
11
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAEH,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,UAAU,EAUV,eAAe,EACf,WAAW,EACX,UAAU,EACV,UAAU,EACV,YAAY,EACZ,SAAS,EACT,OAAO,EACP,SAAS,EACT,YAAY,EACZ,SAAS,EACT,aAAa,EACb,aAAa,EACb,UAAU,EACV,UAAU,EACV,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,gBAAgB,GACnB,MAAM,wBAAwB,CAAC;AAgBhC,WAAW;AACX,MAAM,UAAU,QAAQ,CAAc,QAAW,EAAE,UAA2B,EAAE;IAC5E,MAAM,GAAG,GAA8B;QACnC,aAAa,EAAE,UAAU;QACzB,GAAG,OAAO;KACb,CAAC;IACF,OAAO,IAAI,gBAAgB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,KAAK,EAAyB,CAAC;AAC9E,CAAC"}
|
package/dist/parser.d.ts
CHANGED
|
@@ -1,28 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
export type FormulaTemplate = {
|
|
3
|
-
type: 'formula';
|
|
4
|
-
value: string;
|
|
5
|
-
};
|
|
6
|
-
/** 字符串插值模板 */
|
|
7
|
-
export type InterpolationTemplate = {
|
|
8
|
-
type: 'interpolation';
|
|
9
|
-
templates: string[];
|
|
10
|
-
values: string[];
|
|
11
|
-
};
|
|
1
|
+
import { type VmScript } from '@mirascript/mirascript';
|
|
12
2
|
/** 字符串模板 */
|
|
13
|
-
export type Template = string |
|
|
3
|
+
export type Template = string | {
|
|
4
|
+
type: TemplateType;
|
|
5
|
+
value: VmScript;
|
|
6
|
+
};
|
|
14
7
|
/** 字符串模板类型 */
|
|
15
|
-
export type TemplateType =
|
|
16
|
-
/**
|
|
17
|
-
* 解析字符串插值模板
|
|
18
|
-
* @example parseInterpolation("hello $name! I am $age years old. I'll be ${age+1} next year. And $(2*age) after $<age> years.")
|
|
19
|
-
* // {
|
|
20
|
-
* // type: 'interpolation',
|
|
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
|
-
* // }
|
|
24
|
-
*/
|
|
25
|
-
export declare function parseInterpolation(template: string, start?: number, length?: number): InterpolationTemplate;
|
|
8
|
+
export type TemplateType = 'interpolation' | 'formula';
|
|
26
9
|
/**
|
|
27
10
|
* 解析字符串模板
|
|
28
11
|
* - 长度大于 1
|
package/dist/parser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAGpE,YAAY;AACZ,MAAM,MAAM,QAAQ,GACd,MAAM,GACN;IACI,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,QAAQ,CAAC;CACnB,CAAC;AAER,cAAc;AACd,MAAM,MAAM,YAAY,GAAG,eAAe,GAAG,SAAS,CAAC;AA2BvD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CASxD"}
|
package/dist/parser.js
CHANGED
|
@@ -1,144 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* 解析字符串插值模板
|
|
27
|
-
* @example parseInterpolationImpl("hello $name! I am $age years old. I'll be ${age+1} next year. Give me $$100.")
|
|
28
|
-
* // {
|
|
29
|
-
* // type: 'interpolation',
|
|
30
|
-
* // templates: ['hello ', '! I am ', ' years old. I\'ll be ', ' next year. Give me $$100.'],
|
|
31
|
-
* // values: ['name', 'age', 'age+1']
|
|
32
|
-
* // }
|
|
33
|
-
*/
|
|
34
|
-
function parseInterpolationImpl(template, start, length) {
|
|
35
|
-
const templates = [];
|
|
36
|
-
const values = [];
|
|
37
|
-
let currentTemplate = '';
|
|
38
|
-
let currentValue = '';
|
|
39
|
-
let expressionComplexDepth = 0;
|
|
40
|
-
let status = PARSER_STATUS_TEXT;
|
|
41
|
-
let complexExpressionStartType = -1;
|
|
42
|
-
const end = start + length - 1;
|
|
43
|
-
for (let i = start; i <= end; i++) {
|
|
44
|
-
if (status === PARSER_STATUS_TEXT) {
|
|
45
|
-
const nextInterpolationChar = template.indexOf(INTERPOLATION_CHAR, i);
|
|
46
|
-
if (nextInterpolationChar < 0 || nextInterpolationChar >= end) {
|
|
47
|
-
// No more interpolation
|
|
48
|
-
currentTemplate += template.slice(i, end + 1);
|
|
49
|
-
break;
|
|
50
|
-
}
|
|
51
|
-
currentTemplate += template.slice(i, nextInterpolationChar);
|
|
52
|
-
i = nextInterpolationChar;
|
|
53
|
-
const nextChar = template.charAt(nextInterpolationChar + 1);
|
|
54
|
-
complexExpressionStartType = INTERPOLATION_EXPRESSION_START.indexOf(nextChar);
|
|
55
|
-
if (complexExpressionStartType >= 0) {
|
|
56
|
-
// Start of complex expression
|
|
57
|
-
templates.push(currentTemplate);
|
|
58
|
-
currentTemplate = '';
|
|
59
|
-
status = PARSER_STATUS_EXPRESSION_COMPLEX;
|
|
60
|
-
expressionComplexDepth = 1;
|
|
61
|
-
i++;
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
if (isIdentifierFirstChar(nextChar)) {
|
|
65
|
-
// Start of simple expression
|
|
66
|
-
templates.push(currentTemplate);
|
|
67
|
-
currentTemplate = '';
|
|
68
|
-
currentValue = nextChar;
|
|
69
|
-
status = PARSER_STATUS_EXPRESSION_SIMPLE;
|
|
70
|
-
i++;
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
// Not an expression
|
|
74
|
-
currentTemplate += INTERPOLATION_CHAR;
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
const char = template.charAt(i);
|
|
78
|
-
if (status === PARSER_STATUS_EXPRESSION_SIMPLE) {
|
|
79
|
-
if (isIdentifierChar(char)) {
|
|
80
|
-
currentValue += char;
|
|
81
|
-
continue;
|
|
82
|
-
}
|
|
83
|
-
// End of expression
|
|
84
|
-
values.push(currentValue);
|
|
85
|
-
currentValue = '';
|
|
86
|
-
status = PARSER_STATUS_TEXT;
|
|
87
|
-
i--;
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
if (status === PARSER_STATUS_EXPRESSION_COMPLEX) {
|
|
91
|
-
if (char === INTERPOLATION_EXPRESSION_START[complexExpressionStartType]) {
|
|
92
|
-
expressionComplexDepth++;
|
|
93
|
-
}
|
|
94
|
-
else if (char === INTERPOLATION_EXPRESSION_END[complexExpressionStartType]) {
|
|
95
|
-
expressionComplexDepth--;
|
|
96
|
-
if (expressionComplexDepth === 0) {
|
|
97
|
-
// End of expression
|
|
98
|
-
values.push(currentValue.trim());
|
|
99
|
-
currentValue = '';
|
|
100
|
-
status = PARSER_STATUS_TEXT;
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
currentValue += char;
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
if (status === PARSER_STATUS_TEXT) {
|
|
109
|
-
templates.push(currentTemplate);
|
|
110
|
-
}
|
|
111
|
-
else if (status === PARSER_STATUS_EXPRESSION_SIMPLE) {
|
|
112
|
-
values.push(currentValue);
|
|
113
|
-
templates.push('');
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
throw new Error('Unexpected end of input');
|
|
117
|
-
}
|
|
118
|
-
return {
|
|
119
|
-
type: 'interpolation',
|
|
120
|
-
templates,
|
|
121
|
-
values,
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* 解析字符串插值模板
|
|
126
|
-
* @example parseInterpolation("hello $name! I am $age years old. I'll be ${age+1} next year. And $(2*age) after $<age> years.")
|
|
127
|
-
* // {
|
|
128
|
-
* // type: 'interpolation',
|
|
129
|
-
* // templates: ['hello ', '! I am ', ' years old. I\'ll be ', ' next year. And ', ' after ', ' years.'],
|
|
130
|
-
* // values: ['name', 'age', 'age+1', '2*age', 'age']
|
|
131
|
-
* // }
|
|
132
|
-
*/
|
|
133
|
-
export function parseInterpolation(template, start, length) {
|
|
134
|
-
start ??= 0;
|
|
135
|
-
length ??= template.length - start;
|
|
136
|
-
if (start < 0 || start > template.length)
|
|
137
|
-
throw new Error('start out of range');
|
|
138
|
-
if (length < 0 || start + length > template.length)
|
|
139
|
-
throw new Error('length out of range');
|
|
140
|
-
return parseInterpolationImpl(template, start, length);
|
|
141
|
-
}
|
|
1
|
+
import { compileSync } from '@mirascript/mirascript';
|
|
2
|
+
import { LRUCache } from 'lru-cache';
|
|
3
|
+
const CACHE_SIZE = 100;
|
|
4
|
+
const formula = new LRUCache({
|
|
5
|
+
max: CACHE_SIZE,
|
|
6
|
+
memoMethod: (template) => {
|
|
7
|
+
const formula = template.slice(1);
|
|
8
|
+
const value = compileSync(formula, { input_mode: 'Script' });
|
|
9
|
+
return {
|
|
10
|
+
type: 'formula',
|
|
11
|
+
value: value,
|
|
12
|
+
};
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
const interpolation = new LRUCache({
|
|
16
|
+
max: CACHE_SIZE,
|
|
17
|
+
memoMethod: (template) => {
|
|
18
|
+
const expr = template.slice(1);
|
|
19
|
+
const value = compileSync(expr, { input_mode: 'Template' });
|
|
20
|
+
return {
|
|
21
|
+
type: 'interpolation',
|
|
22
|
+
value: value,
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
});
|
|
142
26
|
/**
|
|
143
27
|
* 解析字符串模板
|
|
144
28
|
* - 长度大于 1
|
|
@@ -147,21 +31,13 @@ export function parseInterpolation(template, start, length) {
|
|
|
147
31
|
* - 否则表示是一个普通字符串
|
|
148
32
|
*/
|
|
149
33
|
export function parseTemplate(template) {
|
|
150
|
-
if (!template)
|
|
151
|
-
return '';
|
|
152
34
|
if (template.length <= 1)
|
|
153
35
|
return template;
|
|
154
36
|
if (template.startsWith('=')) {
|
|
155
|
-
return
|
|
156
|
-
type: 'formula',
|
|
157
|
-
value: template.slice(1),
|
|
158
|
-
};
|
|
37
|
+
return formula.memo(template);
|
|
159
38
|
}
|
|
160
39
|
if (template.startsWith('$')) {
|
|
161
|
-
|
|
162
|
-
if (result.values.length === 0)
|
|
163
|
-
return result.templates[0];
|
|
164
|
-
return result;
|
|
40
|
+
return interpolation.memo(template);
|
|
165
41
|
}
|
|
166
42
|
return template;
|
|
167
43
|
}
|
package/dist/parser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAiB,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAarC,MAAM,UAAU,GAAG,GAAG,CAAC;AAEvB,MAAM,OAAO,GAAG,IAAI,QAAQ,CAAyC;IACjE,GAAG,EAAE,UAAU;IACf,UAAU,EAAE,CAAC,QAAgB,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC7D,OAAO;YACH,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,KAAK;SACf,CAAC;IACN,CAAC;CACJ,CAAC,CAAC;AACH,MAAM,aAAa,GAAG,IAAI,QAAQ,CAA+C;IAC7E,GAAG,EAAE,UAAU;IACf,UAAU,EAAE,CAAC,QAAgB,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;QAC5D,OAAO;YACH,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,KAAK;SACf,CAAC;IACN,CAAC;CACJ,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC1C,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC1C,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IACD,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,QAAQ,CAAC;AACpB,CAAC"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** 是否为 ArrayBuffer */
|
|
2
|
+
export declare let isArrayBuffer: (value: object) => value is ArrayBuffer | SharedArrayBuffer;
|
|
3
|
+
/** 是否为 Error */
|
|
4
|
+
export declare let isError: (value: unknown) => value is Error;
|
|
5
|
+
declare global {
|
|
6
|
+
/** @inheritdoc */
|
|
7
|
+
interface ErrorConstructor {
|
|
8
|
+
/** @inheritdoc */
|
|
9
|
+
isError?(this: void, value: unknown): value is Error;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Object.prototype.toString.call 的快捷方式
|
|
14
|
+
*/
|
|
15
|
+
export declare const toString: (value: unknown) => string;
|
|
16
|
+
export declare const hasOwn: (o: object, v: PropertyKey) => boolean;
|
|
17
|
+
export declare const isArray: (arg: any) => arg is any[];
|
|
18
|
+
export declare const isArrayBufferView: (arg: any) => arg is ArrayBufferView;
|
|
19
|
+
export declare const stringify: {
|
|
20
|
+
(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
|
|
21
|
+
(value: any, replacer?: (number | string)[] | null, space?: string | number): string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* 获取 ArrayBuffer 的拷贝
|
|
25
|
+
*/
|
|
26
|
+
export declare function copyArrayBuffer(buffer: ArrayBuffer | SharedArrayBuffer, start: number, length?: number): ArrayBuffer;
|
|
27
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,eAAO,IAAI,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,IAAI,WAAW,GAAG,iBAAiB,CAAC;AAEtF,gBAAgB;AAChB,eAAO,IAAI,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,IAAI,KAAK,CAAC;AAEvD,OAAO,CAAC,MAAM,CAAC;IACX,kBAAkB;IAClB,UAAU,gBAAgB;QACtB,kBAAkB;QAClB,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,KAAK,CAAC;KACxD;CACJ;AAqBD;;GAEG;AAEH,eAAO,MAAM,QAAQ,EAAoD,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC;AACpG,eAAO,MAAQ,MAAM,wCAAW,CAAC;AACjC,eAAO,MAAQ,OAAO,4BAAU,CAAC;AACjC,eAAO,MAAM,iBAAiB,sCAAuC,CAAC;AACtE,eAAO,MAAQ,SAAS;;;CAAS,CAAC;AAClC;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,CAIpH"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** 是否为 ArrayBuffer */
|
|
2
|
+
export let isArrayBuffer;
|
|
3
|
+
/** 是否为 Error */
|
|
4
|
+
export let isError;
|
|
5
|
+
if (typeof Error.isError == 'function') {
|
|
6
|
+
isError = Error.isError;
|
|
7
|
+
}
|
|
8
|
+
if (typeof process == 'object' && typeof process.getBuiltinModule == 'function') {
|
|
9
|
+
const typeUtils = process.getBuiltinModule('node:util/types');
|
|
10
|
+
isArrayBuffer = typeUtils.isAnyArrayBuffer;
|
|
11
|
+
isError = typeUtils.isNativeError;
|
|
12
|
+
}
|
|
13
|
+
isError ??= (value) => {
|
|
14
|
+
return value instanceof Error;
|
|
15
|
+
};
|
|
16
|
+
isArrayBuffer ??= (value) => {
|
|
17
|
+
const tag = toString(value);
|
|
18
|
+
return tag === '[object ArrayBuffer]' || tag === '[object SharedArrayBuffer]';
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Object.prototype.toString.call 的快捷方式
|
|
22
|
+
*/
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
24
|
+
export const toString = Function.call.bind(Object.prototype.toString);
|
|
25
|
+
export const { hasOwn } = Object;
|
|
26
|
+
export const { isArray } = Array;
|
|
27
|
+
export const isArrayBufferView = ArrayBuffer.isView.bind(ArrayBuffer);
|
|
28
|
+
export const { stringify } = JSON;
|
|
29
|
+
/**
|
|
30
|
+
* 获取 ArrayBuffer 的拷贝
|
|
31
|
+
*/
|
|
32
|
+
export function copyArrayBuffer(buffer, start, length) {
|
|
33
|
+
const copy = new ArrayBuffer(length ?? buffer.byteLength - start);
|
|
34
|
+
new Uint8Array(copy).set(new Uint8Array(buffer, start, length));
|
|
35
|
+
return copy;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,MAAM,CAAC,IAAI,aAA0E,CAAC;AAEtF,gBAAgB;AAChB,MAAM,CAAC,IAAI,OAA2C,CAAC;AAUvD,IAAI,OAAO,KAAK,CAAC,OAAO,IAAI,UAAU,EAAE,CAAC;IACrC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;AAC5B,CAAC;AAED,IAAI,OAAO,OAAO,IAAI,QAAQ,IAAI,OAAO,OAAO,CAAC,gBAAgB,IAAI,UAAU,EAAE,CAAC;IAC9E,MAAM,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;IAC9D,aAAa,GAAG,SAAS,CAAC,gBAAgB,CAAC;IAC3C,OAAO,GAAG,SAAS,CAAC,aAAa,CAAC;AACtC,CAAC;AAED,OAAO,KAAK,CAAC,KAAc,EAAkB,EAAE;IAC3C,OAAO,KAAK,YAAY,KAAK,CAAC;AAClC,CAAC,CAAC;AAEF,aAAa,KAAK,CAAC,KAAa,EAA4C,EAAE;IAC1E,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5B,OAAO,GAAG,KAAK,sBAAsB,IAAI,GAAG,KAAK,4BAA4B,CAAC;AAClF,CAAC,CAAC;AAEF;;GAEG;AACH,6DAA6D;AAC7D,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAA+B,CAAC;AACpG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;AACjC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;AACjC,MAAM,CAAC,MAAM,iBAAiB,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AACtE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;AAClC;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,MAAuC,EAAE,KAAa,EAAE,MAAe;IACnG,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,GAAG,KAAK,CAAC,CAAC;IAClE,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAChE,OAAO,IAAI,CAAC;AAChB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudpss/template",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.16",
|
|
4
4
|
"author": "CloudPSS",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
"module": "dist/index.js",
|
|
14
14
|
"types": "dist/index.d.ts",
|
|
15
15
|
"exports": "./dist/index.js",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@mirascript/mirascript": "^0.1.39",
|
|
18
|
+
"lru-cache": "^11.2.4"
|
|
19
|
+
},
|
|
16
20
|
"scripts": {
|
|
17
21
|
"build": "pnpm clean && tsc --build --force",
|
|
18
22
|
"clean": "rimraf dist",
|
package/src/builder.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { stringify } from './utils.js';
|
|
2
|
+
|
|
3
|
+
const KNOWN_ERRORS = [EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError] as const;
|
|
4
|
+
|
|
5
|
+
/** 构建 Error */
|
|
6
|
+
export function buildError(err: Error): string {
|
|
7
|
+
if (typeof DOMException == 'function' && err instanceof DOMException) {
|
|
8
|
+
return `new DOMException(${stringify(err.message)}, ${stringify(err.name)})`;
|
|
9
|
+
}
|
|
10
|
+
const constructor = KNOWN_ERRORS.find((type) => err instanceof type)?.name ?? 'Error';
|
|
11
|
+
if (err.name === constructor) {
|
|
12
|
+
return `new ${constructor}(${stringify(err.message)})`;
|
|
13
|
+
}
|
|
14
|
+
return `Object.assign(new ${constructor}(${stringify(err.message)}), {name: ${stringify(err.name)}})`;
|
|
15
|
+
}
|