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.
Files changed (133) hide show
  1. package/lib/RootRenderer.js +14 -0
  2. package/lib/RootRenderer.js.map +2 -2
  3. package/lib/SchemaRenderer.js +8 -3
  4. package/lib/SchemaRenderer.js.map +2 -2
  5. package/lib/components/Alert2.d.ts +10 -10
  6. package/lib/components/DateRangePicker.js +11 -9
  7. package/lib/components/DateRangePicker.js.map +2 -2
  8. package/lib/components/SearchBox.d.ts +40 -40
  9. package/lib/components/Select.d.ts +193 -193
  10. package/lib/components/Select.js +2 -4
  11. package/lib/components/Select.js.map +2 -2
  12. package/lib/components/virtual-list/index.js +1 -1
  13. package/lib/components/virtual-list/index.js.map +1 -1
  14. package/lib/index.js +1 -1
  15. package/lib/locale/de-DE.js +1 -0
  16. package/lib/locale/de-DE.js.map +2 -2
  17. package/lib/locale/en-US.js +1 -0
  18. package/lib/locale/en-US.js.map +2 -2
  19. package/lib/locale/zh-CN.js +5 -2
  20. package/lib/locale/zh-CN.js.map +2 -2
  21. package/lib/renderers/Action.d.ts +6 -0
  22. package/lib/renderers/Action.js.map +2 -2
  23. package/lib/renderers/CRUD.js +2 -1
  24. package/lib/renderers/CRUD.js.map +2 -2
  25. package/lib/renderers/Card.js +5 -4
  26. package/lib/renderers/Card.js.map +2 -2
  27. package/lib/renderers/Carousel.d.ts +1 -1
  28. package/lib/renderers/Carousel.js +5 -1
  29. package/lib/renderers/Carousel.js.map +2 -2
  30. package/lib/renderers/Form/InputImage.js +1 -1
  31. package/lib/renderers/Form/InputImage.js.map +2 -2
  32. package/lib/renderers/Form/InputText.js +1 -1
  33. package/lib/renderers/Form/InputText.js.map +2 -2
  34. package/lib/renderers/Form/Options.js +1 -0
  35. package/lib/renderers/Form/Options.js.map +2 -2
  36. package/lib/renderers/Form/Select.d.ts +12 -0
  37. package/lib/renderers/Form/Select.js +1 -3
  38. package/lib/renderers/Form/Select.js.map +2 -2
  39. package/lib/renderers/Form/wrapControl.js +72 -19
  40. package/lib/renderers/Form/wrapControl.js.map +2 -2
  41. package/lib/renderers/Service.js +1 -0
  42. package/lib/renderers/Service.js.map +2 -2
  43. package/lib/renderers/Table/TableContent.d.ts +2 -2
  44. package/lib/renderers/Table/TableContent.js +4 -16
  45. package/lib/renderers/Table/TableContent.js.map +2 -2
  46. package/lib/renderers/Table/index.d.ts +2 -5
  47. package/lib/renderers/Table/index.js +2 -2
  48. package/lib/renderers/Table/index.js.map +2 -2
  49. package/lib/store/table.js +7 -3
  50. package/lib/store/table.js.map +2 -2
  51. package/lib/themes/ang-ie11.css +0 -1
  52. package/lib/themes/ang.css +0 -1
  53. package/lib/themes/ang.css.map +1 -1
  54. package/lib/themes/antd-ie11.css +0 -1
  55. package/lib/themes/antd.css +0 -1
  56. package/lib/themes/antd.css.map +1 -1
  57. package/lib/themes/cxd-ie11.css +8 -1
  58. package/lib/themes/cxd.css +8 -1
  59. package/lib/themes/cxd.css.map +1 -1
  60. package/lib/themes/dark-ie11.css +0 -1
  61. package/lib/themes/dark.css +0 -1
  62. package/lib/themes/dark.css.map +1 -1
  63. package/lib/themes/default-ie11.css +8 -1
  64. package/lib/themes/default.css +8 -1
  65. package/lib/themes/default.css.map +1 -1
  66. package/lib/types.d.ts +1 -1
  67. package/lib/types.js.map +1 -1
  68. package/lib/utils/formula.d.ts +16 -0
  69. package/lib/utils/formula.js +207 -0
  70. package/lib/utils/formula.js.map +13 -0
  71. package/lib/utils/grammar.d.ts +4 -0
  72. package/lib/utils/grammar.js +47 -0
  73. package/lib/utils/grammar.js.map +13 -0
  74. package/lib/utils/helper.js +1 -0
  75. package/lib/utils/helper.js.map +2 -2
  76. package/lib/utils/tpl.js +3 -0
  77. package/lib/utils/tpl.js.map +2 -2
  78. package/package.json +1 -1
  79. package/schema.json +278 -222
  80. package/scss/components/_collapse.scss +1 -1
  81. package/scss/themes/cxd.scss +12 -0
  82. package/sdk/ang-ie11.css +0 -1
  83. package/sdk/ang.css +0 -1
  84. package/sdk/antd-ie11.css +0 -1
  85. package/sdk/antd.css +0 -1
  86. package/sdk/barcode.js +51 -51
  87. package/sdk/charts.js +14 -14
  88. package/sdk/codemirror.js +7 -7
  89. package/sdk/color-picker.js +65 -65
  90. package/sdk/cropperjs.js +2 -2
  91. package/sdk/cxd-ie11.css +9 -1
  92. package/sdk/cxd.css +9 -1
  93. package/sdk/dark-ie11.css +0 -1
  94. package/sdk/dark.css +0 -1
  95. package/sdk/exceljs.js +1 -1
  96. package/sdk/locale/de-DE.js +1 -0
  97. package/sdk/markdown.js +69 -69
  98. package/sdk/papaparse.js +1 -1
  99. package/sdk/renderers/Form/CityDB.js +1 -1
  100. package/sdk/rest.js +16 -16
  101. package/sdk/rich-text.js +62 -62
  102. package/sdk/sdk-ie11.css +9 -1
  103. package/sdk/sdk.css +9 -1
  104. package/sdk/sdk.js +1695 -1665
  105. package/sdk/thirds/hls.js/hls.js +1 -1
  106. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  107. package/sdk/tinymce.js +57 -57
  108. package/src/RootRenderer.tsx +14 -0
  109. package/src/SchemaRenderer.tsx +4 -2
  110. package/src/components/DateRangePicker.tsx +73 -60
  111. package/src/components/Select.tsx +2 -4
  112. package/src/components/virtual-list/index.tsx +1 -1
  113. package/src/locale/de-DE.ts +1 -0
  114. package/src/locale/en-US.ts +1 -0
  115. package/src/locale/zh-CN.ts +5 -2
  116. package/src/renderers/Action.tsx +8 -0
  117. package/src/renderers/CRUD.tsx +2 -1
  118. package/src/renderers/Card.tsx +10 -5
  119. package/src/renderers/Carousel.tsx +10 -4
  120. package/src/renderers/Form/InputImage.tsx +1 -1
  121. package/src/renderers/Form/InputText.tsx +1 -0
  122. package/src/renderers/Form/Options.tsx +1 -0
  123. package/src/renderers/Form/Select.tsx +13 -3
  124. package/src/renderers/Form/wrapControl.tsx +90 -22
  125. package/src/renderers/Service.tsx +1 -0
  126. package/src/renderers/Table/TableContent.tsx +22 -34
  127. package/src/renderers/Table/index.tsx +4 -8
  128. package/src/store/table.ts +10 -3
  129. package/src/types.ts +1 -0
  130. package/src/utils/formula.ts +240 -0
  131. package/src/utils/grammar.ts +53 -0
  132. package/src/utils/helper.ts +2 -1
  133. 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,4 @@
1
+ /**
2
+ * @file 公式语法解析
3
+ */
4
+ export declare function collectVariables(strOrAst: string | Object, execMode?: boolean): Array<string>;
@@ -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
+ }
@@ -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)