feat(editor): 新增parseDSL配置,用于解析DSL,默认使用eval

This commit is contained in:
roymondchen 2023-06-19 11:27:47 +08:00
parent 1f5527270c
commit 2b881c3863
10 changed files with 36 additions and 21 deletions

View File

@ -33,7 +33,7 @@
</TMagicCard>
</template>
<script lang="ts" setup>
import { inject, ref, watchEffect } from 'vue';
import { inject, provide, ref, watchEffect } from 'vue';
import { cloneDeep } from 'lodash-es';
import { TMagicCard, TMagicInput, tMagicMessage } from '@tmagic/design';
@ -41,6 +41,7 @@ import { ColumnConfig, TableConfig } from '@tmagic/form';
import { CodeParam, Id } from '@tmagic/schema';
import type { Services } from '@editor/type';
import { getConfig } from '@editor/utils/config';
import CodeDraftEditor from './CodeDraftEditor.vue';
@ -48,6 +49,8 @@ defineOptions({
name: 'MEditorFunctionEditor',
});
provide('mForm', {});
const defaultParamColConfig: ColumnConfig = {
type: 'row',
label: '参数类型',
@ -147,9 +150,8 @@ initTableModel();
//
const beforeSave = (codeValue: string): boolean => {
try {
// evaljs
// eslint-disable-next-line no-eval
eval(codeValue);
// js
getConfig('parseDSL')(codeValue);
return true;
} catch (e: any) {
tMagicMessage.error(e.stack);

View File

@ -6,6 +6,8 @@
import { computed, reactive, watch } from 'vue';
import serialize from 'serialize-javascript';
import { getConfig } from '@editor/utils/config';
defineOptions({
name: 'MEditorCodeLink',
});
@ -69,8 +71,8 @@ const changeHandler = (v: Record<string, any>) => {
if (!props.name || !props.model) return;
try {
// eslint-disable-next-line no-eval
props.model[props.name] = eval(`(${v[props.name]})`);
const parseDSL = getConfig('parseDSL');
props.model[props.name] = parseDSL(`(${v[props.name]})`);
emit('change', props.model[props.name]);
} catch (e) {
console.error(e);

View File

@ -64,11 +64,12 @@ export { default as LayoutContainer } from './components/SplitView.vue';
export { default as SplitView } from './components/SplitView.vue';
const defaultInstallOpt: InstallOptions = {
// @todo, 自定义图片上传方法等编辑器依赖的外部选项
// eslint-disable-next-line no-eval
parseDSL: (dsl: string) => eval(dsl),
};
export default {
install: (app: App, opt?: InstallOptions): void => {
install: (app: App, opt?: Partial<InstallOptions>): void => {
const option = Object.assign(defaultInstallOpt, opt || {});
// eslint-disable-next-line no-param-reassign

View File

@ -52,6 +52,7 @@ import { TMagicScrollbar } from '@tmagic/design';
import SplitView from '@editor/components/SplitView.vue';
import type { GetColumnWidth, Services } from '@editor/type';
import { getConfig } from '@editor/utils/config';
import AddPageBox from './AddPageBox.vue';
import CodeEditor from './CodeEditor.vue';
@ -131,8 +132,8 @@ const columnWidthChange = (columnW: GetColumnWidth) => {
const saveCode = (value: string) => {
try {
// eslint-disable-next-line no-eval
editorService?.set('root', eval(value));
const parseDSL = getConfig('parseDSL');
editorService?.set('root', parseDSL(value));
} catch (e: any) {
console.error(e);
}

View File

@ -36,6 +36,7 @@ import StageCore, { calcValueByFontsize, getOffset, Runtime } from '@tmagic/stag
import ScrollViewer from '@editor/components/ScrollViewer.vue';
import { Layout, MenuButton, MenuComponent, Services, StageOptions } from '@editor/type';
import { getConfig } from '@editor/utils/config';
import { useStage } from '@editor/utils/stage';
import ViewerMenu from './ViewerMenu.vue';
@ -162,8 +163,8 @@ const dropHandler = async (e: DragEvent) => {
}
if (e.dataTransfer && parent && stageContainer.value && stage) {
// eslint-disable-next-line no-eval
const config = eval(`(${e.dataTransfer.getData('data')})`);
const parseDSL = getConfig('parseDSL');
const config = parseDSL(`(${e.dataTransfer.getData('data')})`);
const layout = await services?.editorService.getLayout(parent);
const containerRect = stageContainer.value.getBoundingClientRect();

View File

@ -23,6 +23,7 @@ import { CodeBlockContent, CodeBlockDSL, Id } from '@tmagic/schema';
import type { CodeState } from '@editor/type';
import { CODE_DRAFT_STORAGE_KEY } from '@editor/type';
import { getConfig } from '@editor/utils/config';
import BaseService from './BaseService';
@ -95,8 +96,8 @@ class CodeBlock extends BaseService {
const codeConfigProcessed = codeConfig;
if (codeConfig.content) {
// 在保存的时候转换代码内容
// eslint-disable-next-line no-eval
codeConfigProcessed.content = eval(codeConfig.content);
const parseDSL = getConfig('parseDSL');
codeConfigProcessed.content = parseDSL(codeConfig.content);
}
const existContent = codeDsl[id] || {};

View File

@ -1,5 +1,7 @@
import serialize from 'serialize-javascript';
import { getConfig } from '@editor/utils/config';
import BaseService from './BaseService';
interface Options {
@ -64,8 +66,7 @@ export class WebStorage extends BaseService {
switch (protocol) {
case Protocol.OBJECT:
// eslint-disable-next-line no-eval
return eval(`(${item})`);
return getConfig('parseDSL')(`(${item})`);
case Protocol.JSON:
return JSON.parse(item);
case Protocol.NUMBER:

View File

@ -45,6 +45,7 @@ export type BeforeAdd = (config: MNode, parent: MContainer) => Promise<MNode> |
export type GetConfig = (config: FormConfig) => Promise<FormConfig> | FormConfig;
export interface InstallOptions {
parseDSL: (dsl: string) => MApp;
[key: string]: any;
}

View File

@ -24,6 +24,6 @@ const setConfig = (option: InstallOptions): void => {
$TMAGIC_EDITOR = option;
};
const getConfig = (key: keyof InstallOptions): unknown => $TMAGIC_EDITOR[key];
const getConfig = <K extends keyof InstallOptions>(key: K): InstallOptions[K] => $TMAGIC_EDITOR[key];
export { getConfig, setConfig };

View File

@ -25,7 +25,12 @@ import { NodeType } from '@tmagic/schema';
import editorService from '@editor/services/editor';
import historyService from '@editor/services/history';
import storageService from '@editor/services/storage';
import { COPY_STORAGE_KEY } from '@editor/utils';
import { COPY_STORAGE_KEY, setConfig } from '@editor/utils';
setConfig({
// eslint-disable-next-line no-eval
parseDSL: (dsl: string) => eval(dsl),
});
// mock window.localStage
class LocalStorageMock {
@ -306,7 +311,7 @@ describe('update', () => {
test('没有id', async () => {
try {
await editorService.update({ type: 'text', text: 'text', id: '' });
} catch (e: InstanceType<Error>) {
} catch (e: any) {
expect(e.message).toBe('没有配置或者配置缺少id值');
}
});
@ -315,7 +320,7 @@ describe('update', () => {
// 一般可能出现在外边扩展功能
try {
await editorService.update({ type: '', text: 'text', id: NodeId.NODE_ID });
} catch (e: InstanceType<Error>) {
} catch (e: any) {
expect(e.message).toBe('配置缺少type值');
}
});
@ -325,7 +330,7 @@ describe('update', () => {
// 设置当前编辑的页面
await editorService.select(NodeId.PAGE_ID);
await editorService.update({ type: 'text', text: 'text', id: NodeId.ERROR_NODE_ID });
} catch (e: InstanceType<Error>) {
} catch (e: any) {
expect(e.message).toBe(`获取不到id为${NodeId.ERROR_NODE_ID}的节点`);
}
});