From 9bcb1b7dd53fef2d0227cd7c400e3dcbb7472cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8A=9B=E7=9A=93?= Date: Tue, 11 May 2021 19:45:51 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=89=A9=E6=96=99=E6=8F=8F=E8=BF=B0?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E9=92=A9=E5=AD=90=E5=87=BD=E6=95=B0=E7=AD=89?= =?UTF-8?q?=E6=94=AF=E6=8C=81=20JSFunction=20=E5=BD=A2=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../editor-skeleton/src/register-defaults.ts | 4 ++ .../src/transducers/parse-func.ts | 64 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 packages/editor-skeleton/src/transducers/parse-func.ts diff --git a/packages/editor-skeleton/src/register-defaults.ts b/packages/editor-skeleton/src/register-defaults.ts index 50e73b508..0ec8e8a06 100644 --- a/packages/editor-skeleton/src/register-defaults.ts +++ b/packages/editor-skeleton/src/register-defaults.ts @@ -4,6 +4,7 @@ import ArraySetter from './components/array-setter'; import ObjectSetter from './components/object-setter'; import MixedSetter from './components/mixed-setter'; import { isPlainObject } from '@ali/lowcode-utils'; +import parseJSFunc from './transducers/parse-func'; import parseProps from './transducers/parse-props'; import addonCombine from './transducers/addon-combine'; import SlotSetter from './components/slot-setter'; @@ -56,6 +57,9 @@ export const registerDefaults = () => { }); registerSetter('MixedSetter', MixedSetter); + // parseFunc + registerMetadataTransducer(parseJSFunc, 9, 'parse-func'); + // parseProps registerMetadataTransducer(parseProps, 10, 'parse-props'); diff --git a/packages/editor-skeleton/src/transducers/parse-func.ts b/packages/editor-skeleton/src/transducers/parse-func.ts new file mode 100644 index 000000000..8c02349ce --- /dev/null +++ b/packages/editor-skeleton/src/transducers/parse-func.ts @@ -0,0 +1,64 @@ +import { + FieldConfig, + TransformedComponentMetadata, + isJSFunction, +} from '@ali/lowcode-types'; +import { isPlainObject } from '@ali/lowcode-utils'; + +const leadingFnRe = /^function/; +const leadingFnNameRe = /^\w+\s*\(/; +/** + * 将函数字符串转成函数,支持几种类型 + * 类型一:() => {} / val => {} + * 类型二:setValue() {} + * 类型三:function() {} / function setValue() {} + * @param str + * @returns + */ +function transformStringToFunction(str: string) { + if (typeof str !== 'string') return str; + + let fn; + if (leadingFnNameRe.test(str) && !leadingFnRe.test(str)) { + str = `function ${str}`; + } + let fnBody = ` + return function() { + const self = this; + try { + return (${str}).apply(self, arguments); + } catch(e) { + console.log('call function which parsed by lowcode failed: ', e); + return e.message; + } + }; + `; + try { + // eslint-disable-next-line no-new-func + fn = new Function(fnBody)(); + } catch (e) { + console.error(str); + console.error(e.message); + } + return fn; +} + +function parseJSFunc(obj: any, enableAllowedKeys = true) { + if (!obj) return; + Object.keys(obj).forEach(key => { + const item = obj[key]; + if (isJSFunction(item)) { + obj[key] = transformStringToFunction(item.value); + } else if (Array.isArray(item)) { + item.forEach(o => parseJSFunc(o, enableAllowedKeys)); + } else if (isPlainObject(item)) { + parseJSFunc(item, enableAllowedKeys); + } + }); +} + +export default function (metadata: TransformedComponentMetadata): TransformedComponentMetadata { + parseJSFunc(metadata, false); + + return metadata; +} \ No newline at end of file