mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-31 05:19:53 +00:00
[Manager] Preview the individual nodes for packs on the registry (#3408)
Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
@@ -4,7 +4,10 @@
|
||||
<div class="top-0 z-10 px-6 pt-6 w-full">
|
||||
<InfoPanelHeader :node-packs="[nodePack]" />
|
||||
</div>
|
||||
<div class="p-6 pt-2 overflow-y-auto flex-1 text-sm hidden-scrollbar">
|
||||
<div
|
||||
ref="scrollContainer"
|
||||
class="p-6 pt-2 overflow-y-auto flex-1 text-sm hidden-scrollbar"
|
||||
>
|
||||
<div class="mb-6">
|
||||
<MetadataRow
|
||||
v-if="isPackInstalled(nodePack.id)"
|
||||
@@ -46,7 +49,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { whenever } from '@vueuse/core'
|
||||
import { useScroll, whenever } from '@vueuse/core'
|
||||
import { computed, provide, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
@@ -70,6 +73,8 @@ const { nodePack } = defineProps<{
|
||||
nodePack: components['schemas']['Node']
|
||||
}>()
|
||||
|
||||
const scrollContainer = ref<HTMLElement | null>(null)
|
||||
|
||||
const managerStore = useComfyManagerStore()
|
||||
const isInstalled = computed(() => managerStore.isPackInstalled(nodePack.id))
|
||||
const isInstalling = ref(false)
|
||||
@@ -103,6 +108,17 @@ const infoItems = computed<InfoItem[]>(() => [
|
||||
: undefined
|
||||
}
|
||||
])
|
||||
|
||||
const { y } = useScroll(scrollContainer, {
|
||||
eventListenerOptions: {
|
||||
passive: true
|
||||
}
|
||||
})
|
||||
const onNodePackChange = () => {
|
||||
y.value = 0
|
||||
}
|
||||
|
||||
whenever(() => nodePack, onNodePackChange, { immediate: true, deep: true })
|
||||
</script>
|
||||
<style scoped>
|
||||
.hidden-scrollbar {
|
||||
|
||||
@@ -31,28 +31,29 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useAsyncState } from '@vueuse/core'
|
||||
import { computed } from 'vue'
|
||||
import { computed, onUnmounted } from 'vue'
|
||||
|
||||
import PackStatusMessage from '@/components/dialog/content/manager/PackStatusMessage.vue'
|
||||
import PackInstallButton from '@/components/dialog/content/manager/button/PackInstallButton.vue'
|
||||
import InfoPanelHeader from '@/components/dialog/content/manager/infoPanel/InfoPanelHeader.vue'
|
||||
import MetadataRow from '@/components/dialog/content/manager/infoPanel/MetadataRow.vue'
|
||||
import PackIconStacked from '@/components/dialog/content/manager/packIcon/PackIconStacked.vue'
|
||||
import { useComfyRegistryService } from '@/services/comfyRegistryService'
|
||||
import { useComfyRegistryStore } from '@/stores/comfyRegistryStore'
|
||||
import { components } from '@/types/comfyRegistryTypes'
|
||||
|
||||
const { nodePacks } = defineProps<{
|
||||
nodePacks: components['schemas']['Node'][]
|
||||
}>()
|
||||
|
||||
const comfyRegistryService = useComfyRegistryService()
|
||||
const { getNodeDefs } = useComfyRegistryStore()
|
||||
|
||||
const getPackNodes = async (pack: components['schemas']['Node']) => {
|
||||
if (!comfyRegistryService.packNodesAvailable(pack)) return []
|
||||
return comfyRegistryService.getNodeDefs({
|
||||
if (!pack.latest_version?.version) return []
|
||||
const nodeDefs = await getNodeDefs.call({
|
||||
packId: pack.id,
|
||||
versionId: pack.latest_version?.id
|
||||
version: pack.latest_version?.version
|
||||
})
|
||||
return nodeDefs?.comfy_nodes ?? []
|
||||
}
|
||||
|
||||
const { state: allNodeDefs } = useAsyncState(
|
||||
@@ -69,4 +70,8 @@ const totalNodesCount = computed(() =>
|
||||
0
|
||||
)
|
||||
)
|
||||
|
||||
onUnmounted(() => {
|
||||
getNodeDefs.cancel()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<DescriptionTabPanel :node-pack="nodePack" />
|
||||
</TabPanel>
|
||||
<TabPanel value="nodes">
|
||||
<NodesTabPanel :node-pack="nodePack" />
|
||||
<NodesTabPanel :node-pack="nodePack" :node-names="nodeNames" />
|
||||
</TabPanel>
|
||||
</TabPanels>
|
||||
</Tabs>
|
||||
@@ -27,15 +27,21 @@ import TabList from 'primevue/tablist'
|
||||
import TabPanel from 'primevue/tabpanel'
|
||||
import TabPanels from 'primevue/tabpanels'
|
||||
import Tabs from 'primevue/tabs'
|
||||
import { ref } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import DescriptionTabPanel from '@/components/dialog/content/manager/infoPanel/tabs/DescriptionTabPanel.vue'
|
||||
import NodesTabPanel from '@/components/dialog/content/manager/infoPanel/tabs/NodesTabPanel.vue'
|
||||
import { components } from '@/types/comfyRegistryTypes'
|
||||
|
||||
defineProps<{
|
||||
const { nodePack } = defineProps<{
|
||||
nodePack: components['schemas']['Node']
|
||||
}>()
|
||||
|
||||
const nodeNames = computed(() => {
|
||||
// @ts-expect-error comfy_nodes is an Algolia-specific field
|
||||
const { comfy_nodes } = nodePack
|
||||
return comfy_nodes ?? []
|
||||
})
|
||||
|
||||
const activeTab = ref('description')
|
||||
</script>
|
||||
|
||||
@@ -1,47 +1,92 @@
|
||||
<template>
|
||||
<div class="flex flex-col gap-4 mt-4 overflow-auto text-sm">
|
||||
<div v-if="nodeDefs?.length">
|
||||
<!-- TODO: when registry returns node defs, use them here -->
|
||||
</div>
|
||||
<div
|
||||
v-for="i in 3"
|
||||
v-else
|
||||
:key="i"
|
||||
class="border border-surface-border rounded-lg p-4"
|
||||
>
|
||||
<NodePreview
|
||||
:node-def="placeholderNodeDef"
|
||||
class="!text-[.625rem] !min-w-full"
|
||||
<div class="flex flex-col gap-4 mt-4 text-sm">
|
||||
<template v-if="mappedNodeDefs?.length">
|
||||
<div
|
||||
v-for="nodeDef in mappedNodeDefs"
|
||||
:key="createNodeDefKey(nodeDef)"
|
||||
class="border border-surface-border rounded-lg p-4"
|
||||
>
|
||||
<NodePreview :node-def="nodeDef" class="!text-[.625rem] !min-w-full" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="isLoading">
|
||||
<ProgressSpinner />
|
||||
</template>
|
||||
<template v-else-if="nodeNames.length">
|
||||
<div v-for="node in nodeNames" :key="node" class="text-muted truncate">
|
||||
{{ node }}
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<NoResultsPlaceholder
|
||||
:title="$t('manager.noNodesFound')"
|
||||
:message="$t('manager.noNodesFoundDescription')"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import NodePreview from '@/components/node/NodePreview.vue'
|
||||
import { ComfyNodeDef } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
import { components } from '@/types/comfyRegistryTypes'
|
||||
import { whenever } from '@vueuse/core'
|
||||
import ProgressSpinner from 'primevue/progressspinner'
|
||||
import { computed, ref, shallowRef, useId } from 'vue'
|
||||
|
||||
defineProps<{
|
||||
import NoResultsPlaceholder from '@/components/common/NoResultsPlaceholder.vue'
|
||||
import NodePreview from '@/components/node/NodePreview.vue'
|
||||
import { useComfyRegistryStore } from '@/stores/comfyRegistryStore'
|
||||
import { components, operations } from '@/types/comfyRegistryTypes'
|
||||
import { registryToFrontendV2NodeDef } from '@/utils/mapperUtil'
|
||||
|
||||
type ListComfyNodesResponse =
|
||||
operations['ListComfyNodes']['responses'][200]['content']['application/json']['comfy_nodes']
|
||||
|
||||
const { nodePack, nodeNames } = defineProps<{
|
||||
nodePack: components['schemas']['Node']
|
||||
nodeDefs?: components['schemas']['ComfyNode'][]
|
||||
nodeNames: string[]
|
||||
}>()
|
||||
|
||||
// TODO: when registry returns node defs, use them here
|
||||
const placeholderNodeDef: ComfyNodeDef = {
|
||||
name: 'Sample Node',
|
||||
display_name: 'Sample Node',
|
||||
description: 'This is a sample node for preview purposes',
|
||||
inputs: {
|
||||
input1: { name: 'Input 1', type: 'IMAGE' },
|
||||
input2: { name: 'Input 2', type: 'CONDITIONING' }
|
||||
},
|
||||
outputs: [
|
||||
{ name: 'Output 1', type: 'IMAGE', index: 0, is_list: false },
|
||||
{ name: 'Output 2', type: 'MASK', index: 1, is_list: false }
|
||||
],
|
||||
category: 'Utility',
|
||||
output_node: false,
|
||||
python_module: 'nodes'
|
||||
const { getNodeDefs } = useComfyRegistryStore()
|
||||
|
||||
const isLoading = ref(false)
|
||||
const registryNodeDefs = shallowRef<ListComfyNodesResponse | null>(null)
|
||||
|
||||
const fetchNodeDefs = async () => {
|
||||
isLoading.value = true
|
||||
|
||||
const { id: packId } = nodePack
|
||||
const version = nodePack.latest_version?.version
|
||||
|
||||
if (!packId || !version) {
|
||||
registryNodeDefs.value = null
|
||||
} else {
|
||||
const response = await getNodeDefs.call({
|
||||
packId,
|
||||
version,
|
||||
page: 1,
|
||||
limit: 256
|
||||
})
|
||||
registryNodeDefs.value = response?.comfy_nodes ?? null
|
||||
}
|
||||
|
||||
isLoading.value = false
|
||||
}
|
||||
|
||||
whenever(() => nodePack, fetchNodeDefs, { immediate: true, deep: true })
|
||||
|
||||
const toFrontendNodeDef = (nodeDef: components['schemas']['ComfyNode']) => {
|
||||
try {
|
||||
return registryToFrontendV2NodeDef(nodeDef, nodePack)
|
||||
} catch (error) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
const mappedNodeDefs = computed(() => {
|
||||
if (!registryNodeDefs.value) return null
|
||||
return registryNodeDefs.value
|
||||
.map(toFrontendNodeDef)
|
||||
.filter((nodeDef) => nodeDef !== null)
|
||||
})
|
||||
|
||||
const createNodeDefKey = (nodeDef: components['schemas']['ComfyNode']) =>
|
||||
`${nodeDef.category}${nodeDef.comfy_node_name ?? useId()}`
|
||||
</script>
|
||||
|
||||
@@ -111,6 +111,8 @@
|
||||
"manager": {
|
||||
"title": "Custom Nodes Manager",
|
||||
"failed": "Failed ({count})",
|
||||
"noNodesFound": "No nodes found",
|
||||
"noNodesFoundDescription": "The pack's nodes either could not be parsed, or the pack is a frontend extension only and doesn't have any nodes.",
|
||||
"installationQueue": "Installation Queue",
|
||||
"changingVersion": "Changing version from {from} to {to}",
|
||||
"dependencies": "Dependencies",
|
||||
|
||||
@@ -428,6 +428,8 @@
|
||||
"loadingVersions": "Cargando versiones...",
|
||||
"nightlyVersion": "Nocturna",
|
||||
"noDescription": "No hay descripción disponible",
|
||||
"noNodesFound": "No se encontraron nodos",
|
||||
"noNodesFoundDescription": "Los nodos del paquete no se pudieron analizar, o el paquete es solo una extensión de frontend y no tiene ningún nodo.",
|
||||
"noResultsFound": "No se encontraron resultados que coincidan con tu búsqueda.",
|
||||
"nodePack": "Paquete de Nodos",
|
||||
"packsSelected": "Paquetes Seleccionados",
|
||||
|
||||
@@ -428,6 +428,8 @@
|
||||
"loadingVersions": "Chargement des versions...",
|
||||
"nightlyVersion": "Nocturne",
|
||||
"noDescription": "Aucune description disponible",
|
||||
"noNodesFound": "Aucun nœud trouvé",
|
||||
"noNodesFoundDescription": "Les nœuds du pack n'ont pas pu être analysés, ou le pack est une extension frontend uniquement et n'a pas de nœuds.",
|
||||
"noResultsFound": "Aucun résultat trouvé correspondant à votre recherche.",
|
||||
"nodePack": "Pack de Nœuds",
|
||||
"packsSelected": "Packs sélectionnés",
|
||||
|
||||
@@ -428,6 +428,8 @@
|
||||
"loadingVersions": "バージョンを読み込んでいます...",
|
||||
"nightlyVersion": "ナイトリー",
|
||||
"noDescription": "説明はありません",
|
||||
"noNodesFound": "ノードが見つかりません",
|
||||
"noNodesFoundDescription": "パックのノードは解析できなかったか、パックがフロントエンドの拡張機能のみでノードがない可能性があります。",
|
||||
"noResultsFound": "検索に一致する結果が見つかりませんでした。",
|
||||
"nodePack": "ノードパック",
|
||||
"packsSelected": "選択したパック",
|
||||
|
||||
@@ -428,6 +428,8 @@
|
||||
"loadingVersions": "버전 로딩 중...",
|
||||
"nightlyVersion": "최신 테스트 버전(nightly)",
|
||||
"noDescription": "설명이 없습니다",
|
||||
"noNodesFound": "노드를 찾을 수 없습니다",
|
||||
"noNodesFoundDescription": "팩의 노드를 파싱할 수 없거나, 팩이 프론트엔드 확장만을 가지고 있어서 노드가 없습니다.",
|
||||
"noResultsFound": "검색과 일치하는 결과가 없습니다.",
|
||||
"nodePack": "노드 팩",
|
||||
"packsSelected": "선택한 노드 팩",
|
||||
|
||||
@@ -428,6 +428,8 @@
|
||||
"loadingVersions": "Загрузка версий...",
|
||||
"nightlyVersion": "Ночная",
|
||||
"noDescription": "Описание отсутствует",
|
||||
"noNodesFound": "Узлы не найдены",
|
||||
"noNodesFoundDescription": "Узлы пакета не могут быть проанализированы, или пакет является только расширением интерфейса и не имеет узлов.",
|
||||
"noResultsFound": "По вашему запросу ничего не найдено.",
|
||||
"nodePack": "Пакет Узлов",
|
||||
"packsSelected": "Выбрано пакетов",
|
||||
|
||||
@@ -428,6 +428,8 @@
|
||||
"loadingVersions": "正在加载版本...",
|
||||
"nightlyVersion": "每夜",
|
||||
"noDescription": "无可用描述",
|
||||
"noNodesFound": "未找到节点",
|
||||
"noNodesFoundDescription": "无法解析包的节点,或者该包仅为前端扩展,没有任何节点。",
|
||||
"noResultsFound": "未找到符合您搜索的结果。",
|
||||
"nodePack": "节点包",
|
||||
"packsSelected": "选定的包",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import axios, { AxiosError, AxiosResponse } from 'axios'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import { useNodeDefStore } from '@/stores/nodeDefStore'
|
||||
import type { components, operations } from '@/types/comfyRegistryTypes'
|
||||
import { isAbortError } from '@/utils/typeGuardUtil'
|
||||
|
||||
@@ -25,29 +24,6 @@ export const useComfyRegistryService = () => {
|
||||
const isLoading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
|
||||
const nodeDefStore = useNodeDefStore()
|
||||
|
||||
const isLocalNodePack = (nodePackId: string) =>
|
||||
!!nodeDefStore.nodeDefsByName[nodePackId]
|
||||
|
||||
const isLocalNode = (nodeName: string, nodePackId: string) => {
|
||||
if (!nodeDefStore.nodeDefsByName[nodeName]) return false
|
||||
return (
|
||||
nodeDefStore.nodeDefsByName[nodeName].python_module.toLowerCase() ===
|
||||
nodePackId.toLowerCase()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the node definitions for the pack are available
|
||||
*/
|
||||
const packNodesAvailable = (node: components['schemas']['Node']) => {
|
||||
if (node.id && isLocalNodePack(node.id)) return true
|
||||
if (node.latest_version?.comfy_node_extract_status !== 'success')
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
const handleApiError = (
|
||||
err: unknown,
|
||||
context: string,
|
||||
@@ -125,11 +101,11 @@ export const useComfyRegistryService = () => {
|
||||
const getNodeDefs = async (
|
||||
params: {
|
||||
packId: components['schemas']['Node']['id']
|
||||
versionId: components['schemas']['NodeVersion']['id']
|
||||
},
|
||||
version: components['schemas']['NodeVersion']['version']
|
||||
} & operations['ListComfyNodes']['parameters']['query'],
|
||||
signal?: AbortSignal
|
||||
) => {
|
||||
const { packId, versionId } = params
|
||||
const { packId, version: versionId, ...queryParams } = params
|
||||
if (!packId || !versionId) return null
|
||||
|
||||
const endpoint = `/nodes/${packId}/versions/${versionId}/comfy-nodes`
|
||||
@@ -141,7 +117,10 @@ export const useComfyRegistryService = () => {
|
||||
|
||||
return executeApiRequest(
|
||||
() =>
|
||||
registryApiClient.get<components['schemas']['ComfyNode'][]>(endpoint, {
|
||||
registryApiClient.get<
|
||||
operations['ListComfyNodes']['responses'][200]['content']['application/json']
|
||||
>(endpoint, {
|
||||
params: queryParams,
|
||||
signal
|
||||
}),
|
||||
errorContext,
|
||||
@@ -149,33 +128,6 @@ export const useComfyRegistryService = () => {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Comfy Node definition for a specific node in a specific version of a node pack
|
||||
* @param packId - The ID of the node pack
|
||||
* @param versionId - The version of the node pack
|
||||
* @param comfyNodeName - The name of the comfy node (corresponds to `ComfyNodeDef#name`)
|
||||
* @returns The node definition or null if not found or an error occurred
|
||||
*/
|
||||
const getNodeDef = async (
|
||||
params: {
|
||||
packId: components['schemas']['Node']['id']
|
||||
versionId: components['schemas']['NodeVersion']['id']
|
||||
comfyNodeName: components['schemas']['ComfyNode']['comfy_node_name']
|
||||
},
|
||||
signal?: AbortSignal
|
||||
) => {
|
||||
const { packId, versionId, comfyNodeName } = params
|
||||
if (!comfyNodeName || !packId || !versionId) return null
|
||||
if (isLocalNode(comfyNodeName, packId))
|
||||
return nodeDefStore.nodeDefsByName[comfyNodeName]
|
||||
|
||||
const nodeDefs = await getNodeDefs({ packId, versionId }, signal)
|
||||
return (
|
||||
nodeDefs?.find((nodeDef) => nodeDef.comfy_node_name === comfyNodeName) ||
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a paginated list of packs matching specific criteria.
|
||||
* Search packs using `search` param. Search individual nodes using `comfy_node_search` param.
|
||||
@@ -377,9 +329,7 @@ export const useComfyRegistryService = () => {
|
||||
getPackByVersion,
|
||||
getPublisherById,
|
||||
listPacksForPublisher,
|
||||
getNodeDef,
|
||||
getNodeDefs,
|
||||
postPackReview,
|
||||
packNodesAvailable
|
||||
postPackReview
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,10 @@ type NodePack = components['schemas']['Node']
|
||||
type ListPacksParams = operations['listAllNodes']['parameters']['query']
|
||||
type ListPacksResult =
|
||||
operations['listAllNodes']['responses'][200]['content']['application/json']
|
||||
type ComfyNode = components['schemas']['ComfyNode']
|
||||
type GetNodeDefsParams = operations['ListComfyNodes']['parameters']['query'] & {
|
||||
packId: components['schemas']['Node']['id']
|
||||
version: components['schemas']['NodeVersion']['version']
|
||||
}
|
||||
type GetPackByIdPath = operations['getNode']['parameters']['path']['nodeId']
|
||||
|
||||
const isNodePack = (pack: NodePack | undefined): pack is NodePack => {
|
||||
@@ -89,8 +92,8 @@ export const useComfyRegistryStore = defineStore('comfyRegistry', () => {
|
||||
* Get the node definitions for a pack
|
||||
*/
|
||||
const getNodeDefs = useCachedRequest<
|
||||
{ packId: string; versionId: string },
|
||||
ComfyNode[]
|
||||
GetNodeDefsParams,
|
||||
operations['ListComfyNodes']['responses'][200]['content']['application/json']
|
||||
>(registryService.getNodeDefs, { maxSize: PACK_BY_ID_CACHE_SIZE })
|
||||
|
||||
/**
|
||||
|
||||
77
src/utils/mapperUtil.ts
Normal file
77
src/utils/mapperUtil.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { transformInputSpecV1ToV2 } from '@/schemas/nodeDef/migration'
|
||||
import {
|
||||
ComfyNodeDef as ComfyNodeDefV2,
|
||||
InputSpec
|
||||
} from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
import { ComfyNodeDef as ComfyNodeDefV1 } from '@/schemas/nodeDefSchema'
|
||||
import { components } from '@/types/comfyRegistryTypes'
|
||||
|
||||
const registryToFrontendV2NodeOutputs = (
|
||||
registryDef: components['schemas']['ComfyNode']
|
||||
): ComfyNodeDefV2['outputs'] => {
|
||||
const returnTypes = JSON.parse(registryDef.return_types ?? '{}')
|
||||
if (!returnTypes.length) return []
|
||||
|
||||
const returnNames = JSON.parse(registryDef.return_names ?? '{}')
|
||||
const outputsIsList = registryDef.output_is_list ?? []
|
||||
|
||||
const outputs = []
|
||||
for (let i = 0; i < returnTypes.length; i++) {
|
||||
outputs.push({
|
||||
type: returnTypes[i],
|
||||
name: returnNames[i] || returnTypes[i],
|
||||
is_list: outputsIsList[i] ?? false,
|
||||
index: i
|
||||
})
|
||||
}
|
||||
|
||||
return outputs
|
||||
}
|
||||
|
||||
const registryToFrontendV2NodeInputs = (
|
||||
registryDef: components['schemas']['ComfyNode']
|
||||
): ComfyNodeDefV2['inputs'] => {
|
||||
const inputTypes = JSON.parse(
|
||||
registryDef.input_types ?? '{}'
|
||||
) as ComfyNodeDefV1['input']
|
||||
if (!inputTypes || !Object.keys(inputTypes).length) return {}
|
||||
|
||||
const inputsV2: Record<string, InputSpec> = {}
|
||||
|
||||
if (inputTypes.required) {
|
||||
Object.entries(inputTypes.required).forEach(([name, inputSpecV1]) => {
|
||||
inputsV2[name] = transformInputSpecV1ToV2(inputSpecV1, {
|
||||
name,
|
||||
isOptional: false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (inputTypes.optional) {
|
||||
Object.entries(inputTypes.optional).forEach(([name, inputSpecV1]) => {
|
||||
inputsV2[name] = transformInputSpecV1ToV2(inputSpecV1, {
|
||||
name,
|
||||
isOptional: true
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return inputsV2
|
||||
}
|
||||
|
||||
export const registryToFrontendV2NodeDef = (
|
||||
nodeDef: components['schemas']['ComfyNode'],
|
||||
nodePack: components['schemas']['Node']
|
||||
): ComfyNodeDefV2 => {
|
||||
const name = nodeDef.comfy_node_name ?? 'Node Name'
|
||||
return {
|
||||
category: nodeDef.category ?? 'unknown',
|
||||
description: nodeDef.description ?? '',
|
||||
display_name: name,
|
||||
name,
|
||||
inputs: registryToFrontendV2NodeInputs(nodeDef),
|
||||
outputs: registryToFrontendV2NodeOutputs(nodeDef),
|
||||
output_node: false,
|
||||
python_module: nodePack.name ?? nodePack.id ?? 'unknown'
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user