fix: refactor update import specifiers (#68)

* fix: refactor update import declaration

* fix: rename module methods

* fix: update types

* fix: update

---------

Co-authored-by: wwsun <ww.sww@outlook.com>
This commit is contained in:
Wells
2023-11-23 15:54:22 +08:00
committed by GitHub
parent 8a1234e565
commit 558f2cd0a6
10 changed files with 239 additions and 297 deletions
+2 -1
View File
@@ -2,11 +2,12 @@
"extends": ["eslint-config-ali/typescript/react", "prettier"],
"ignorePatterns": ["**/dist/**/*", "**/lib/**/*", "**/node_modules/**/*", "scripts/**/*"],
"rules": {
"@typescript-eslint/consistent-type-definitions": "off",
"@typescript-eslint/dot-notation": "off",
"@typescript-eslint/no-unused-vars": "warn",
"import/no-cycle": "off",
"no-nested-ternary": "off",
"no-useless-return":"off",
"no-useless-return": "off",
"no-param-reassign": "off",
"prefer-destructuring": "off"
}
+3
View File
@@ -151,6 +151,7 @@ import {
Input,
FormilyForm,
} from "@music163/antd";
import { Space } from '@music163/antd';
class App extends React.Component {
render() {
return (
@@ -158,8 +159,10 @@ class App extends React.Component {
<Section title="Section Title">
</Section>
<Section>
<Space>
<Button>button</Button>
<Input />
</Space>
</Section>
</Page>
);
+67 -23
View File
@@ -453,7 +453,7 @@ function getLastExportDeclarationIndex(node: t.Program) {
* @param importedSourcePath
* @returns
*/
export function makeImportDeclaration(importedModule: IImportDeclarationPayload) {
export function makeImportDeclarationLegacy(importedModule: IImportDeclarationPayload) {
const specifierNodes =
importedModule.specifiers?.map((localName) =>
t.importSpecifier(t.identifier(localName), t.identifier(localName)),
@@ -468,19 +468,28 @@ export function makeImportDeclaration(importedModule: IImportDeclarationPayload)
return t.importDeclaration(newSpecifierNodes, t.stringLiteral(importedModule.sourcePath));
}
export function makeImportDeclaration2(source: string, specifiers: IImportSpecifierData[]) {
const specifierNodes = specifiers.map((item) => {
switch (item.type) {
case 'ImportDefaultSpecifier':
return t.importDefaultSpecifier(t.identifier(item.localName));
case 'ImportSpecifier':
return t.importSpecifier(t.identifier(item.importedName), t.identifier(item.localName));
case 'ImportNamespaceSpecifier':
return t.importNamespaceSpecifier(t.identifier(item.localName));
default:
return;
}
});
function specifierData2node(data: IImportSpecifierData) {
switch (data.type) {
case 'ImportDefaultSpecifier':
return t.importDefaultSpecifier(t.identifier(data.localName));
case 'ImportSpecifier':
return t.importSpecifier(
t.identifier(data.importedName || data.localName),
t.identifier(data.localName),
);
case 'ImportNamespaceSpecifier':
return t.importNamespaceSpecifier(t.identifier(data.localName));
default:
return;
}
}
function specifierDataList2nodes(specifiers: IImportSpecifierData[]) {
return specifiers.map((item) => specifierData2node(item)).filter((item) => !!item);
}
export function makeImportDeclaration(source: string, specifiers: IImportSpecifierData[]) {
const specifierNodes = specifierDataList2nodes(specifiers);
return t.importDeclaration(specifierNodes, t.stringLiteral(source));
}
@@ -515,11 +524,11 @@ function getImportDeclarationData(node: t.ImportDeclaration): IImportDeclaration
* @param importedSourcePath
* @returns
*/
export function addImportDeclaration(ast: t.File, importedModule: IImportDeclarationPayload) {
export function addImportDeclarationLegacy(ast: t.File, importedModule: IImportDeclarationPayload) {
traverse(ast, {
Program(path) {
const lastIndex = getLastImportDeclarationIndex(path.node);
const newImportDeclaration = makeImportDeclaration(importedModule);
const newImportDeclaration = makeImportDeclarationLegacy(importedModule);
path.node.body.splice(lastIndex, 0, newImportDeclaration);
path.stop();
},
@@ -527,7 +536,7 @@ export function addImportDeclaration(ast: t.File, importedModule: IImportDeclara
return ast;
}
export function addImportDeclaration2(
export function addImportDeclaration(
ast: t.File,
source: string,
specifiers: IImportSpecifierData[],
@@ -535,11 +544,12 @@ export function addImportDeclaration2(
traverse(ast, {
Program(path) {
const lastIndex = getLastImportDeclarationIndex(path.node);
const newImportDeclaration = makeImportDeclaration2(source, specifiers);
const newImportDeclaration = makeImportDeclaration(source, specifiers);
path.node.body.splice(lastIndex, 0, newImportDeclaration);
path.stop();
},
});
return ast;
}
/**
@@ -550,12 +560,15 @@ export function addImportDeclaration2(
* @param importedSourcePath
* @returns
*/
export function updateImportDeclaration(ast: t.File, importedModule: IImportDeclarationPayload) {
export function updateImportDeclarationLegacy(
ast: t.File,
importedModule: IImportDeclarationPayload,
) {
traverse(ast, {
ImportDeclaration(path) {
const currentSourcePath = node2value(path.node.source);
if (currentSourcePath === importedModule.sourcePath) {
const newImportDeclaration = makeImportDeclaration(importedModule);
const newImportDeclaration = makeImportDeclarationLegacy(importedModule);
path.replaceWith(newImportDeclaration);
path.stop(); // 只修改匹配到的第一条
}
@@ -564,7 +577,7 @@ export function updateImportDeclaration(ast: t.File, importedModule: IImportDecl
return ast;
}
export function updateImportDeclaration2(
export function updateImportDeclaration(
ast: t.File,
source: string,
specifiers: IImportSpecifierData[],
@@ -573,7 +586,7 @@ export function updateImportDeclaration2(
ImportDeclaration(path) {
const currentSourcePath = node2value(path.node.source);
if (currentSourcePath === source) {
const newImportDeclaration = makeImportDeclaration2(source, specifiers);
const newImportDeclaration = makeImportDeclaration(source, specifiers);
path.replaceWith(newImportDeclaration);
path.stop(); // 只修改匹配到的第一条
}
@@ -582,6 +595,32 @@ export function updateImportDeclaration2(
return ast;
}
/**
* 再已有的导入语句中添加新的导入符号
* @param ast
* @param source
* @param newSpecifiers
* @returns
*/
export function insertImportSpecifiers(
ast: t.File,
source: string,
newSpecifiers: IImportSpecifierData[],
) {
traverse(ast, {
ImportDeclaration(path) {
const currentSourcePath = node2value(path.node.source);
if (currentSourcePath === source) {
const nodes = specifierDataList2nodes(newSpecifiers);
path.node.specifiers.push(...nodes);
// 只在匹配到的第一个导入声明语句添加即可,不再重复执行
path.stop();
}
},
});
return ast;
}
/**
* 新增类属性
* @param ast
@@ -1180,7 +1219,12 @@ export function traverseViewFile(ast: t.File, idGenerator: IdGenerator) {
traverse(ast, {
ImportDeclaration(path) {
const { source, specifiers } = parseImportDeclaration(path.node);
imports[source] = specifiers;
if (imports[source]) {
// 存在重复的导入语句,合并导入符号列表
imports[source] = imports[source].concat(specifiers);
} else {
imports[source] = specifiers;
}
// FIXME: 下面的逻辑兼容旧的逻辑,后续需要移除掉
const declarationData = specifiers.reduce(
+36 -1
View File
@@ -7,12 +7,47 @@ import {
uuid,
} from '@music163/tango-helpers';
import { getRelativePath, isFilepath } from './string';
import type { IImportDeclarationPayload } from '../types';
import type { IImportDeclarationPayload, IImportSpecifierData } from '../types';
import { code2expression } from './ast';
import { isWrappedByExpressionContainer } from './assert';
export function prototype2importDeclarationData(
prototype: ComponentPrototypeType,
relativeFilepath?: string,
): { source: string; specifiers: IImportSpecifierData[] } {
let source = prototype.package;
if (relativeFilepath && isFilepath(source)) {
source = getRelativePath(relativeFilepath, source);
}
if (source.endsWith('.js')) {
source = source.slice(0, -3);
}
const specifiers: IImportSpecifierData[] = [];
if (prototype.exportType === 'defaultExport') {
specifiers.push({
localName: prototype.name,
type: 'ImportDefaultSpecifier',
});
} else {
[prototype.name, ...(prototype.relatedImports || [])].forEach((item) => {
specifiers.push({
localName: item,
type: 'ImportSpecifier',
});
});
}
return {
source,
specifiers,
};
}
/**
* 根据组件的 prototype 生成 ImportDeclarationPayload
* @deprecated
*/
export function getImportDeclarationPayloadByPrototype(
prototype: ComponentPrototypeType,
+13 -21
View File
@@ -5,12 +5,12 @@ import { DragSource } from './drag-source';
import {
IFileConfig,
FileType,
IImportDeclarationPayload,
InsertChildPositionType,
ITangoConfigPackages,
IPageConfigData,
IServiceFunctionPayload,
IImportSpecifierSourceData,
IImportSpecifierData,
} from '../types';
import { TangoFile, TangoJsonFile } from './file';
import { TangoRouteModule } from './route-module';
@@ -33,6 +33,14 @@ export interface IViewFile {
update: (code?: string, isFormatCode?: boolean, refreshWorkspace?: boolean) => void;
/**
* 添加新的导入符号
* @param source 导入来源
* @param newSpecifiers 新导入符号列表
* @returns this
*/
addImportSpecifiers: (source: string, newSpecifiers: IImportSpecifierData[]) => IViewFile;
getNode: (targetNodeId: string) => IViewNode;
removeNode: (targetNodeId: string) => IViewFile;
@@ -41,31 +49,15 @@ export interface IViewFile {
targetNodeId: string,
newNode: any,
position?: InsertChildPositionType,
sourcePrototype?: string | ComponentPrototypeType,
) => IViewFile;
insertAfter: (
targetNodeId: string,
newNode: any,
sourcePrototype?: string | ComponentPrototypeType,
) => IViewFile;
insertAfter: (targetNodeId: string, newNode: any) => IViewFile;
insertBefore: (
targetNodeId: string,
newNode: any,
sourcePrototype?: string | ComponentPrototypeType,
) => IViewFile;
insertBefore: (targetNodeId: string, newNode: any) => IViewFile;
replaceNode: (
targetNodeId: string,
newNode: any,
sourcePrototype?: string | ComponentPrototypeType,
) => IViewFile;
replaceNode: (targetNodeId: string, newNode: any) => IViewFile;
replaceViewChildren: (
rawNodes: any[],
importDeclarations?: IImportDeclarationPayload[],
) => IViewFile;
replaceViewChildren: (rawNodes: any[]) => IViewFile;
updateNodeAttribute: (
nodeId: string,
+4 -4
View File
@@ -6,8 +6,8 @@ import {
ast2code,
formatCode,
traverseFile,
addImportDeclaration2,
updateImportDeclaration2,
addImportDeclaration,
updateImportDeclaration,
} from '../helpers';
import { TangoFile } from './file';
import { IFileConfig, IImportSpecifierData, ImportDeclarationDataType } from '../types';
@@ -52,12 +52,12 @@ export class TangoModule extends TangoFile {
}
addImportDeclaration(source: string, specifiers: IImportSpecifierData[]) {
addImportDeclaration2(this.ast, source, specifiers);
this.ast = addImportDeclaration(this.ast, source, specifiers);
return this;
}
updateImportDeclaration(source: string, specifiers: IImportSpecifierData[]) {
updateImportDeclaration2(this.ast, source, specifiers);
this.ast = updateImportDeclaration(this.ast, source, specifiers);
return this;
}
+80 -93
View File
@@ -1,6 +1,6 @@
import * as t from '@babel/types';
import { action, computed, makeObservable, observable, toJS } from 'mobx';
import { ComponentPrototypeType, Dict } from '@music163/tango-helpers';
import { Dict } from '@music163/tango-helpers';
import {
ast2code,
traverseViewFile,
@@ -8,15 +8,17 @@ import {
insertSiblingAfterJSXElement,
appendChildToJSXElement,
addImportDeclaration,
updateImportDeclaration,
replaceJSXElement,
getImportDeclarationPayloadByPrototype,
removeUnusedImportSpecifiers,
insertSiblingBeforeJSXElement,
replaceRootJSXElementChildren,
IdGenerator,
updateJSXAttributes,
queryXFormItemFields,
prototype2importDeclarationData,
insertImportSpecifiers,
addImportDeclarationLegacy,
updateImportDeclarationLegacy,
} from '../helpers';
import { TangoNode } from './node';
import {
@@ -26,10 +28,57 @@ import {
InsertChildPositionType,
IImportSpecifierSourceData,
ImportDeclarationDataType,
IImportSpecifierData,
} from '../types';
import { IViewFile, IWorkspace } from './interfaces';
import { TangoModule } from './module';
/**
* 导入信息转为 变量名->来源 的 map 结构
* @param importedModules
* @returns
*/
function buildImportMap(importedModules: ImportDeclarationDataType) {
const map: Dict<IImportSpecifierSourceData> = {};
Object.keys(importedModules).forEach((source) => {
const specifiers = importedModules[source];
specifiers?.forEach((specifier) => {
map[specifier.localName] = {
source,
isDefault: specifier.type === 'ImportDefaultSpecifier',
};
});
});
return map;
}
/**
* 将节点列表转换为 tree data 嵌套数组
* @param list
*/
function nodeListToTreeData(list: ITangoViewNodeData[]) {
const map: Record<string, ITangoViewNodeData> = {};
list.forEach((item) => {
// 如果不存在,则初始化
if (!map[item.id]) {
map[item.id] = {
...item,
children: [],
};
}
// 是否找到父节点,找到则塞进去
if (item.parentId && map[item.parentId]) {
map[item.parentId].children.push(map[item.id]);
}
});
// 保留根节点
const ret = Object.values(map).filter((item) => !item.parentId);
return ret;
}
/**
* 视图模块
*/
@@ -111,7 +160,7 @@ export class TangoViewModule extends TangoModule implements IViewFile {
this._importedModules = importedModules;
this.imports = imports;
this.importMap = this.buildImportMap(imports);
this.importMap = buildImportMap(imports);
this.variables = variables;
this._nodes.clear();
@@ -172,27 +221,30 @@ export class TangoViewModule extends TangoModule implements IViewFile {
}
/**
* 基于组件的 prototype 信息更新导入信息
* TODO: 和 Module.addImportDeclaration 中的保持一致
* @deprecated
* @param prototype
* @param shouldUpdateCode
* 添加导入符号
* @param source
* @param newSpecifiers
* @returns
*/
updateImportSpecifiersByPrototype(sourcePrototype: string | ComponentPrototypeType) {
const prototype = this.workspace.getPrototype(sourcePrototype);
if (prototype) {
const importDeclaration = getImportDeclarationPayloadByPrototype(prototype, this.filename);
this.updateImportSpecifiers(importDeclaration);
addImportSpecifiers(source: string, newSpecifiers: IImportSpecifierData[]) {
const existSpecifiers = this.imports[source];
if (existSpecifiers) {
const insertedSpecifiers = newSpecifiers.filter((item) => {
return !existSpecifiers.find((existItem) => existItem.localName === item.localName);
});
this.ast = insertImportSpecifiers(this.ast, source, insertedSpecifiers);
} else {
// 不存在导入来源,直接添加新的导入语句
this.ast = addImportDeclaration(this.ast, source, newSpecifiers);
}
return this;
}
/**
* 更新导入的变量(新版)
* TODO: 和 Module.updateImportDeclaration 中的保持一致
* @deprecated
* 更新导入的变量
* @deprecated 使用 updateImportDeclaration 代替
*/
updateImportSpecifiers(importDeclaration: IImportDeclarationPayload) {
updateImportSpecifiersLegacy(importDeclaration: IImportDeclarationPayload) {
const mods = this._importedModules[importDeclaration.sourcePath];
let ast;
// 如果模块已存在,需要去重
@@ -207,12 +259,12 @@ export class TangoViewModule extends TangoModule implements IViewFile {
(name) => !specifiers.includes(name),
);
ast = updateImportDeclaration(this.ast, {
ast = updateImportDeclarationLegacy(this.ast, {
...importDeclaration,
specifiers: newSpecifiers.concat(targetMod.specifiers),
});
} else {
ast = addImportDeclaration(this.ast, importDeclaration);
ast = addImportDeclarationLegacy(this.ast, importDeclaration);
}
this.ast = ast;
return this;
@@ -257,7 +309,8 @@ export class TangoViewModule extends TangoModule implements IViewFile {
// 导入依赖的组件
relatedImports.forEach((name: string) => {
const proto = this.workspace.getPrototype(name);
this.updateImportSpecifiersByPrototype(proto);
const { source, specifiers } = prototype2importDeclarationData(proto, this.filename);
this.addImportSpecifiers(source, specifiers);
});
}
this.ast = updateJSXAttributes(this.ast, nodeId, config);
@@ -268,43 +321,25 @@ export class TangoViewModule extends TangoModule implements IViewFile {
* 插入子节点的最后面
* @param targetNodeId
* @param newNode
* @param sourceName
* @param position
* @returns
*/
insertChild(
targetNodeId: string,
newNode: t.JSXElement,
position: InsertChildPositionType = 'last',
sourceName: string | ComponentPrototypeType,
) {
this.ast = appendChildToJSXElement(this.ast, targetNodeId, newNode, position);
if (sourceName) {
this.updateImportSpecifiersByPrototype(sourceName);
}
return this;
}
insertAfter(
targetNodeId: string,
newNode: t.JSXElement,
sourceName?: string | ComponentPrototypeType,
) {
insertAfter(targetNodeId: string, newNode: t.JSXElement) {
this.ast = insertSiblingAfterJSXElement(this.ast, targetNodeId, newNode);
if (sourceName) {
this.updateImportSpecifiersByPrototype(sourceName);
}
return this;
}
insertBefore(
targetNodeId: string,
newNode: t.JSXElement,
sourceName?: string | ComponentPrototypeType,
) {
insertBefore(targetNodeId: string, newNode: t.JSXElement) {
this.ast = insertSiblingBeforeJSXElement(this.ast, targetNodeId, newNode);
if (sourceName) {
this.updateImportSpecifiersByPrototype(sourceName);
}
return this;
}
@@ -312,22 +347,15 @@ export class TangoViewModule extends TangoModule implements IViewFile {
* 替换目标节点为新节点
* @param targetNodeId
* @param newNode
* @param sourcePrototype
*/
replaceNode(
targetNodeId: string,
newNode: t.JSXElement,
sourceName?: string | ComponentPrototypeType,
) {
replaceNode(targetNodeId: string, newNode: t.JSXElement) {
this.ast = replaceJSXElement(this.ast, targetNodeId, newNode);
if (sourceName) {
this.updateImportSpecifiersByPrototype(sourceName);
}
return this;
}
/**
* 替换 jsx 跟结点的子元素
* @deprecated 不推荐使用
*/
replaceViewChildren(
childrenNodes: t.JSXElement[],
@@ -339,51 +367,10 @@ export class TangoViewModule extends TangoModule implements IViewFile {
if (importDeclarations?.length) {
importDeclarations.forEach((item) => {
this.updateImportSpecifiers(item);
this.updateImportSpecifiersLegacy(item);
});
}
return this;
}
private buildImportMap(importedModules: ImportDeclarationDataType) {
const map: Dict<IImportSpecifierSourceData> = {};
Object.keys(importedModules).forEach((source) => {
const specifiers = importedModules[source];
specifiers?.forEach((specifier) => {
map[specifier.localName] = {
source,
isDefault: specifier.type === 'ImportDefaultSpecifier',
};
});
});
return map;
}
}
/**
* 将节点列表转换为 tree data 嵌套数组
* @param list
*/
function nodeListToTreeData(list: ITangoViewNodeData[]) {
const map: Record<string, ITangoViewNodeData> = {};
list.forEach((item) => {
// 如果不存在,则初始化
if (!map[item.id]) {
map[item.id] = {
...item,
children: [],
};
}
// 是否找到父节点,找到则塞进去
if (item.parentId && map[item.parentId]) {
map[item.parentId].children.push(map[item.id]);
}
});
// 保留根节点
const ret = Object.values(map).filter((item) => !item.parentId);
return ret;
}
+32 -9
View File
@@ -17,6 +17,7 @@ import {
namesToImportDeclarations,
getBlockNameByFilename,
getPrivilegeCode,
prototype2importDeclarationData,
} from '../helpers';
import { DropMethod } from './drop-target';
import { HistoryMessage, TangoHistory } from './history';
@@ -950,7 +951,7 @@ export class Workspace extends EventTarget implements IWorkspace {
);
importDeclarations.forEach((importDeclaration) => {
this.activeViewModule.updateImportSpecifiers(importDeclaration);
this.activeViewModule.updateImportSpecifiersLegacy(importDeclaration);
});
this.copyTempNodes.forEach((node) => {
@@ -1001,7 +1002,11 @@ export class Workspace extends EventTarget implements IWorkspace {
const sourcePrototype = this.getPrototype(sourceName);
const newNode = prototype2jsxElement(sourcePrototype);
const file = this.getNode(targetNodeId).file;
file.insertChild(targetNodeId, newNode, 'last', sourcePrototype).update();
const { source, specifiers } = prototype2importDeclarationData(sourcePrototype, file.filename);
file
.insertChild(targetNodeId, newNode, 'last')
.addImportSpecifiers(source, specifiers)
.update();
this.history.push({
message: HistoryMessage.InsertNode,
data: {
@@ -1021,7 +1026,8 @@ export class Workspace extends EventTarget implements IWorkspace {
const sourcePrototype = this.getPrototype(sourceName);
const newNode = prototype2jsxElement(sourcePrototype);
const file = this.getNode(targetNodeId).file;
file.replaceNode(targetNodeId, newNode, sourcePrototype).update();
const { source, specifiers } = prototype2importDeclarationData(sourcePrototype, file.filename);
file.replaceNode(targetNodeId, newNode).addImportSpecifiers(source, specifiers).update();
this.history.push({
message: HistoryMessage.ReplaceNode,
data: {
@@ -1039,7 +1045,14 @@ export class Workspace extends EventTarget implements IWorkspace {
if (insertedPrototype) {
const newNode = prototype2jsxElement(insertedPrototype);
const file = this.selectSource.file;
file.insertChild(this.selectSource.first.id, newNode, 'last', insertedPrototype).update();
const { source, specifiers } = prototype2importDeclarationData(
insertedPrototype,
file.filename,
);
file
.insertChild(this.selectSource.first.id, newNode, 'last')
.addImportSpecifiers(source, specifiers)
.update();
this.history.push({
message: HistoryMessage.InsertNode,
data: {
@@ -1095,30 +1108,40 @@ export class Workspace extends EventTarget implements IWorkspace {
const targetFile = dropTarget.node?.file;
const sourceFile = dragSource.node?.file;
// dragSourcePrototype to importDeclarations
const { source, specifiers } = prototype2importDeclarationData(
dragSourcePrototype,
targetFile.filename,
);
let isValidOperation = true;
switch (dropTarget.method) {
// 直接往目标节点的 children 里添加一个节点
case DropMethod.InsertChild: {
targetFile.insertChild(dropTarget.id, newNode, 'last', dragSourcePrototype);
targetFile
.insertChild(dropTarget.id, newNode, 'last')
.addImportSpecifiers(source, specifiers);
break;
}
case DropMethod.InsertFirstChild: {
targetFile.insertChild(dropTarget.id, newNode, 'first', dragSourcePrototype);
targetFile
.insertChild(dropTarget.id, newNode, 'first')
.addImportSpecifiers(source, specifiers);
break;
}
// 往目标节点的后边插入一个节点
case DropMethod.InsertAfter: {
targetFile.insertAfter(dropTarget.id, newNode, dragSourcePrototype);
targetFile.insertAfter(dropTarget.id, newNode).addImportSpecifiers(source, specifiers);
break;
}
// 往目标节点的前方插入一个节点
case DropMethod.InsertBefore: {
targetFile.insertBefore(dropTarget.id, newNode, dragSourcePrototype);
targetFile.insertBefore(dropTarget.id, newNode).addImportSpecifiers(source, specifiers);
break;
}
// 替换目标节点
case DropMethod.ReplaceNode: {
targetFile.replaceNode(dropTarget.id, newNode, dragSourcePrototype);
targetFile.replaceNode(dropTarget.id, newNode).addImportSpecifiers(source, specifiers);
break;
}
default:
-143
View File
@@ -33,94 +33,11 @@ export type OptionType = {
relatedImports?: string[];
};
type TangoSchemaTreeNodePropValueBaseType = {
value: string | number | boolean;
rawCode: string;
};
type TangoSchemaTreeNodePropValueSlotType = {
type: 'Slot';
value: TangoSchemaTreeNodeType;
};
type TangoSchemaTreeNodePropValueType =
| string
| number
| boolean
| object
| TangoSchemaTreeNodePropValueBaseType
| TangoSchemaTreeNodePropValueSlotType;
export type TangoSchemaTreeNodeType = {
/**
* 节点唯一标识
*/
id?: string;
/**
* 节点组件名
*/
component?: string;
/**
* 节点属性集合
*/
props?: Record<string, TangoSchemaTreeNodePropValueType>;
/**
* 节点是否渲染
* TODO: 支持变量表达式
*/
isRender?: boolean;
/**
* 子节点
*/
children?: TangoSchemaTreeNodeType[];
};
/**
* 服务函数类型
*/
export type ServiceFunctionType = (...args: any[]) => Promise<any>;
export type TangoRemoteServicesType = {
/**
* 图片服务
*/
ImageService?: {
listMy: ServiceFunctionType;
listFav: ServiceFunctionType;
listPub: ServiceFunctionType;
};
/**
* 数据源服务
*/
OxService?: {
listApp: ServiceFunctionType;
listBranch: ServiceFunctionType;
listApi: ServiceFunctionType;
listApiByPage: ServiceFunctionType;
};
/**
* 依赖面板服务
*/
DependencyService?: {
listBizDependencies: ServiceFunctionType;
listBaseDependencies: ServiceFunctionType;
listPackageVersions: ServiceFunctionType;
};
RiddleService?: {
listBlock: ServiceFunctionType;
postBlock: ServiceFunctionType;
updateBlock: ServiceFunctionType;
};
/**
* AIGC 服务
*/
GptService?: {
codeCompletion?: ServiceFunctionType;
textCompletion?: ServiceFunctionType;
textEmbedding?: ServiceFunctionType;
};
};
export type RelatedDependencyType = { name: string; version: string };
/**
@@ -163,63 +80,3 @@ export type SetterOnChangeDetailType = {
relatedImports?: string[];
isRawCode?: boolean;
};
/**
* 智能向导生成类型
*/
export enum WizardType {
NEW = 'new',
REPLACE = 'replace',
PREVIEW = 'preview',
}
/**
* 智能向导OX模型定义
*/
export interface IOXModel {
key: string; // 唯一标识 (字段名加哈希值)
name: string; // 字段名
description: string; // 字段描述
basicDataModelName: 'List' | 'Integer' | 'int' | 'String' | 'long' | 'boolean' | 'ENUM'; // 字段类型
dataModelFieldDTOList: IOXModel[];
type: 'ARRAY' | 'BASIC' | 'CLASS' | 'GENERIC' | 'ENUM' | 'MAP';
extra: IOXModel;
extras: IOXModel[];
linkedDataModelName: String;
linkedModelDTO: {
type: 'ARRAY' | 'BASIC' | 'CLASS' | 'GENERIC' | 'ENUM' | 'MAP';
fieldDTOList: IOXModel[];
};
paramType: 'RequestParam' | 'JsonRequestParam'; // 请求传参类型
}
/**
* 通用智能向导
*/
type ChildType = Array<Record<string, any>>;
export type IDataProviderFormProps = {
loadData: string;
payload: Record<string, any>;
model: string;
formatter: (res: any) => any;
};
export interface CommonGuideFormValueType {
fatherComponentName: string;
fatherProps: Record<string, any>;
childComponentName: string;
children: ChildType;
dataProviderProps: IDataProviderFormProps;
childPropsConfig: {
// 字段名对应属性名
fieldName: string;
// 字段注释对应属性名
fieldDescriptionName: string;
// 字段值类型对应属性类型 (暂时用不到)
fieldType?: string;
};
}
/**
* end
*/
+2 -2
View File
@@ -15,8 +15,8 @@ export type PartialRecord<K extends keyof any, T> = {
[P in K]?: T;
};
export type ReactComponentProps = {
export interface ReactComponentProps {
children?: React.ReactNode;
style?: React.CSSProperties;
className?: string;
};
}