feat: 物料描述中的钩子函数等支持 JSFunction 形式

This commit is contained in:
力皓 2021-05-11 19:45:51 +08:00
parent b23231e8d0
commit 9bcb1b7dd5
2 changed files with 68 additions and 0 deletions

View File

@ -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');

View File

@ -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;
}