mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-29 09:44:47 +00:00
perf:change plugin version update position (#1493)
* perf:change plugin version update position * use nodeversion
This commit is contained in:
2
packages/global/core/plugin/type.d.ts
vendored
2
packages/global/core/plugin/type.d.ts
vendored
@@ -23,6 +23,7 @@ export type PluginItemSchema = {
|
|||||||
customHeaders?: string;
|
customHeaders?: string;
|
||||||
};
|
};
|
||||||
version?: 'v1' | 'v2';
|
version?: 'v1' | 'v2';
|
||||||
|
nodeVersion?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* plugin template */
|
/* plugin template */
|
||||||
@@ -32,6 +33,7 @@ export type PluginTemplateType = PluginRuntimeType & {
|
|||||||
source: `${PluginSourceEnum}`;
|
source: `${PluginSourceEnum}`;
|
||||||
templateType: FlowNodeTemplateType['templateType'];
|
templateType: FlowNodeTemplateType['templateType'];
|
||||||
intro: string;
|
intro: string;
|
||||||
|
nodeVersion: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PluginRuntimeType = {
|
export type PluginRuntimeType = {
|
||||||
|
@@ -64,6 +64,7 @@ export type FlowNodeTemplateType = FlowNodeCommonType & {
|
|||||||
// action
|
// action
|
||||||
forbidDelete?: boolean; // forbid delete
|
forbidDelete?: boolean; // forbid delete
|
||||||
unique?: boolean;
|
unique?: boolean;
|
||||||
|
nodeVersion?: string;
|
||||||
};
|
};
|
||||||
export type FlowNodeItemType = FlowNodeTemplateType & {
|
export type FlowNodeItemType = FlowNodeTemplateType & {
|
||||||
nodeId: string;
|
nodeId: string;
|
||||||
|
@@ -52,7 +52,8 @@ const getPluginTemplateById = async (id: string): Promise<PluginTemplateType> =>
|
|||||||
nodes: item.modules,
|
nodes: item.modules,
|
||||||
edges: item.edges,
|
edges: item.edges,
|
||||||
templateType: FlowNodeTemplateTypeEnum.personalPlugin,
|
templateType: FlowNodeTemplateTypeEnum.personalPlugin,
|
||||||
isTool: true
|
isTool: true,
|
||||||
|
nodeVersion: item?.nodeVersion || ''
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return Promise.reject('plugin not found');
|
return Promise.reject('plugin not found');
|
||||||
@@ -72,6 +73,7 @@ export async function getPluginPreviewNode({ id }: { id: string }): Promise<Flow
|
|||||||
intro: plugin.intro,
|
intro: plugin.intro,
|
||||||
showStatus: plugin.showStatus,
|
showStatus: plugin.showStatus,
|
||||||
isTool: plugin.isTool,
|
isTool: plugin.isTool,
|
||||||
|
nodeVersion: plugin.nodeVersion,
|
||||||
version: '481',
|
version: '481',
|
||||||
sourceHandle: getHandleConfig(true, true, true, true),
|
sourceHandle: getHandleConfig(true, true, true, true),
|
||||||
targetHandle: getHandleConfig(true, true, true, true),
|
targetHandle: getHandleConfig(true, true, true, true),
|
||||||
|
@@ -64,6 +64,10 @@ const PluginSchema = new Schema({
|
|||||||
version: {
|
version: {
|
||||||
type: String,
|
type: String,
|
||||||
enum: ['v1', 'v2']
|
enum: ['v1', 'v2']
|
||||||
|
},
|
||||||
|
nodeVersion: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -62,7 +62,7 @@ export const valueTypeFormat = (value: any, type?: WorkflowIOValueTypeEnum) => {
|
|||||||
return JSON.stringify(value);
|
return JSON.stringify(value);
|
||||||
}
|
}
|
||||||
if (type === 'number') return Number(value);
|
if (type === 'number') return Number(value);
|
||||||
if (type === 'boolean') return Boolean(value);
|
if (type === 'boolean') return value === 'true' ? true : false;
|
||||||
try {
|
try {
|
||||||
if (type === WorkflowIOValueTypeEnum.datasetQuote && !Array.isArray(value)) {
|
if (type === WorkflowIOValueTypeEnum.datasetQuote && !Array.isArray(value)) {
|
||||||
return JSON.parse(value);
|
return JSON.parse(value);
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
},
|
},
|
||||||
"module": {
|
"module": {
|
||||||
"Combine Modules": "Combine Modules",
|
"Combine Modules": "Combine Modules",
|
||||||
|
"Confirm Sync": "Using the latest template will overwrite the existing one and may result in the loss of some previous configuration information. Please confirm.",
|
||||||
"Custom Title Tip": "This title will be displayed during the conversation",
|
"Custom Title Tip": "This title will be displayed during the conversation",
|
||||||
"My Modules": "My Modules",
|
"My Modules": "My Modules",
|
||||||
"No Modules": "No modules yet~",
|
"No Modules": "No modules yet~",
|
||||||
|
@@ -38,6 +38,7 @@
|
|||||||
},
|
},
|
||||||
"module": {
|
"module": {
|
||||||
"Combine Modules": "组合模块",
|
"Combine Modules": "组合模块",
|
||||||
|
"Confirm Sync": "将会使用最新模板进行覆盖,可能会丢失一些旧的配置信息,请确认",
|
||||||
"Custom Title Tip": "该标题名字会展示在对话过程中",
|
"Custom Title Tip": "该标题名字会展示在对话过程中",
|
||||||
"My Modules": "",
|
"My Modules": "",
|
||||||
"No Modules": "还没有模块~",
|
"No Modules": "还没有模块~",
|
||||||
|
@@ -1,13 +1,15 @@
|
|||||||
import React, { useCallback, useMemo } from 'react';
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { Box, Button, Card, Flex } from '@chakra-ui/react';
|
import { Box, Button, Card, Flex } from '@chakra-ui/react';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
import Avatar from '@/components/Avatar';
|
import Avatar from '@/components/Avatar';
|
||||||
import type { FlowNodeItemType } from '@fastgpt/global/core/workflow/type/index.d';
|
import type {
|
||||||
|
FlowNodeItemType,
|
||||||
|
FlowNodeTemplateType
|
||||||
|
} from '@fastgpt/global/core/workflow/type/index.d';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useEditTitle } from '@/web/common/hooks/useEditTitle';
|
import { useEditTitle } from '@/web/common/hooks/useEditTitle';
|
||||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||||
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
|
||||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||||
import { LOGO_ICON } from '@fastgpt/global/common/system/constants';
|
import { LOGO_ICON } from '@fastgpt/global/common/system/constants';
|
||||||
import { ToolTargetHandle } from './Handle/ToolHandle';
|
import { ToolTargetHandle } from './Handle/ToolHandle';
|
||||||
@@ -17,7 +19,6 @@ import { useDebug } from '../../hooks/useDebug';
|
|||||||
import { ResponseBox } from '@/components/ChatBox/WholeResponseModal';
|
import { ResponseBox } from '@/components/ChatBox/WholeResponseModal';
|
||||||
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
||||||
import { getPreviewPluginModule } from '@/web/core/plugin/api';
|
import { getPreviewPluginModule } from '@/web/core/plugin/api';
|
||||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
|
||||||
import { storeNode2FlowNode, updateFlowNodeVersion } from '@/web/core/workflow/utils';
|
import { storeNode2FlowNode, updateFlowNodeVersion } from '@/web/core/workflow/utils';
|
||||||
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
||||||
import { useContextSelector } from 'use-context-selector';
|
import { useContextSelector } from 'use-context-selector';
|
||||||
@@ -26,6 +27,8 @@ import { useI18n } from '@/web/context/I18n';
|
|||||||
import { moduleTemplatesFlat } from '@fastgpt/global/core/workflow/template/constants';
|
import { moduleTemplatesFlat } from '@fastgpt/global/core/workflow/template/constants';
|
||||||
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||||
import MyTooltip from '@/components/MyTooltip';
|
import MyTooltip from '@/components/MyTooltip';
|
||||||
|
import { isEqual } from 'lodash';
|
||||||
|
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||||
|
|
||||||
type Props = FlowNodeItemType & {
|
type Props = FlowNodeItemType & {
|
||||||
children?: React.ReactNode | React.ReactNode[] | string;
|
children?: React.ReactNode | React.ReactNode[] | string;
|
||||||
@@ -69,6 +72,9 @@ const NodeCard = (props: Props) => {
|
|||||||
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
|
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
|
||||||
const onResetNode = useContextSelector(WorkflowContext, (v) => v.onResetNode);
|
const onResetNode = useContextSelector(WorkflowContext, (v) => v.onResetNode);
|
||||||
|
|
||||||
|
const [hasNewVersion, setHasNewVersion] = useState(false);
|
||||||
|
const { setLoading } = useSystemStore();
|
||||||
|
|
||||||
// custom title edit
|
// custom title edit
|
||||||
const { onOpenModal: onOpenCustomTitleModal, EditModal: EditTitleModal } = useEditTitle({
|
const { onOpenModal: onOpenCustomTitleModal, EditModal: EditTitleModal } = useEditTitle({
|
||||||
title: t('common.Custom Title'),
|
title: t('common.Custom Title'),
|
||||||
@@ -81,13 +87,50 @@ const NodeCard = (props: Props) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const node = nodeList.find((node) => node.nodeId === nodeId);
|
const node = nodeList.find((node) => node.nodeId === nodeId);
|
||||||
|
const { openConfirm: onOpenConfirmSync, ConfirmModal: ConfirmSyncModal } = useConfirm({
|
||||||
|
content: appT('module.Confirm Sync')
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchPluginModule = async () => {
|
||||||
|
if (node?.flowNodeType === FlowNodeTypeEnum.pluginModule) {
|
||||||
|
if (!node?.pluginId) return;
|
||||||
|
const template = await getPreviewPluginModule(node.pluginId);
|
||||||
|
setHasNewVersion(!!template.nodeVersion && node.nodeVersion !== template.nodeVersion);
|
||||||
|
} else {
|
||||||
|
const template = moduleTemplatesFlat.find(
|
||||||
|
(item) => item.flowNodeType === node?.flowNodeType
|
||||||
|
);
|
||||||
|
setHasNewVersion(node?.version !== template?.version);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchPluginModule();
|
||||||
|
}, [node]);
|
||||||
|
|
||||||
const template = moduleTemplatesFlat.find((item) => item.flowNodeType === node?.flowNodeType);
|
const template = moduleTemplatesFlat.find((item) => item.flowNodeType === node?.flowNodeType);
|
||||||
const hasNewVersion = useMemo(() => {
|
|
||||||
return (
|
const onClickSyncVersion = useCallback(async () => {
|
||||||
template?.flowNodeType !== FlowNodeTypeEnum.pluginModule &&
|
try {
|
||||||
node?.version !== template?.version
|
setLoading(true);
|
||||||
);
|
if (!node || !template) return;
|
||||||
}, [node?.version, template?.flowNodeType, template?.version]);
|
if (node?.flowNodeType === 'pluginModule') {
|
||||||
|
if (!node.pluginId) return;
|
||||||
|
onResetNode({
|
||||||
|
id: nodeId,
|
||||||
|
node: await getPreviewPluginModule(node.pluginId)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
onResetNode({
|
||||||
|
id: nodeId,
|
||||||
|
node: updateFlowNodeVersion(node, template)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching plugin module:', error);
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
|
}, [node, nodeId, onResetNode, setLoading, template]);
|
||||||
|
|
||||||
/* Node header */
|
/* Node header */
|
||||||
const Header = useMemo(() => {
|
const Header = useMemo(() => {
|
||||||
@@ -149,13 +192,7 @@ const NodeCard = (props: Props) => {
|
|||||||
fontWeight={'medium'}
|
fontWeight={'medium'}
|
||||||
cursor={'pointer'}
|
cursor={'pointer'}
|
||||||
_hover={{ bg: 'yellow.100' }}
|
_hover={{ bg: 'yellow.100' }}
|
||||||
onClick={() => {
|
onClick={onOpenConfirmSync(onClickSyncVersion)}
|
||||||
if (!node || !template) return;
|
|
||||||
onResetNode({
|
|
||||||
id: nodeId,
|
|
||||||
node: updateFlowNodeVersion(node, template)
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Box>{appT('app.modules.has new version')}</Box>
|
<Box>{appT('app.modules.has new version')}</Box>
|
||||||
<QuestionOutlineIcon ml={1} />
|
<QuestionOutlineIcon ml={1} />
|
||||||
@@ -171,6 +208,7 @@ const NodeCard = (props: Props) => {
|
|||||||
/>
|
/>
|
||||||
<NodeIntro nodeId={nodeId} intro={intro} />
|
<NodeIntro nodeId={nodeId} intro={intro} />
|
||||||
</Box>
|
</Box>
|
||||||
|
<ConfirmSyncModal />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}, [
|
}, [
|
||||||
@@ -181,16 +219,16 @@ const NodeCard = (props: Props) => {
|
|||||||
name,
|
name,
|
||||||
menuForbid,
|
menuForbid,
|
||||||
hasNewVersion,
|
hasNewVersion,
|
||||||
|
appT,
|
||||||
|
onOpenConfirmSync,
|
||||||
|
onClickSyncVersion,
|
||||||
pluginId,
|
pluginId,
|
||||||
flowNodeType,
|
flowNodeType,
|
||||||
intro,
|
intro,
|
||||||
|
ConfirmSyncModal,
|
||||||
onOpenCustomTitleModal,
|
onOpenCustomTitleModal,
|
||||||
onChangeNode,
|
onChangeNode,
|
||||||
toast,
|
toast
|
||||||
appT,
|
|
||||||
node,
|
|
||||||
template,
|
|
||||||
onResetNode
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -249,21 +287,14 @@ const MenuRender = React.memo(function MenuRender({
|
|||||||
menuForbid?: Props['menuForbid'];
|
menuForbid?: Props['menuForbid'];
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { toast } = useToast();
|
|
||||||
const { setLoading } = useSystemStore();
|
|
||||||
const { openDebugNode, DebugInputModal } = useDebug();
|
const { openDebugNode, DebugInputModal } = useDebug();
|
||||||
|
|
||||||
const { openConfirm: onOpenConfirmSync, ConfirmModal: ConfirmSyncModal } = useConfirm({
|
|
||||||
content: t('module.Confirm Sync Plugin')
|
|
||||||
});
|
|
||||||
|
|
||||||
const { openConfirm: onOpenConfirmDeleteNode, ConfirmModal: ConfirmDeleteModal } = useConfirm({
|
const { openConfirm: onOpenConfirmDeleteNode, ConfirmModal: ConfirmDeleteModal } = useConfirm({
|
||||||
content: t('core.module.Confirm Delete Node'),
|
content: t('core.module.Confirm Delete Node'),
|
||||||
type: 'delete'
|
type: 'delete'
|
||||||
});
|
});
|
||||||
|
|
||||||
const setNodes = useContextSelector(WorkflowContext, (v) => v.setNodes);
|
const setNodes = useContextSelector(WorkflowContext, (v) => v.setNodes);
|
||||||
const onResetNode = useContextSelector(WorkflowContext, (v) => v.onResetNode);
|
|
||||||
const setEdges = useContextSelector(WorkflowContext, (v) => v.setEdges);
|
const setEdges = useContextSelector(WorkflowContext, (v) => v.setEdges);
|
||||||
|
|
||||||
const onCopyNode = useCallback(
|
const onCopyNode = useCallback(
|
||||||
@@ -310,22 +341,6 @@ const MenuRender = React.memo(function MenuRender({
|
|||||||
},
|
},
|
||||||
[setEdges, setNodes]
|
[setEdges, setNodes]
|
||||||
);
|
);
|
||||||
const onClickSyncVersion = useCallback(async () => {
|
|
||||||
if (!pluginId) return;
|
|
||||||
try {
|
|
||||||
setLoading(true);
|
|
||||||
onResetNode({
|
|
||||||
id: nodeId,
|
|
||||||
node: await getPreviewPluginModule(pluginId)
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
return toast({
|
|
||||||
status: 'error',
|
|
||||||
title: getErrText(e, t('plugin.Get Plugin Module Detail Failed'))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
setLoading(false);
|
|
||||||
}, [nodeId, onResetNode, pluginId, setLoading, t, toast]);
|
|
||||||
|
|
||||||
const Render = useMemo(() => {
|
const Render = useMemo(() => {
|
||||||
const menuList = [
|
const menuList = [
|
||||||
@@ -349,17 +364,6 @@ const MenuRender = React.memo(function MenuRender({
|
|||||||
onClick: () => onCopyNode(nodeId)
|
onClick: () => onCopyNode(nodeId)
|
||||||
}
|
}
|
||||||
]),
|
]),
|
||||||
...(flowNodeType === FlowNodeTypeEnum.pluginModule
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
icon: 'common/refreshLight',
|
|
||||||
label: t('plugin.Synchronous version'),
|
|
||||||
variant: 'whiteBase',
|
|
||||||
onClick: onOpenConfirmSync(onClickSyncVersion)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
: []),
|
|
||||||
|
|
||||||
...(menuForbid?.delete
|
...(menuForbid?.delete
|
||||||
? []
|
? []
|
||||||
: [
|
: [
|
||||||
@@ -401,7 +405,6 @@ const MenuRender = React.memo(function MenuRender({
|
|||||||
</Box>
|
</Box>
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
<ConfirmSyncModal />
|
|
||||||
<ConfirmDeleteModal />
|
<ConfirmDeleteModal />
|
||||||
<DebugInputModal />
|
<DebugInputModal />
|
||||||
</>
|
</>
|
||||||
@@ -411,11 +414,7 @@ const MenuRender = React.memo(function MenuRender({
|
|||||||
menuForbid?.copy,
|
menuForbid?.copy,
|
||||||
menuForbid?.delete,
|
menuForbid?.delete,
|
||||||
t,
|
t,
|
||||||
flowNodeType,
|
|
||||||
onOpenConfirmSync,
|
|
||||||
onClickSyncVersion,
|
|
||||||
onOpenConfirmDeleteNode,
|
onOpenConfirmDeleteNode,
|
||||||
ConfirmSyncModal,
|
|
||||||
ConfirmDeleteModal,
|
ConfirmDeleteModal,
|
||||||
DebugInputModal,
|
DebugInputModal,
|
||||||
openDebugNode,
|
openDebugNode,
|
||||||
|
@@ -22,7 +22,8 @@ export const flowNode2StoreNodes = ({
|
|||||||
version: item.data.version,
|
version: item.data.version,
|
||||||
inputs: item.data.inputs,
|
inputs: item.data.inputs,
|
||||||
outputs: item.data.outputs,
|
outputs: item.data.outputs,
|
||||||
pluginId: item.data.pluginId
|
pluginId: item.data.pluginId,
|
||||||
|
nodeVersion: item.data.nodeVersion
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// get all handle
|
// get all handle
|
||||||
|
@@ -7,6 +7,8 @@ import { MongoPlugin } from '@fastgpt/service/core/plugin/schema';
|
|||||||
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
||||||
import { ClientSession } from '@fastgpt/service/common/mongo';
|
import { ClientSession } from '@fastgpt/service/common/mongo';
|
||||||
import { httpApiSchema2Plugins } from '@fastgpt/global/core/plugin/httpPlugin/utils';
|
import { httpApiSchema2Plugins } from '@fastgpt/global/core/plugin/httpPlugin/utils';
|
||||||
|
import { isEqual } from 'lodash';
|
||||||
|
import { nanoid } from 'nanoid';
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||||
try {
|
try {
|
||||||
@@ -22,7 +24,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
|||||||
per: 'owner'
|
per: 'owner'
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateData = {
|
const originPlugin = await MongoPlugin.findById(id);
|
||||||
|
|
||||||
|
let updateData = {
|
||||||
name: props.name,
|
name: props.name,
|
||||||
intro: props.intro,
|
intro: props.intro,
|
||||||
avatar: props.avatar,
|
avatar: props.avatar,
|
||||||
@@ -32,9 +36,26 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
|||||||
modules: modules
|
modules: modules
|
||||||
}),
|
}),
|
||||||
...(edges?.length && { edges }),
|
...(edges?.length && { edges }),
|
||||||
metadata: props.metadata
|
metadata: props.metadata,
|
||||||
|
nodeVersion: originPlugin?.nodeVersion
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isNodeVersionEqual =
|
||||||
|
isEqual(
|
||||||
|
originPlugin?.modules.map((module) => {
|
||||||
|
return { ...module, position: undefined };
|
||||||
|
}),
|
||||||
|
updateData.modules?.map((module) => {
|
||||||
|
return { ...module, position: undefined };
|
||||||
|
})
|
||||||
|
) && isEqual(originPlugin?.edges, updateData.edges);
|
||||||
|
|
||||||
|
if (!isNodeVersionEqual) {
|
||||||
|
updateData = {
|
||||||
|
...updateData,
|
||||||
|
nodeVersion: nanoid(6)
|
||||||
|
};
|
||||||
|
}
|
||||||
if (props.metadata?.apiSchemaStr) {
|
if (props.metadata?.apiSchemaStr) {
|
||||||
await mongoSessionRun(async (session) => {
|
await mongoSessionRun(async (session) => {
|
||||||
// update children
|
// update children
|
||||||
|
Reference in New Issue
Block a user