@cloudpss/template 0.6.15 → 0.6.17

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.
@@ -1,168 +0,0 @@
1
- import { parseTemplate } from '../parser.js';
2
- /** 是否为 ArrayBuffer */
3
- function isArrayBuffer(value) {
4
- if (value instanceof ArrayBuffer)
5
- return true;
6
- if (typeof SharedArrayBuffer == 'function' && value instanceof SharedArrayBuffer)
7
- return true;
8
- return false;
9
- }
10
- /** 是否为 Error */
11
- function isError(value) {
12
- return value instanceof Error || (typeof DOMException == 'function' && value instanceof DOMException);
13
- }
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;
18
- /** 模板序列号 */
19
- let seq = 0;
20
- /** 创建模板 */
21
- export class TemplateCompiler {
22
- constructor(template, options) {
23
- this.template = template;
24
- this.options = options;
25
- this.params = new Map();
26
- this.copyable = [];
27
- }
28
- /** 构建求值 */
29
- buildEval(expression, type) {
30
- const { evaluator } = this.options;
31
- if (!this.params.has('evaluator')) {
32
- this.params.set('evaluator', evaluator.inject);
33
- }
34
- return evaluator.compile(expression, type);
35
- }
36
- /** 构建字符串 */
37
- buildString(str) {
38
- const parsed = parseTemplate(str);
39
- if (typeof parsed === 'string')
40
- return [JSON.stringify(parsed), false];
41
- if (parsed.type === 'formula')
42
- return [this.buildEval(parsed.value, parsed.type), true];
43
- let result = '';
44
- for (let i = 0; i < parsed.templates.length; i++) {
45
- if (parsed.templates[i]) {
46
- result += (result ? '+' : '') + JSON.stringify(parsed.templates[i]);
47
- }
48
- if (i < parsed.values.length) {
49
- if (!result)
50
- result = '""';
51
- result += '+' + this.buildEval(parsed.values[i], parsed.type);
52
- }
53
- }
54
- return [result, true];
55
- }
56
- /** 构建 Error */
57
- buildError(err) {
58
- if (typeof DOMException == 'function' && err instanceof DOMException) {
59
- return `new DOMException(${this.buildString(err.message)[0]}, ${this.buildString(err.name)[0]})`;
60
- }
61
- const constructor = KNOWN_ERRORS.find((type) => err instanceof type)?.name ?? 'Error';
62
- if (err.name === constructor) {
63
- return `new ${constructor}(${this.buildString(err.message)[0]})`;
64
- }
65
- return `Object.assign(new ${constructor}(${this.buildString(err.message)[0]}), {name: ${this.buildString(err.name)[0]}})`;
66
- }
67
- /** 构建数组 */
68
- buildArray(arr) {
69
- return `[${arr.map(this.buildValue.bind(this)).join(',\n')}]`;
70
- }
71
- /** 构建 ArrayBuffer */
72
- buildArrayBuffer(buffer) {
73
- this.copyable.push(buffer.slice(0));
74
- return `copyable[${this.copyable.length - 1}].slice(0)`;
75
- }
76
- /** 构建 ArrayBufferView */
77
- buildArrayBufferView(view) {
78
- this.copyable.push(view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength));
79
- return `new ${view.constructor.name}(copyable[${this.copyable.length - 1}].slice(0))`;
80
- }
81
- /** 构建对象 */
82
- buildObject(obj) {
83
- let result = '';
84
- for (const key in obj) {
85
- if (!hasOwn(obj, key))
86
- continue;
87
- const value = obj[key];
88
- if (result)
89
- result += ',\n';
90
- if (this.options.objectKeyMode === 'ignore') {
91
- result += JSON.stringify(key);
92
- }
93
- else {
94
- const [e, isExpression] = this.buildString(key);
95
- if (isExpression) {
96
- result += '[' + e + ']';
97
- }
98
- else {
99
- result += e;
100
- }
101
- }
102
- result += ':';
103
- result += this.buildValue(value);
104
- }
105
- return '{' + result + '}';
106
- }
107
- /** 构建值 */
108
- buildValue(value) {
109
- if (value === null)
110
- return 'null';
111
- if (value === undefined)
112
- return 'undefined';
113
- if (value === true)
114
- return 'true';
115
- if (value === false)
116
- return 'false';
117
- if (typeof value == 'function')
118
- return 'undefined';
119
- if (typeof value == 'symbol')
120
- return 'undefined';
121
- if (typeof value == 'bigint')
122
- return `${value}n`;
123
- if (typeof value == 'number')
124
- return String(value);
125
- if (typeof value == 'string')
126
- return this.buildString(value)[0];
127
- /* c8 ignore next */
128
- if (typeof value != 'object')
129
- throw new Error(`Unsupported value: ${toString(value)}`);
130
- if (value instanceof Date)
131
- return `new Date(${value.getTime()})`;
132
- if (value instanceof RegExp)
133
- return value.toString();
134
- if (isError(value))
135
- return this.buildError(value);
136
- if (Array.isArray(value))
137
- return this.buildArray(value);
138
- if (isArrayBuffer(value))
139
- return this.buildArrayBuffer(value);
140
- if (ArrayBuffer.isView(value))
141
- return this.buildArrayBufferView(value);
142
- return this.buildObject(value);
143
- }
144
- /** 构建模板 */
145
- build() {
146
- const source = this.buildValue(this.template);
147
- if (this.copyable.length) {
148
- this.params.set('copyable', this.copyable);
149
- }
150
- const params = [...this.params];
151
- try {
152
- // eslint-disable-next-line @typescript-eslint/no-implied-eval, @typescript-eslint/no-unsafe-call
153
- const result = new Function(...params.map(([key]) => key), [
154
- `//# sourceURL=cloudpss-template[${seq++}]`, // sourceURL 用于调试
155
- this.options.evaluator.async
156
- ? `return async (context = {}) => (${source});`
157
- : `return (context = {}) => (${source});`,
158
- ].join('\n'))(...params.map(([, value]) => value));
159
- defineProperty(result, 'source', { value: source, configurable: true });
160
- return result;
161
- /* c8 ignore next 3 */
162
- }
163
- catch (e) {
164
- throw new Error(`Failed to compile template: ${source}\n${e.message}`, { cause: e });
165
- }
166
- }
167
- }
168
- //# sourceMappingURL=compiler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../src/template/compiler.ts"],"names":[],"mappings":"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"}
@@ -1,42 +0,0 @@
1
- import type { TemplateType } from '../parser.js';
2
- /** 模板编译求值 */
3
- export type TemplateEvaluator = {
4
- /** 注入为 `evaluator` 变量,可在生成的求值代码中使用 */
5
- inject?: unknown;
6
- /**
7
- * 求值代码是否为异步
8
- * @default false
9
- */
10
- async?: boolean;
11
- /** 生成求值 JS 代码,可用变量:`evaluator` `context` */
12
- compile: (expression: string, type: TemplateType) => string;
13
- };
14
- /** 模板选项 */
15
- export interface TemplateOptions {
16
- /**
17
- * 模板求值器
18
- * @default context?.[expression] ?? (type === 'formula' ? undefined : '')
19
- */
20
- evaluator?: TemplateEvaluator;
21
- /**
22
- * 对 object key 的处理方式
23
- * - `template` 使用模板进行插值
24
- * - `ignore` 原样输出
25
- * @default 'template'
26
- */
27
- objectKeyMode?: 'template' | 'ignore';
28
- }
29
- export declare const defaultEvaluator: TemplateEvaluator;
30
- /** 已编译的模板函数 */
31
- export type TemplateFunction<T = unknown, C = Record<string, unknown>> = ((context?: C) => T) & {
32
- source: string;
33
- };
34
- /** 创建模板 */
35
- export declare function template<T = unknown, C = Record<string, unknown>>(template: T, options: TemplateOptions & {
36
- evaluator: {
37
- async: true;
38
- };
39
- }): TemplateFunction<Promise<T>, C>;
40
- /** 创建模板 */
41
- export declare function template<T = unknown, C = Record<string, unknown>>(template: T, options?: TemplateOptions): TemplateFunction<T, C>;
42
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/template/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD,aAAa;AACb,MAAM,MAAM,iBAAiB,GAAG;IAC5B,sCAAsC;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4CAA4C;IAC5C,OAAO,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,KAAK,MAAM,CAAC;CAC/D,CAAC;AAEF,WAAW;AACX,MAAM,WAAW,eAAe;IAC5B;;;OAGG;IACH,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;CACzC;AAED,eAAO,MAAM,gBAAgB,EAAE,iBAa9B,CAAC;AAEF,eAAe;AACf,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG;IAC5F,MAAM,EAAE,MAAM,CAAC;CAClB,CAAC;AACF,WAAW;AACX,wBAAgB,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7D,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,eAAe,GAAG;IAAE,SAAS,EAAE;QAAE,KAAK,EAAE,IAAI,CAAA;KAAE,CAAA;CAAE,GAC1D,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACnC,WAAW;AACX,wBAAgB,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7D,QAAQ,EAAE,CAAC,EACX,OAAO,CAAC,EAAE,eAAe,GAC1B,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC"}
@@ -1,25 +0,0 @@
1
- import { TemplateCompiler } from './compiler.js';
2
- export const defaultEvaluator = {
3
- compile: (expression, type) => {
4
- const key = JSON.stringify(expression.trim());
5
- switch (type) {
6
- case 'formula':
7
- return `context[${key}]`;
8
- case 'interpolation':
9
- return `(context[${key}] ?? '')`;
10
- /* c8 ignore next 2 */
11
- default:
12
- throw new Error(`Unsupported type: ${type}`);
13
- }
14
- },
15
- };
16
- /** 创建模板 */
17
- export function template(template, options = {}) {
18
- const opt = {
19
- objectKeyMode: 'template',
20
- evaluator: defaultEvaluator,
21
- ...options,
22
- };
23
- return new TemplateCompiler(template, opt).build();
24
- }
25
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/template/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AA+BjD,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"}
@@ -1,151 +0,0 @@
1
- import { parseTemplate, type TemplateType } from '../parser.js';
2
- import type { TemplateFunction, TemplateOptions } from './index.js';
3
-
4
- /** 是否为 ArrayBuffer */
5
- function isArrayBuffer(value: object): value is ArrayBuffer | SharedArrayBuffer {
6
- if (value instanceof ArrayBuffer) return true;
7
- if (typeof SharedArrayBuffer == 'function' && value instanceof SharedArrayBuffer) return true;
8
- return false;
9
- }
10
-
11
- /** 是否为 Error */
12
- function isError(value: unknown): value is Error {
13
- return value instanceof Error || (typeof DOMException == 'function' && value instanceof DOMException);
14
- }
15
-
16
- const KNOWN_ERRORS = [EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError] as const;
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
-
22
- /** 模板序列号 */
23
- let seq = 0;
24
-
25
- /** 创建模板 */
26
- export class TemplateCompiler {
27
- constructor(
28
- readonly template: unknown,
29
- readonly options: Required<TemplateOptions>,
30
- ) {}
31
- private readonly params = new Map<string, unknown>();
32
- private readonly copyable: unknown[] = [];
33
- /** 构建求值 */
34
- private buildEval(expression: string, type: TemplateType): string {
35
- const { evaluator } = this.options;
36
- if (!this.params.has('evaluator')) {
37
- this.params.set('evaluator', evaluator.inject);
38
- }
39
- return evaluator.compile(expression, type);
40
- }
41
- /** 构建字符串 */
42
- private buildString(str: string): [result: string, isExpression: boolean] {
43
- const parsed = parseTemplate(str);
44
- if (typeof parsed === 'string') return [JSON.stringify(parsed), false];
45
- if (parsed.type === 'formula') return [this.buildEval(parsed.value, parsed.type), true];
46
- let result = '';
47
- for (let i = 0; i < parsed.templates.length; i++) {
48
- if (parsed.templates[i]) {
49
- result += (result ? '+' : '') + JSON.stringify(parsed.templates[i]!);
50
- }
51
- if (i < parsed.values.length) {
52
- if (!result) result = '""';
53
- result += '+' + this.buildEval(parsed.values[i]!, parsed.type);
54
- }
55
- }
56
- return [result, true];
57
- }
58
- /** 构建 Error */
59
- private buildError(err: Error): string {
60
- if (typeof DOMException == 'function' && err instanceof DOMException) {
61
- return `new DOMException(${this.buildString(err.message)[0]}, ${this.buildString(err.name)[0]})`;
62
- }
63
- const constructor = KNOWN_ERRORS.find((type) => err instanceof type)?.name ?? 'Error';
64
- if (err.name === constructor) {
65
- return `new ${constructor}(${this.buildString(err.message)[0]})`;
66
- }
67
- return `Object.assign(new ${constructor}(${this.buildString(err.message)[0]}), {name: ${this.buildString(err.name)[0]}})`;
68
- }
69
- /** 构建数组 */
70
- private buildArray(arr: unknown[]): string {
71
- return `[${arr.map(this.buildValue.bind(this)).join(',\n')}]`;
72
- }
73
- /** 构建 ArrayBuffer */
74
- private buildArrayBuffer(buffer: ArrayBuffer | SharedArrayBuffer): string {
75
- this.copyable.push(buffer.slice(0));
76
- return `copyable[${this.copyable.length - 1}].slice(0)`;
77
- }
78
- /** 构建 ArrayBufferView */
79
- private buildArrayBufferView(view: ArrayBufferView): string {
80
- this.copyable.push(view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength));
81
- return `new ${view.constructor.name}(copyable[${this.copyable.length - 1}].slice(0))`;
82
- }
83
- /** 构建对象 */
84
- private buildObject(obj: Record<string, unknown>): string {
85
- let result = '';
86
- for (const key in obj) {
87
- if (!hasOwn(obj, key)) continue;
88
- const value = obj[key];
89
- if (result) result += ',\n';
90
- if (this.options.objectKeyMode === 'ignore') {
91
- result += JSON.stringify(key);
92
- } else {
93
- const [e, isExpression] = this.buildString(key);
94
- if (isExpression) {
95
- result += '[' + e + ']';
96
- } else {
97
- result += e;
98
- }
99
- }
100
- result += ':';
101
- result += this.buildValue(value);
102
- }
103
- return '{' + result + '}';
104
- }
105
- /** 构建值 */
106
- private buildValue(value: unknown): string {
107
- if (value === null) return 'null';
108
- if (value === undefined) return 'undefined';
109
- if (value === true) return 'true';
110
- if (value === false) return 'false';
111
- if (typeof value == 'function') return 'undefined';
112
- if (typeof value == 'symbol') return 'undefined';
113
- if (typeof value == 'bigint') return `${value}n`;
114
- if (typeof value == 'number') return String(value);
115
- if (typeof value == 'string') return this.buildString(value)[0];
116
- /* c8 ignore next */
117
- if (typeof value != 'object') throw new Error(`Unsupported value: ${toString(value)}`);
118
- if (value instanceof Date) return `new Date(${value.getTime()})`;
119
- if (value instanceof RegExp) return value.toString();
120
- if (isError(value)) return this.buildError(value);
121
- if (Array.isArray(value)) return this.buildArray(value);
122
- if (isArrayBuffer(value)) return this.buildArrayBuffer(value);
123
- if (ArrayBuffer.isView(value)) return this.buildArrayBufferView(value);
124
- return this.buildObject(value as Record<string, unknown>);
125
- }
126
- /** 构建模板 */
127
- build(): TemplateFunction {
128
- const source = this.buildValue(this.template);
129
- if (this.copyable.length) {
130
- this.params.set('copyable', this.copyable);
131
- }
132
- const params = [...this.params];
133
- try {
134
- // eslint-disable-next-line @typescript-eslint/no-implied-eval, @typescript-eslint/no-unsafe-call
135
- const result = new Function(
136
- ...params.map(([key]) => key),
137
- [
138
- `//# sourceURL=cloudpss-template[${seq++}]`, // sourceURL 用于调试
139
- this.options.evaluator.async
140
- ? `return async (context = {}) => (${source});`
141
- : `return (context = {}) => (${source});`,
142
- ].join('\n'),
143
- )(...params.map(([, value]) => value)) as TemplateFunction;
144
- defineProperty(result, 'source', { value: source, configurable: true });
145
- return result;
146
- /* c8 ignore next 3 */
147
- } catch (e) {
148
- throw new Error(`Failed to compile template: ${source}\n${(e as Error).message}`, { cause: e });
149
- }
150
- }
151
- }
@@ -1,74 +0,0 @@
1
- import type { TemplateType } from '../parser.js';
2
- import { TemplateCompiler } from './compiler.js';
3
-
4
- /** 模板编译求值 */
5
- export type TemplateEvaluator = {
6
- /** 注入为 `evaluator` 变量,可在生成的求值代码中使用 */
7
- inject?: unknown;
8
- /**
9
- * 求值代码是否为异步
10
- * @default false
11
- */
12
- async?: boolean;
13
- /** 生成求值 JS 代码,可用变量:`evaluator` `context` */
14
- compile: (expression: string, type: TemplateType) => string;
15
- };
16
-
17
- /** 模板选项 */
18
- export interface TemplateOptions {
19
- /**
20
- * 模板求值器
21
- * @default context?.[expression] ?? (type === 'formula' ? undefined : '')
22
- */
23
- evaluator?: TemplateEvaluator;
24
- /**
25
- * 对 object key 的处理方式
26
- * - `template` 使用模板进行插值
27
- * - `ignore` 原样输出
28
- * @default 'template'
29
- */
30
- objectKeyMode?: 'template' | 'ignore';
31
- }
32
-
33
- export const defaultEvaluator: TemplateEvaluator = {
34
- compile: (expression, type) => {
35
- const key = JSON.stringify(expression.trim());
36
- switch (type) {
37
- case 'formula':
38
- return `context[${key}]`;
39
- case 'interpolation':
40
- return `(context[${key}] ?? '')`;
41
- /* c8 ignore next 2 */
42
- default:
43
- throw new Error(`Unsupported type: ${type satisfies never as string}`);
44
- }
45
- },
46
- };
47
-
48
- /** 已编译的模板函数 */
49
- export type TemplateFunction<T = unknown, C = Record<string, unknown>> = ((context?: C) => T) & {
50
- source: string;
51
- };
52
- /** 创建模板 */
53
- export function template<T = unknown, C = Record<string, unknown>>(
54
- template: T,
55
- options: TemplateOptions & { evaluator: { async: true } },
56
- ): TemplateFunction<Promise<T>, C>;
57
- /** 创建模板 */
58
- export function template<T = unknown, C = Record<string, unknown>>(
59
- template: T,
60
- options?: TemplateOptions,
61
- ): TemplateFunction<T, C>;
62
-
63
- /** 创建模板 */
64
- export function template<T = unknown, C = Record<string, unknown>>(
65
- template: T,
66
- options: TemplateOptions = {},
67
- ): TemplateFunction<T, C> {
68
- const opt = {
69
- objectKeyMode: 'template',
70
- evaluator: defaultEvaluator,
71
- ...options,
72
- };
73
- return new TemplateCompiler(template, opt as Required<TemplateOptions>).build() as TemplateFunction<T, C>;
74
- }