amis 1.9.1-beta.11 → 1.9.1-beta.12
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/RootRenderer.js +14 -0
- package/lib/RootRenderer.js.map +2 -2
- package/lib/SchemaRenderer.js +8 -3
- package/lib/SchemaRenderer.js.map +2 -2
- package/lib/components/Alert2.d.ts +10 -10
- package/lib/components/DateRangePicker.js +11 -9
- package/lib/components/DateRangePicker.js.map +2 -2
- package/lib/components/SearchBox.d.ts +40 -40
- package/lib/components/Select.d.ts +193 -193
- package/lib/components/Select.js +2 -4
- package/lib/components/Select.js.map +2 -2
- package/lib/components/virtual-list/index.js +1 -1
- package/lib/components/virtual-list/index.js.map +1 -1
- package/lib/index.js +1 -1
- package/lib/locale/de-DE.js +1 -0
- package/lib/locale/de-DE.js.map +2 -2
- package/lib/locale/en-US.js +1 -0
- package/lib/locale/en-US.js.map +2 -2
- package/lib/locale/zh-CN.js +5 -2
- package/lib/locale/zh-CN.js.map +2 -2
- package/lib/renderers/Action.d.ts +6 -0
- package/lib/renderers/Action.js.map +2 -2
- package/lib/renderers/CRUD.js +2 -1
- package/lib/renderers/CRUD.js.map +2 -2
- package/lib/renderers/Card.js +5 -4
- package/lib/renderers/Card.js.map +2 -2
- package/lib/renderers/Carousel.d.ts +1 -1
- package/lib/renderers/Carousel.js +5 -1
- package/lib/renderers/Carousel.js.map +2 -2
- package/lib/renderers/Form/InputImage.js +1 -1
- package/lib/renderers/Form/InputImage.js.map +2 -2
- package/lib/renderers/Form/InputText.js +1 -1
- package/lib/renderers/Form/InputText.js.map +2 -2
- package/lib/renderers/Form/Options.js +1 -0
- package/lib/renderers/Form/Options.js.map +2 -2
- package/lib/renderers/Form/Select.d.ts +12 -0
- package/lib/renderers/Form/Select.js +1 -3
- package/lib/renderers/Form/Select.js.map +2 -2
- package/lib/renderers/Form/wrapControl.js +72 -19
- package/lib/renderers/Form/wrapControl.js.map +2 -2
- package/lib/renderers/Service.js +1 -0
- package/lib/renderers/Service.js.map +2 -2
- package/lib/renderers/Table/TableContent.d.ts +2 -2
- package/lib/renderers/Table/TableContent.js +4 -16
- package/lib/renderers/Table/TableContent.js.map +2 -2
- package/lib/renderers/Table/index.d.ts +2 -5
- package/lib/renderers/Table/index.js +2 -2
- package/lib/renderers/Table/index.js.map +2 -2
- package/lib/store/table.js +7 -3
- package/lib/store/table.js.map +2 -2
- package/lib/themes/ang-ie11.css +0 -1
- package/lib/themes/ang.css +0 -1
- package/lib/themes/ang.css.map +1 -1
- package/lib/themes/antd-ie11.css +0 -1
- package/lib/themes/antd.css +0 -1
- package/lib/themes/antd.css.map +1 -1
- package/lib/themes/cxd-ie11.css +8 -1
- package/lib/themes/cxd.css +8 -1
- package/lib/themes/cxd.css.map +1 -1
- package/lib/themes/dark-ie11.css +0 -1
- package/lib/themes/dark.css +0 -1
- package/lib/themes/dark.css.map +1 -1
- package/lib/themes/default-ie11.css +8 -1
- package/lib/themes/default.css +8 -1
- package/lib/themes/default.css.map +1 -1
- package/lib/types.d.ts +1 -1
- package/lib/types.js.map +1 -1
- package/lib/utils/formula.d.ts +16 -0
- package/lib/utils/formula.js +207 -0
- package/lib/utils/formula.js.map +13 -0
- package/lib/utils/grammar.d.ts +4 -0
- package/lib/utils/grammar.js +47 -0
- package/lib/utils/grammar.js.map +13 -0
- package/lib/utils/helper.js +1 -0
- package/lib/utils/helper.js.map +2 -2
- package/lib/utils/tpl.js +3 -0
- package/lib/utils/tpl.js.map +2 -2
- package/package.json +1 -1
- package/schema.json +278 -222
- package/scss/components/_collapse.scss +1 -1
- package/scss/themes/cxd.scss +12 -0
- package/sdk/ang-ie11.css +0 -1
- package/sdk/ang.css +0 -1
- package/sdk/antd-ie11.css +0 -1
- package/sdk/antd.css +0 -1
- package/sdk/barcode.js +51 -51
- package/sdk/charts.js +14 -14
- package/sdk/codemirror.js +7 -7
- package/sdk/color-picker.js +65 -65
- package/sdk/cropperjs.js +2 -2
- package/sdk/cxd-ie11.css +9 -1
- package/sdk/cxd.css +9 -1
- package/sdk/dark-ie11.css +0 -1
- package/sdk/dark.css +0 -1
- package/sdk/exceljs.js +1 -1
- package/sdk/locale/de-DE.js +1 -0
- package/sdk/markdown.js +69 -69
- package/sdk/papaparse.js +1 -1
- package/sdk/renderers/Form/CityDB.js +1 -1
- package/sdk/rest.js +16 -16
- package/sdk/rich-text.js +62 -62
- package/sdk/sdk-ie11.css +9 -1
- package/sdk/sdk.css +9 -1
- package/sdk/sdk.js +1695 -1665
- package/sdk/thirds/hls.js/hls.js +1 -1
- package/sdk/thirds/mpegts.js/mpegts.js +1 -1
- package/sdk/tinymce.js +57 -57
- package/src/RootRenderer.tsx +14 -0
- package/src/SchemaRenderer.tsx +4 -2
- package/src/components/DateRangePicker.tsx +73 -60
- package/src/components/Select.tsx +2 -4
- package/src/components/virtual-list/index.tsx +1 -1
- package/src/locale/de-DE.ts +1 -0
- package/src/locale/en-US.ts +1 -0
- package/src/locale/zh-CN.ts +5 -2
- package/src/renderers/Action.tsx +8 -0
- package/src/renderers/CRUD.tsx +2 -1
- package/src/renderers/Card.tsx +10 -5
- package/src/renderers/Carousel.tsx +10 -4
- package/src/renderers/Form/InputImage.tsx +1 -1
- package/src/renderers/Form/InputText.tsx +1 -0
- package/src/renderers/Form/Options.tsx +1 -0
- package/src/renderers/Form/Select.tsx +13 -3
- package/src/renderers/Form/wrapControl.tsx +90 -22
- package/src/renderers/Service.tsx +1 -0
- package/src/renderers/Table/TableContent.tsx +22 -34
- package/src/renderers/Table/index.tsx +4 -8
- package/src/store/table.ts +10 -3
- package/src/types.ts +1 -0
- package/src/utils/formula.ts +240 -0
- package/src/utils/grammar.ts +53 -0
- package/src/utils/helper.ts +2 -1
- package/src/utils/tpl.ts +2 -0
package/lib/types.d.ts
CHANGED
@@ -75,7 +75,7 @@ export interface Definitions {
|
|
75
75
|
[propName: string]: SchemaNode;
|
76
76
|
}
|
77
77
|
export interface Action extends Button {
|
78
|
-
actionType?: 'submit' | 'copy' | 'reload' | 'ajax' | 'dialog' | 'drawer' | 'jump' | 'link' | 'url' | 'email' | 'close' | 'confirm' | 'add' | 'remove' | 'delete' | 'edit' | 'cancel' | 'next' | 'prev' | 'reset' | 'validate' | 'reset-and-submit' | 'clear' | 'clear-and-submit' | 'toast' | 'goto-step' | 'goto-image' | 'expand' | 'collapse' | 'step-submit' | 'selectAll' | 'changeTabKey';
|
78
|
+
actionType?: 'submit' | 'copy' | 'reload' | 'ajax' | 'saveAs' | 'dialog' | 'drawer' | 'jump' | 'link' | 'url' | 'email' | 'close' | 'confirm' | 'add' | 'remove' | 'delete' | 'edit' | 'cancel' | 'next' | 'prev' | 'reset' | 'validate' | 'reset-and-submit' | 'clear' | 'clear-and-submit' | 'toast' | 'goto-step' | 'goto-image' | 'expand' | 'collapse' | 'step-submit' | 'selectAll' | 'changeTabKey';
|
79
79
|
api?: Api;
|
80
80
|
asyncApi?: Api;
|
81
81
|
payload?: any;
|
package/lib/types.js.map
CHANGED
@@ -8,6 +8,6 @@
|
|
8
8
|
"names": [],
|
9
9
|
"mappings": "",
|
10
10
|
"sourcesContent": [
|
11
|
-
"import type {ActionSchema} from './renderers/Action';\nimport {SchemaApiObject} from './Schema';\n\nexport interface ApiObject extends SchemaApiObject {\n config?: {\n withCredentials?: boolean;\n cancelExecutor?: (cancel: Function) => void;\n };\n graphql?: string;\n operationName?: string;\n body?: PlainObject;\n query?: PlainObject;\n adaptor?: (payload: object, response: fetcherResult, api: ApiObject) => any;\n requestAdaptor?: (api: ApiObject) => ApiObject;\n}\nexport type ApiString = string;\nexport type Api = ApiString | ApiObject;\n\nexport interface fetcherResult {\n data?: {\n data: object;\n status: number;\n msg: string;\n msgTimeout?: number;\n errors?: {\n [propName: string]: string;\n };\n type?: string;\n [propName: string]: any; // 为了兼容其他返回格式\n };\n status: number;\n headers: object;\n}\n\nexport interface fetchOptions {\n method?: 'get' | 'post' | 'put' | 'patch' | 'delete' | 'jsonp';\n successMessage?: string;\n errorMessage?: string;\n autoAppend?: boolean;\n beforeSend?: (data: any) => any;\n onSuccess?: (json: Payload) => any;\n onFailed?: (json: Payload) => any;\n silent?: boolean;\n [propName: string]: any;\n}\n\nexport interface Payload {\n ok: boolean;\n msg: string;\n msgTimeout?: number;\n data: any;\n status: number;\n errors?: {\n [propName: string]: string;\n };\n}\n\nexport interface Schema {\n type: string;\n detectField?: string;\n visibleOn?: string;\n hiddenOn?: string;\n children?: JSX.Element | ((props: any, schema?: any) => JSX.Element) | null;\n definitions?: Definitions;\n [propName: string]: any;\n}\n\nexport interface Button {\n type: 'submit' | 'button' | 'reset';\n label?: string;\n icon?: string;\n size?: string;\n disabled?: boolean;\n className?: string;\n}\n\nexport type SchemaNode = Schema | string | Array<Schema | string>;\nexport interface SchemaArray extends Array<SchemaNode> {}\nexport interface Definitions {\n [propName: string]: SchemaNode;\n}\nexport interface Action extends Button {\n actionType?:\n | 'submit'\n | 'copy'\n | 'reload'\n | 'ajax'\n | 'dialog'\n | 'drawer'\n | 'jump'\n | 'link'\n | 'url'\n | 'email'\n | 'close'\n | 'confirm'\n | 'add'\n | 'remove'\n | 'delete'\n | 'edit'\n | 'cancel'\n | 'next'\n | 'prev'\n | 'reset'\n | 'validate'\n | 'reset-and-submit'\n | 'clear'\n | 'clear-and-submit'\n | 'toast'\n | 'goto-step'\n | 'goto-image'\n | 'expand'\n | 'collapse'\n | 'step-submit'\n | 'selectAll'\n | 'changeTabKey';\n api?: Api;\n asyncApi?: Api;\n payload?: any;\n dialog?: SchemaNode;\n to?: string;\n target?: string;\n link?: string;\n url?: string;\n cc?: string;\n bcc?: string;\n subject?: string;\n body?: string;\n mergeData?: boolean;\n reload?: string;\n messages?: {\n success?: string;\n failed?: string;\n };\n feedback?: any;\n required?: Array<string>;\n [propName: string]: any;\n}\n\nexport interface Location {\n pathname: string;\n search: string;\n state: any;\n hash: string;\n key?: string;\n query?: any;\n}\n\nexport interface PlainObject {\n [propsName: string]: any;\n}\n\nexport interface RendererData {\n [propsName: string]: any;\n __prev?: RendererDataAlias;\n __super?: RendererData;\n}\ntype RendererDataAlias = RendererData;\n\nexport type FunctionPropertyNames<T> = {\n [K in keyof T]: T[K] extends Function ? K : never;\n}[keyof T];\n\nexport interface JSONSchema {\n [propsName: string]: any;\n}\n\n// export type Omit<T, K extends keyof T & any> = Pick<T, Exclude<keyof T, K>>;\n// export type Override<M, N> = Omit<M, Extract<keyof M, keyof N>> & N;\n// export type ExtractProps<\n// TComponentOrTProps\n// > = TComponentOrTProps extends React.ComponentType<infer P> ? P : never;\n\n/**\n * 事件跟踪的定义\n */\nexport interface EventTrack {\n /**\n * 事件类型,目前有以下几种\n *\n * api: 所有 fetcher 前调用\n * url: 打开外部链接,组件有可能是 action 也有可能是 link\n * link: 打开内部链接\n * dialog: action 的弹框\n * drawer: action 的抽出式弹框\n * copy: action 里的复制\n * reload: action 里的 reload\n * email: action 里的 email\n * prev: action 里的 prev\n * next: action 里的 next\n * cancel: action 里的 cancel\n * close: action 里的 close\n * submit: 有可能是 action 里的 submit,也有可能是表单提交\n * confirm: action 里的 confirm\n * add: action 里的 add\n * reset: action 里的 reset\n * reset-and-submit: action 里的 reset-and-submit\n * formItemChange: 表单项内容变化\n * formError: 表单验证失败\n * formSubmit: 表单成功提交,在表单验证成功之后才会触发,这个可能会和 api 重合\n * tabChange: tab 切换\n * netError: api 报错\n */\n eventType:\n | 'api'\n | 'url'\n | 'link'\n | 'dialog'\n | 'drawer'\n | 'copy'\n | 'reload'\n | 'email'\n | 'prev'\n | 'next'\n | 'cancel'\n | 'close'\n | 'submit'\n | 'confirm'\n | 'reset'\n | 'reset-and-submit'\n | 'formItemChange'\n | 'tabChange';\n\n /**\n * 事件数据\n */\n eventData: ActionSchema | Api;\n}\n"
|
11
|
+
"import type {ActionSchema} from './renderers/Action';\nimport {SchemaApiObject} from './Schema';\n\nexport interface ApiObject extends SchemaApiObject {\n config?: {\n withCredentials?: boolean;\n cancelExecutor?: (cancel: Function) => void;\n };\n graphql?: string;\n operationName?: string;\n body?: PlainObject;\n query?: PlainObject;\n adaptor?: (payload: object, response: fetcherResult, api: ApiObject) => any;\n requestAdaptor?: (api: ApiObject) => ApiObject;\n}\nexport type ApiString = string;\nexport type Api = ApiString | ApiObject;\n\nexport interface fetcherResult {\n data?: {\n data: object;\n status: number;\n msg: string;\n msgTimeout?: number;\n errors?: {\n [propName: string]: string;\n };\n type?: string;\n [propName: string]: any; // 为了兼容其他返回格式\n };\n status: number;\n headers: object;\n}\n\nexport interface fetchOptions {\n method?: 'get' | 'post' | 'put' | 'patch' | 'delete' | 'jsonp';\n successMessage?: string;\n errorMessage?: string;\n autoAppend?: boolean;\n beforeSend?: (data: any) => any;\n onSuccess?: (json: Payload) => any;\n onFailed?: (json: Payload) => any;\n silent?: boolean;\n [propName: string]: any;\n}\n\nexport interface Payload {\n ok: boolean;\n msg: string;\n msgTimeout?: number;\n data: any;\n status: number;\n errors?: {\n [propName: string]: string;\n };\n}\n\nexport interface Schema {\n type: string;\n detectField?: string;\n visibleOn?: string;\n hiddenOn?: string;\n children?: JSX.Element | ((props: any, schema?: any) => JSX.Element) | null;\n definitions?: Definitions;\n [propName: string]: any;\n}\n\nexport interface Button {\n type: 'submit' | 'button' | 'reset';\n label?: string;\n icon?: string;\n size?: string;\n disabled?: boolean;\n className?: string;\n}\n\nexport type SchemaNode = Schema | string | Array<Schema | string>;\nexport interface SchemaArray extends Array<SchemaNode> {}\nexport interface Definitions {\n [propName: string]: SchemaNode;\n}\nexport interface Action extends Button {\n actionType?:\n | 'submit'\n | 'copy'\n | 'reload'\n | 'ajax'\n | 'saveAs'\n | 'dialog'\n | 'drawer'\n | 'jump'\n | 'link'\n | 'url'\n | 'email'\n | 'close'\n | 'confirm'\n | 'add'\n | 'remove'\n | 'delete'\n | 'edit'\n | 'cancel'\n | 'next'\n | 'prev'\n | 'reset'\n | 'validate'\n | 'reset-and-submit'\n | 'clear'\n | 'clear-and-submit'\n | 'toast'\n | 'goto-step'\n | 'goto-image'\n | 'expand'\n | 'collapse'\n | 'step-submit'\n | 'selectAll'\n | 'changeTabKey';\n api?: Api;\n asyncApi?: Api;\n payload?: any;\n dialog?: SchemaNode;\n to?: string;\n target?: string;\n link?: string;\n url?: string;\n cc?: string;\n bcc?: string;\n subject?: string;\n body?: string;\n mergeData?: boolean;\n reload?: string;\n messages?: {\n success?: string;\n failed?: string;\n };\n feedback?: any;\n required?: Array<string>;\n [propName: string]: any;\n}\n\nexport interface Location {\n pathname: string;\n search: string;\n state: any;\n hash: string;\n key?: string;\n query?: any;\n}\n\nexport interface PlainObject {\n [propsName: string]: any;\n}\n\nexport interface RendererData {\n [propsName: string]: any;\n __prev?: RendererDataAlias;\n __super?: RendererData;\n}\ntype RendererDataAlias = RendererData;\n\nexport type FunctionPropertyNames<T> = {\n [K in keyof T]: T[K] extends Function ? K : never;\n}[keyof T];\n\nexport interface JSONSchema {\n [propsName: string]: any;\n}\n\n// export type Omit<T, K extends keyof T & any> = Pick<T, Exclude<keyof T, K>>;\n// export type Override<M, N> = Omit<M, Extract<keyof M, keyof N>> & N;\n// export type ExtractProps<\n// TComponentOrTProps\n// > = TComponentOrTProps extends React.ComponentType<infer P> ? P : never;\n\n/**\n * 事件跟踪的定义\n */\nexport interface EventTrack {\n /**\n * 事件类型,目前有以下几种\n *\n * api: 所有 fetcher 前调用\n * url: 打开外部链接,组件有可能是 action 也有可能是 link\n * link: 打开内部链接\n * dialog: action 的弹框\n * drawer: action 的抽出式弹框\n * copy: action 里的复制\n * reload: action 里的 reload\n * email: action 里的 email\n * prev: action 里的 prev\n * next: action 里的 next\n * cancel: action 里的 cancel\n * close: action 里的 close\n * submit: 有可能是 action 里的 submit,也有可能是表单提交\n * confirm: action 里的 confirm\n * add: action 里的 add\n * reset: action 里的 reset\n * reset-and-submit: action 里的 reset-and-submit\n * formItemChange: 表单项内容变化\n * formError: 表单验证失败\n * formSubmit: 表单成功提交,在表单验证成功之后才会触发,这个可能会和 api 重合\n * tabChange: tab 切换\n * netError: api 报错\n */\n eventType:\n | 'api'\n | 'url'\n | 'link'\n | 'dialog'\n | 'drawer'\n | 'copy'\n | 'reload'\n | 'email'\n | 'prev'\n | 'next'\n | 'cancel'\n | 'close'\n | 'submit'\n | 'confirm'\n | 'reset'\n | 'reset-and-submit'\n | 'formItemChange'\n | 'tabChange';\n\n /**\n * 事件数据\n */\n eventData: ActionSchema | Api;\n}\n"
|
12
12
|
]
|
13
13
|
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
/**
|
2
|
+
* 用于存储当前可用运算器,默认支持 tpl、formula、js、var 四种类型运算器
|
3
|
+
* 备注:在这里统一参数。
|
4
|
+
*/
|
5
|
+
export declare const FormulaExec: {
|
6
|
+
[key: string]: Function;
|
7
|
+
};
|
8
|
+
export declare function formulaExec(value: any, data: any, execMode?: string | boolean): any;
|
9
|
+
export declare function registerFormulaExec(execMode: string, formulaExec: Function): void;
|
10
|
+
export declare function isExpression(expression: any): boolean;
|
11
|
+
export declare function isNeedFormula(expression: any, prevData: {
|
12
|
+
[propName: string]: any;
|
13
|
+
}, curData: {
|
14
|
+
[propName: string]: any;
|
15
|
+
}): boolean;
|
16
|
+
export declare function replaceExpression(expression: any): any;
|
@@ -0,0 +1,207 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.replaceExpression = exports.isNeedFormula = exports.isExpression = exports.registerFormulaExec = exports.formulaExec = exports.FormulaExec = void 0;
|
4
|
+
var tslib_1 = require("tslib");
|
5
|
+
var isObject_1 = (0, tslib_1.__importDefault)(require("lodash/isObject"));
|
6
|
+
var isString_1 = (0, tslib_1.__importDefault)(require("lodash/isString"));
|
7
|
+
var isBoolean_1 = (0, tslib_1.__importDefault)(require("lodash/isBoolean"));
|
8
|
+
var amis_formula_1 = require("amis-formula");
|
9
|
+
var tpl_1 = require("./tpl");
|
10
|
+
var tpl_builtin_1 = require("./tpl-builtin");
|
11
|
+
var grammar_1 = require("./grammar");
|
12
|
+
/**
|
13
|
+
* formulaExec 运算器:根据当前字符串类型执行对应运算,也可按指定执行模式执行运算
|
14
|
+
*
|
15
|
+
* 运算模式(execMode)支持以下取值:
|
16
|
+
* 1. tpl: 按模板字符串执行(JavaScript 模板引擎),比如:Hello ${amisUser.email}、<h1>Hello</h1>, <span>${amisUser.email}</span>;
|
17
|
+
* 备注: 在模板中可以自由访问变量,详细请见:https://www.lodashjs.com/docs/lodash.template;
|
18
|
+
* 2. formula: 按新版公式表达式执行,用于执行 ${ xxx } 格式的表达式;
|
19
|
+
* 支持从window、localStorage、sessionStorage获取数据,比如:${num1 + 2}、${ls:env}、${window:document}、${window:document.URL}、${amisUser.email};
|
20
|
+
* 详细请见:https://aisuda.bce.baidu.com/amis/zh-CN/docs/concepts/data-mapping#namespace
|
21
|
+
* 3. evalFormula: 按新版公式表达式执行,用于执行 ${ xxx } 和 非${ xxx } 格式的表达式(evalMode 为 true,不用 ${} 包裹也可以执行),功能同 formula 运算模式;
|
22
|
+
* 4. js: 按Javascript执行,表达式中可以通过data.xxx来获取指定数据,并且支持简单运算;
|
23
|
+
* 比如:data.num1 + 2、this.num1 + 2、num1 + 2;(备注:三个表达式是等价的,这里的 this 就是 data。)
|
24
|
+
* 5. var: 以此字符串作为key值从当前数据域data中获取数值;性能最高(运行期间不会生成ast和表达式运算);
|
25
|
+
* 6. true 或者 false: 当execMode设置为true时,不用 ${} 包裹也可以执行表达式;
|
26
|
+
* 7. collect: 用于从表达式中获取所有变量;
|
27
|
+
*
|
28
|
+
* 备注1: 用户也可以使用 registerFormulaExec 注册一个自定义运算器;
|
29
|
+
* 备注2: 模板字符串 和 Javascript 模板引擎 不可以交叉使用;
|
30
|
+
* 备注3: amis 现有的 evalFormula 方法,可执行 ${} 格式类表达式,但不支持 filter 过滤器,所以这里用 resolveValueByName 实现;
|
31
|
+
* 备注4: 后续可考虑将 amis现有的运算器都放这里管理,充当统一的运算器入口。
|
32
|
+
*/
|
33
|
+
// 缓存,用于提升性能
|
34
|
+
var FORMULA_EVAL_CACHE = {};
|
35
|
+
/**
|
36
|
+
* 用于存储当前可用运算器,默认支持 tpl、formula、js、var 四种类型运算器
|
37
|
+
* 备注:在这里统一参数。
|
38
|
+
*/
|
39
|
+
exports.FormulaExec = {
|
40
|
+
tpl: function (expression, data) {
|
41
|
+
var curData = data || {};
|
42
|
+
return (0, tpl_1.filter)(expression, curData);
|
43
|
+
},
|
44
|
+
formula: function (expression, data) {
|
45
|
+
// 邮箱格式直接返回,后续需要在 amis-formula 中处理
|
46
|
+
if (/^\$\{([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})\}$/.test(expression)) {
|
47
|
+
return expression.substring(2, expression.length - 1); // 剔除前后特殊字符
|
48
|
+
}
|
49
|
+
var curData = data || {};
|
50
|
+
var result = undefined;
|
51
|
+
try {
|
52
|
+
// 执行 ${} 格式类表达式,且支持 filter 过滤器。(备注: isPureVariable 可用于判断是否有 过滤器。)
|
53
|
+
result = (0, amis_formula_1.resolveVariableAndFilter)(expression, curData, '| raw');
|
54
|
+
}
|
55
|
+
catch (e) {
|
56
|
+
console.warn('[formula]表达式执行异常,当前表达式: ', expression, ',当前上下文数据: ', data);
|
57
|
+
return expression;
|
58
|
+
}
|
59
|
+
// 备注: 此处不用 result ?? expression 是为了避免 没有对应结果时直接显示 expression: ${xxx}
|
60
|
+
return result;
|
61
|
+
},
|
62
|
+
evalFormula: function (expression, data) {
|
63
|
+
var curData = data || {};
|
64
|
+
var result = undefined;
|
65
|
+
try {
|
66
|
+
result = (0, amis_formula_1.evaluate)(expression, curData, {
|
67
|
+
evalMode: true,
|
68
|
+
allowFilter: false
|
69
|
+
});
|
70
|
+
}
|
71
|
+
catch (e) {
|
72
|
+
console.warn('[evalFormula]表达式执行异常,当前表达式: ', expression, ',当前上下文数据: ', data);
|
73
|
+
return expression;
|
74
|
+
}
|
75
|
+
return result !== null && result !== void 0 ? result : expression;
|
76
|
+
},
|
77
|
+
js: function (expression, data) {
|
78
|
+
var debug = false;
|
79
|
+
var idx = expression.indexOf('debugger');
|
80
|
+
if (~idx) {
|
81
|
+
debug = true;
|
82
|
+
expression = expression.replace(/debugger;?/, '');
|
83
|
+
}
|
84
|
+
var fn;
|
85
|
+
if (expression in FORMULA_EVAL_CACHE) {
|
86
|
+
fn = FORMULA_EVAL_CACHE[expression];
|
87
|
+
}
|
88
|
+
else {
|
89
|
+
fn = new Function('data', 'utils', "with(data) {".concat(debug ? 'debugger;' : '', "return (").concat(expression, ");}"));
|
90
|
+
FORMULA_EVAL_CACHE[expression] = fn;
|
91
|
+
}
|
92
|
+
data = data || {};
|
93
|
+
var curResult = undefined;
|
94
|
+
try {
|
95
|
+
curResult = fn.call(data, data, (0, tpl_builtin_1.getFilters)());
|
96
|
+
}
|
97
|
+
catch (e) {
|
98
|
+
console.warn('[formula:js]表达式执行异常,当前表达式: ', expression, ',当前上下文数据: ', data);
|
99
|
+
return expression;
|
100
|
+
}
|
101
|
+
return curResult;
|
102
|
+
},
|
103
|
+
var: function (expression, data) {
|
104
|
+
var curData = data || {};
|
105
|
+
var result = (0, amis_formula_1.getVariable)(curData, expression); // 不支持过滤器
|
106
|
+
return result !== null && result !== void 0 ? result : expression;
|
107
|
+
},
|
108
|
+
collect: function (expression) {
|
109
|
+
var variables = [];
|
110
|
+
if ((0, isObject_1.default)(expression) || (0, isString_1.default)(expression)) {
|
111
|
+
// 仅对 Object类型 和 String类型 进行变量提取
|
112
|
+
variables = (0, grammar_1.collectVariables)(expression);
|
113
|
+
}
|
114
|
+
else {
|
115
|
+
variables = [];
|
116
|
+
}
|
117
|
+
return variables;
|
118
|
+
}
|
119
|
+
};
|
120
|
+
// 根据表达式类型自动匹配指定运算器,也可以通过设置 execMode 直接指定运算器
|
121
|
+
function formulaExec(value, data, execMode) {
|
122
|
+
if (!value) {
|
123
|
+
return '';
|
124
|
+
}
|
125
|
+
var OpenFormulaExecEvalMode = false;
|
126
|
+
var curExecMode = '';
|
127
|
+
if ((0, isBoolean_1.default)(execMode)) {
|
128
|
+
// OpenFormulaExecEvalMode 设置为 true 后,非 ${ xxx } 格式也使用表达式运算器
|
129
|
+
OpenFormulaExecEvalMode = execMode;
|
130
|
+
}
|
131
|
+
else if ((0, isString_1.default)(execMode)) {
|
132
|
+
// 指定 execMode 可以直接选用对应的运算器
|
133
|
+
curExecMode = execMode;
|
134
|
+
}
|
135
|
+
if (!(0, isString_1.default)(value)) {
|
136
|
+
// 非字符串类型,直接返回,比如:boolean、number类型、Object、Array类型
|
137
|
+
return value;
|
138
|
+
}
|
139
|
+
else if (curExecMode && exports.FormulaExec[curExecMode]) {
|
140
|
+
return exports.FormulaExec[curExecMode];
|
141
|
+
}
|
142
|
+
var curValue = value.trim(); // 剔除前后空格
|
143
|
+
// OpenFormulaExecEvalMode 为 true 时,非 ${ xxx } 格式也会尝试使用表达式运算器
|
144
|
+
if (OpenFormulaExecEvalMode && /^[0-9a-zA-z_]+$/.test(curValue)) {
|
145
|
+
// 普通字符串类型(非表达式),先试一下从上下文中获取数据
|
146
|
+
var curValueTemp = exports.FormulaExec['var'](curValue, data);
|
147
|
+
// 备注: 其他特殊格式,比如邮箱、日期
|
148
|
+
return curValueTemp !== null && curValueTemp !== void 0 ? curValueTemp : curValue;
|
149
|
+
}
|
150
|
+
else if (curValue.startsWith('${') && curValue.endsWith('}')) {
|
151
|
+
// ${ xxx } 格式 使用 formula 运算器
|
152
|
+
return exports.FormulaExec['formula'](curValue, data);
|
153
|
+
}
|
154
|
+
else if (isExpression(test)) {
|
155
|
+
// 表达式格式使用 formula 运算器
|
156
|
+
return exports.FormulaExec['formula'](curValue, data);
|
157
|
+
}
|
158
|
+
else if (/(\${).+(\})/.test(curValue)) {
|
159
|
+
// 包含 ${ xxx } 则使用 tpl 运算器
|
160
|
+
return exports.FormulaExec['tpl'](curValue, data); // 可识别 <% %> 语法
|
161
|
+
}
|
162
|
+
else if (OpenFormulaExecEvalMode) {
|
163
|
+
// 支持 ${} 和 非 ${} 表达式
|
164
|
+
return exports.FormulaExec['evalFormula'](curValue, data);
|
165
|
+
}
|
166
|
+
else {
|
167
|
+
return curValue;
|
168
|
+
}
|
169
|
+
}
|
170
|
+
exports.formulaExec = formulaExec;
|
171
|
+
// 用于注册自定义 formulaExec 运算器
|
172
|
+
function registerFormulaExec(execMode, formulaExec) {
|
173
|
+
if (exports.FormulaExec[execMode]) {
|
174
|
+
console.error("registerFormulaExec: \u8FD0\u7B97\u5668\u6CE8\u518C\u5931\u8D25\uFF0C\u5B58\u5728\u540C\u540D\u8FD0\u7B97\u5668\uFF08$(execMode)\uFF09\u3002");
|
175
|
+
}
|
176
|
+
else {
|
177
|
+
exports.FormulaExec[execMode] = formulaExec;
|
178
|
+
}
|
179
|
+
}
|
180
|
+
exports.registerFormulaExec = registerFormulaExec;
|
181
|
+
// 用于判断是否优先使用value。
|
182
|
+
function isExpression(expression) {
|
183
|
+
if (!(0, isString_1.default)(expression)) {
|
184
|
+
// 非字符串类型,比如:Object、Array类型、boolean、number类型
|
185
|
+
return false;
|
186
|
+
}
|
187
|
+
// 备注: "\\${xxx}"不作为表达式,至少含一个${xxx}才算是表达式
|
188
|
+
return /(?<!\\)(\${).+(\})/.test(expression);
|
189
|
+
}
|
190
|
+
exports.isExpression = isExpression;
|
191
|
+
// 用于判断是否需要执行表达式:
|
192
|
+
function isNeedFormula(expression, prevData, curData) {
|
193
|
+
var variables = exports.FormulaExec.collect(expression);
|
194
|
+
return variables.some(function (variable) {
|
195
|
+
return exports.FormulaExec.var(variable, prevData) !== exports.FormulaExec.var(variable, curData);
|
196
|
+
});
|
197
|
+
}
|
198
|
+
exports.isNeedFormula = isNeedFormula;
|
199
|
+
// 将 \${xx} 替换成 ${xx}
|
200
|
+
function replaceExpression(expression) {
|
201
|
+
if (expression && (0, isString_1.default)(expression) && /(\\)(\${).+(\})/.test(expression)) {
|
202
|
+
return expression.replace(/\\\$\{/g, '${');
|
203
|
+
}
|
204
|
+
return expression;
|
205
|
+
}
|
206
|
+
exports.replaceExpression = replaceExpression;
|
207
|
+
//# sourceMappingURL=./utils/formula.js.map
|
@@ -0,0 +1,13 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"file": "formula.js",
|
4
|
+
"sourceRoot": "",
|
5
|
+
"sources": [
|
6
|
+
"/src/utils/formula.ts"
|
7
|
+
],
|
8
|
+
"names": [],
|
9
|
+
"mappings": "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",
|
10
|
+
"sourcesContent": [
|
11
|
+
"import isObjectByLodash from 'lodash/isObject';\nimport isString from 'lodash/isString';\nimport isBoolean from 'lodash/isBoolean';\nimport {\n getVariable,\n isPureVariable,\n resolveVariable,\n resolveVariableAndFilter,\n evaluate\n} from 'amis-formula';\n\nimport {filter} from './tpl';\nimport {getFilters} from './tpl-builtin';\nimport {collectVariables} from './grammar';\n\n/**\n * formulaExec 运算器:根据当前字符串类型执行对应运算,也可按指定执行模式执行运算\n *\n * 运算模式(execMode)支持以下取值:\n * 1. tpl: 按模板字符串执行(JavaScript 模板引擎),比如:Hello ${amisUser.email}、<h1>Hello</h1>, <span>${amisUser.email}</span>;\n * 备注: 在模板中可以自由访问变量,详细请见:https://www.lodashjs.com/docs/lodash.template;\n * 2. formula: 按新版公式表达式执行,用于执行 ${ xxx } 格式的表达式;\n * 支持从window、localStorage、sessionStorage获取数据,比如:${num1 + 2}、${ls:env}、${window:document}、${window:document.URL}、${amisUser.email};\n * 详细请见:https://aisuda.bce.baidu.com/amis/zh-CN/docs/concepts/data-mapping#namespace\n * 3. evalFormula: 按新版公式表达式执行,用于执行 ${ xxx } 和 非${ xxx } 格式的表达式(evalMode 为 true,不用 ${} 包裹也可以执行),功能同 formula 运算模式;\n * 4. js: 按Javascript执行,表达式中可以通过data.xxx来获取指定数据,并且支持简单运算;\n * 比如:data.num1 + 2、this.num1 + 2、num1 + 2;(备注:三个表达式是等价的,这里的 this 就是 data。)\n * 5. var: 以此字符串作为key值从当前数据域data中获取数值;性能最高(运行期间不会生成ast和表达式运算);\n * 6. true 或者 false: 当execMode设置为true时,不用 ${} 包裹也可以执行表达式;\n * 7. collect: 用于从表达式中获取所有变量;\n * \n * 备注1: 用户也可以使用 registerFormulaExec 注册一个自定义运算器;\n * 备注2: 模板字符串 和 Javascript 模板引擎 不可以交叉使用;\n * 备注3: amis 现有的 evalFormula 方法,可执行 ${} 格式类表达式,但不支持 filter 过滤器,所以这里用 resolveValueByName 实现;\n * 备注4: 后续可考虑将 amis现有的运算器都放这里管理,充当统一的运算器入口。\n */\n\n// 缓存,用于提升性能\nconst FORMULA_EVAL_CACHE: {[key: string]: Function} = {};\n\n/**\n * 用于存储当前可用运算器,默认支持 tpl、formula、js、var 四种类型运算器\n * 备注:在这里统一参数。\n */\nexport const FormulaExec: {\n [key: string]: Function;\n} = {\n tpl: (expression: string, data?: object) => {\n const curData = data || {};\n return filter(expression, curData);\n },\n formula: (expression: string, data?: object) => {\n // 邮箱格式直接返回,后续需要在 amis-formula 中处理\n if (\n /^\\$\\{([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})\\}$/.test(\n expression\n )\n ) {\n return expression.substring(2, expression.length - 1); // 剔除前后特殊字符\n }\n const curData = data || {};\n let result = undefined;\n try {\n // 执行 ${} 格式类表达式,且支持 filter 过滤器。(备注: isPureVariable 可用于判断是否有 过滤器。)\n result = resolveVariableAndFilter(expression, curData, '| raw');\n } catch (e) {\n console.warn(\n '[formula]表达式执行异常,当前表达式: ',\n expression,\n ',当前上下文数据: ',\n data\n );\n return expression;\n }\n // 备注: 此处不用 result ?? expression 是为了避免 没有对应结果时直接显示 expression: ${xxx}\n return result;\n },\n evalFormula: (expression: string, data?: object) => {\n const curData = data || {};\n let result = undefined;\n try {\n result = evaluate(expression, curData, {\n evalMode: true, // evalMode 为 true 时,不用 ${} 包裹也可以执行,\n allowFilter: false\n });\n } catch (e) {\n console.warn(\n '[evalFormula]表达式执行异常,当前表达式: ',\n expression,\n ',当前上下文数据: ',\n data\n );\n return expression;\n }\n return result ?? expression;\n },\n js: (expression: string, data?: object) => {\n let debug = false;\n const idx = expression.indexOf('debugger');\n if (~idx) {\n debug = true;\n expression = expression.replace(/debugger;?/, '');\n }\n\n let fn;\n if (expression in FORMULA_EVAL_CACHE) {\n fn = FORMULA_EVAL_CACHE[expression];\n } else {\n fn = new Function(\n 'data',\n 'utils',\n `with(data) {${debug ? 'debugger;' : ''}return (${expression});}`\n );\n FORMULA_EVAL_CACHE[expression] = fn;\n }\n\n data = data || {};\n\n let curResult = undefined;\n try {\n curResult = fn.call(data, data, getFilters());\n } catch (e) {\n console.warn(\n '[formula:js]表达式执行异常,当前表达式: ',\n expression,\n ',当前上下文数据: ',\n data\n );\n return expression;\n }\n return curResult;\n },\n var: (expression: string, data?: object) => {\n const curData = data || {};\n const result = getVariable(curData, expression); // 不支持过滤器\n return result ?? expression;\n },\n collect: (expression: any) => {\n let variables: Array<string> = [];\n if (isObjectByLodash(expression) || isString(expression)) {\n // 仅对 Object类型 和 String类型 进行变量提取\n variables = collectVariables(expression);\n } else {\n variables = [];\n }\n return variables;\n }\n};\n\n// 根据表达式类型自动匹配指定运算器,也可以通过设置 execMode 直接指定运算器\nexport function formulaExec(\n value: any,\n data: any,\n execMode?: string | boolean\n) {\n if (!value) {\n return '';\n }\n let OpenFormulaExecEvalMode = false;\n let curExecMode = '';\n if (isBoolean(execMode)) {\n // OpenFormulaExecEvalMode 设置为 true 后,非 ${ xxx } 格式也使用表达式运算器\n OpenFormulaExecEvalMode = execMode;\n } else if (isString(execMode)) {\n // 指定 execMode 可以直接选用对应的运算器\n curExecMode = execMode;\n }\n if (!isString(value)) {\n // 非字符串类型,直接返回,比如:boolean、number类型、Object、Array类型\n return value;\n } else if (curExecMode && FormulaExec[curExecMode]) {\n return FormulaExec[curExecMode];\n }\n\n const curValue = value.trim(); // 剔除前后空格\n\n // OpenFormulaExecEvalMode 为 true 时,非 ${ xxx } 格式也会尝试使用表达式运算器\n if (OpenFormulaExecEvalMode && /^[0-9a-zA-z_]+$/.test(curValue)) {\n // 普通字符串类型(非表达式),先试一下从上下文中获取数据\n const curValueTemp = FormulaExec['var'](curValue, data);\n // 备注: 其他特殊格式,比如邮箱、日期\n return curValueTemp ?? curValue;\n } else if (curValue.startsWith('${') && curValue.endsWith('}')) {\n // ${ xxx } 格式 使用 formula 运算器\n return FormulaExec['formula'](curValue, data);\n } else if (isExpression(test)) {\n // 表达式格式使用 formula 运算器\n return FormulaExec['formula'](curValue, data);\n } else if (/(\\${).+(\\})/.test(curValue)) {\n // 包含 ${ xxx } 则使用 tpl 运算器\n return FormulaExec['tpl'](curValue, data); // 可识别 <% %> 语法\n } else if (OpenFormulaExecEvalMode) {\n // 支持 ${} 和 非 ${} 表达式\n return FormulaExec['evalFormula'](curValue, data);\n } else {\n return curValue;\n }\n}\n\n// 用于注册自定义 formulaExec 运算器\nexport function registerFormulaExec(execMode: string, formulaExec: Function) {\n if (FormulaExec[execMode]) {\n console.error(\n `registerFormulaExec: 运算器注册失败,存在同名运算器($(execMode))。`\n );\n } else {\n FormulaExec[execMode] = formulaExec;\n }\n}\n\n// 用于判断是否优先使用value。\nexport function isExpression(expression: any): boolean {\n if (!isString(expression)) {\n // 非字符串类型,比如:Object、Array类型、boolean、number类型\n return false;\n }\n // 备注: \"\\\\${xxx}\"不作为表达式,至少含一个${xxx}才算是表达式\n return /(?<!\\\\)(\\${).+(\\})/.test(expression);\n}\n\n// 用于判断是否需要执行表达式:\nexport function isNeedFormula(\n expression: any,\n prevData: {[propName: string]: any},\n curData: {[propName: string]: any}\n): boolean {\n const variables = FormulaExec.collect(expression);\n return variables.some(\n (variable: string) =>\n FormulaExec.var(variable, prevData) !== FormulaExec.var(variable, curData)\n );\n}\n\n// 将 \\${xx} 替换成 ${xx}\nexport function replaceExpression(expression: any): any {\n if (expression && isString(expression) && /(\\\\)(\\${).+(\\})/.test(expression)) {\n return expression.replace(/\\\\\\$\\{/g, '${');\n }\n return expression;\n}\n"
|
12
|
+
]
|
13
|
+
}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
"use strict";
|
2
|
+
/**
|
3
|
+
* @file 公式语法解析
|
4
|
+
*/
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.collectVariables = void 0;
|
7
|
+
var amis_formula_1 = require("amis-formula");
|
8
|
+
function traverseAst(ast, iterator) {
|
9
|
+
if (!ast || !ast.type) {
|
10
|
+
return;
|
11
|
+
}
|
12
|
+
iterator(ast);
|
13
|
+
Object.keys(ast).forEach(function (key) {
|
14
|
+
var value = ast[key];
|
15
|
+
if (Array.isArray(value)) {
|
16
|
+
value.forEach(function (child) { return traverseAst(child, iterator); });
|
17
|
+
}
|
18
|
+
else {
|
19
|
+
traverseAst(value, iterator);
|
20
|
+
}
|
21
|
+
});
|
22
|
+
}
|
23
|
+
// 缓存,用于提升性能
|
24
|
+
var COLLECT_EXPRESSION_CACHE = {};
|
25
|
+
// 提取表达式中有哪些变量
|
26
|
+
function collectVariables(strOrAst, execMode) {
|
27
|
+
var variables = [];
|
28
|
+
if (typeof strOrAst === 'string' && COLLECT_EXPRESSION_CACHE[strOrAst]) {
|
29
|
+
return COLLECT_EXPRESSION_CACHE[strOrAst];
|
30
|
+
}
|
31
|
+
var ast = typeof strOrAst === 'string'
|
32
|
+
? (0, amis_formula_1.parse)(strOrAst, {
|
33
|
+
evalMode: execMode !== null && execMode !== void 0 ? execMode : false
|
34
|
+
})
|
35
|
+
: strOrAst;
|
36
|
+
traverseAst(ast, function (item) {
|
37
|
+
if (item.type === 'variable') {
|
38
|
+
variables.push(item.name);
|
39
|
+
}
|
40
|
+
});
|
41
|
+
if (typeof strOrAst === 'string') {
|
42
|
+
COLLECT_EXPRESSION_CACHE[strOrAst] = variables;
|
43
|
+
}
|
44
|
+
return variables;
|
45
|
+
}
|
46
|
+
exports.collectVariables = collectVariables;
|
47
|
+
//# sourceMappingURL=./utils/grammar.js.map
|
@@ -0,0 +1,13 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"file": "grammar.js",
|
4
|
+
"sourceRoot": "",
|
5
|
+
"sources": [
|
6
|
+
"/src/utils/grammar.ts"
|
7
|
+
],
|
8
|
+
"names": [],
|
9
|
+
"mappings": ";AAAA;;GAEG;;;AAEH,6CAAmC;AAEnC,SAAS,WAAW,CAAC,GAAQ,EAAE,QAA4B;IACzD,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;QACrB,OAAO;KACR;IAED,QAAQ,CAAC,GAAG,CAAC,CAAC;IAEd,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,UAAA,GAAG;QAC1B,IAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAEvB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACxB,KAAK,CAAC,OAAO,CAAC,UAAA,KAAK,IAAI,OAAA,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,EAA5B,CAA4B,CAAC,CAAC;SACtD;aAAM;YACL,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;SAC9B;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,YAAY;AACZ,IAAM,wBAAwB,GAAmC,EAAE,CAAC;AAEpE,cAAc;AACd,SAAgB,gBAAgB,CAAC,QAAyB,EAAE,QAAkB;IAC5E,IAAM,SAAS,GAAkB,EAAE,CAAC;IAEpC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,wBAAwB,CAAC,QAAQ,CAAC,EAAE;QACtE,OAAO,wBAAwB,CAAC,QAAQ,CAAC,CAAC;KAC3C;IACD,IAAM,GAAG,GACP,OAAO,QAAQ,KAAK,QAAQ;QAC1B,CAAC,CAAC,IAAA,oBAAK,EAAC,QAAQ,EAAE;YACd,QAAQ,EAAE,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,KAAK;SAC5B,CAAC;QACJ,CAAC,CAAC,QAAQ,CAAC;IAEf,WAAW,CAAC,GAAG,EAAE,UAAC,IAAS;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE;YAC5B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAC3B;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;QAChC,wBAAwB,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;KAChD;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAxBD,4CAwBC",
|
10
|
+
"sourcesContent": [
|
11
|
+
"/**\n * @file 公式语法解析\n */\n\nimport {parse} from 'amis-formula';\n\nfunction traverseAst(ast: any, iterator: (ast: any) => void) {\n if (!ast || !ast.type) {\n return;\n }\n\n iterator(ast);\n\n Object.keys(ast).forEach(key => {\n const value = ast[key];\n\n if (Array.isArray(value)) {\n value.forEach(child => traverseAst(child, iterator));\n } else {\n traverseAst(value, iterator);\n }\n });\n}\n\n// 缓存,用于提升性能\nconst COLLECT_EXPRESSION_CACHE: {[key: string]: Array<string>} = {};\n\n// 提取表达式中有哪些变量\nexport function collectVariables(strOrAst: string | Object, execMode?: boolean): Array<string> {\n const variables: Array<string> = [];\n\n if (typeof strOrAst === 'string' && COLLECT_EXPRESSION_CACHE[strOrAst]) {\n return COLLECT_EXPRESSION_CACHE[strOrAst];\n }\n const ast =\n typeof strOrAst === 'string'\n ? parse(strOrAst, {\n evalMode: execMode ?? false\n })\n : strOrAst;\n\n traverseAst(ast, (item: any) => {\n if (item.type === 'variable') {\n variables.push(item.name);\n }\n });\n\n if (typeof strOrAst === 'string') {\n COLLECT_EXPRESSION_CACHE[strOrAst] = variables;\n }\n\n return variables;\n}\n"
|
12
|
+
]
|
13
|
+
}
|
package/lib/utils/helper.js
CHANGED
@@ -1103,6 +1103,7 @@ function getScrollbarWidth() {
|
|
1103
1103
|
return scrollbarWidth;
|
1104
1104
|
}
|
1105
1105
|
exports.getScrollbarWidth = getScrollbarWidth;
|
1106
|
+
// 后续改用 FormulaExec['formula']
|
1106
1107
|
function resolveValueByName(data, name) {
|
1107
1108
|
return (0, amis_formula_1.isPureVariable)(name)
|
1108
1109
|
? (0, amis_formula_1.resolveVariableAndFilter)(name, data)
|