mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-29 02:32:18 +00:00
[refactor] Simplify conflict detection types and improve code maintainability (#4589)
This commit is contained in:
@@ -53,7 +53,7 @@ const mockNodePack = {
|
|||||||
// Create mock functions
|
// Create mock functions
|
||||||
const mockGetPackVersions = vi.fn()
|
const mockGetPackVersions = vi.fn()
|
||||||
const mockInstallPack = vi.fn().mockResolvedValue(undefined)
|
const mockInstallPack = vi.fn().mockResolvedValue(undefined)
|
||||||
const mockCheckVersionCompatibility = vi.fn()
|
const mockCheckNodeCompatibility = vi.fn()
|
||||||
|
|
||||||
// Mock the registry service
|
// Mock the registry service
|
||||||
vi.mock('@/services/comfyRegistryService', () => ({
|
vi.mock('@/services/comfyRegistryService', () => ({
|
||||||
@@ -77,7 +77,7 @@ vi.mock('@/stores/comfyManagerStore', () => ({
|
|||||||
// Mock the conflict detection composable
|
// Mock the conflict detection composable
|
||||||
vi.mock('@/composables/useConflictDetection', () => ({
|
vi.mock('@/composables/useConflictDetection', () => ({
|
||||||
useConflictDetection: vi.fn(() => ({
|
useConflictDetection: vi.fn(() => ({
|
||||||
checkVersionCompatibility: mockCheckVersionCompatibility
|
checkNodeCompatibility: mockCheckNodeCompatibility
|
||||||
}))
|
}))
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ describe('PackVersionSelectorPopover', () => {
|
|||||||
vi.clearAllMocks()
|
vi.clearAllMocks()
|
||||||
mockGetPackVersions.mockReset()
|
mockGetPackVersions.mockReset()
|
||||||
mockInstallPack.mockReset().mockResolvedValue(undefined)
|
mockInstallPack.mockReset().mockResolvedValue(undefined)
|
||||||
mockCheckVersionCompatibility
|
mockCheckNodeCompatibility
|
||||||
.mockReset()
|
.mockReset()
|
||||||
.mockReturnValue({ hasConflict: false, conflicts: [] })
|
.mockReturnValue({ hasConflict: false, conflicts: [] })
|
||||||
})
|
})
|
||||||
@@ -376,7 +376,7 @@ describe('PackVersionSelectorPopover', () => {
|
|||||||
mockGetPackVersions.mockResolvedValueOnce(defaultMockVersions)
|
mockGetPackVersions.mockResolvedValueOnce(defaultMockVersions)
|
||||||
|
|
||||||
// Mock compatibility check to return conflict for specific version
|
// Mock compatibility check to return conflict for specific version
|
||||||
mockCheckVersionCompatibility.mockImplementation((versionData) => {
|
mockCheckNodeCompatibility.mockImplementation((versionData) => {
|
||||||
if (versionData.supported_os?.includes('linux')) {
|
if (versionData.supported_os?.includes('linux')) {
|
||||||
return {
|
return {
|
||||||
hasConflict: true,
|
hasConflict: true,
|
||||||
@@ -404,7 +404,7 @@ describe('PackVersionSelectorPopover', () => {
|
|||||||
await waitForPromises()
|
await waitForPromises()
|
||||||
|
|
||||||
// Check that compatibility checking function was called
|
// Check that compatibility checking function was called
|
||||||
expect(mockCheckVersionCompatibility).toHaveBeenCalled()
|
expect(mockCheckNodeCompatibility).toHaveBeenCalled()
|
||||||
|
|
||||||
// The warning icon should be shown for incompatible versions
|
// The warning icon should be shown for incompatible versions
|
||||||
const warningIcons = wrapper.findAll('.pi-exclamation-triangle')
|
const warningIcons = wrapper.findAll('.pi-exclamation-triangle')
|
||||||
@@ -416,7 +416,7 @@ describe('PackVersionSelectorPopover', () => {
|
|||||||
mockGetPackVersions.mockResolvedValueOnce(defaultMockVersions)
|
mockGetPackVersions.mockResolvedValueOnce(defaultMockVersions)
|
||||||
|
|
||||||
// Mock compatibility check to return no conflicts
|
// Mock compatibility check to return no conflicts
|
||||||
mockCheckVersionCompatibility.mockReturnValue({
|
mockCheckNodeCompatibility.mockReturnValue({
|
||||||
hasConflict: false,
|
hasConflict: false,
|
||||||
conflicts: []
|
conflicts: []
|
||||||
})
|
})
|
||||||
@@ -425,7 +425,7 @@ describe('PackVersionSelectorPopover', () => {
|
|||||||
await waitForPromises()
|
await waitForPromises()
|
||||||
|
|
||||||
// Check that compatibility checking function was called
|
// Check that compatibility checking function was called
|
||||||
expect(mockCheckVersionCompatibility).toHaveBeenCalled()
|
expect(mockCheckNodeCompatibility).toHaveBeenCalled()
|
||||||
|
|
||||||
// The verified icon should be shown for compatible versions
|
// The verified icon should be shown for compatible versions
|
||||||
// Look for the VerifiedIcon component or SVG elements
|
// Look for the VerifiedIcon component or SVG elements
|
||||||
@@ -469,20 +469,24 @@ describe('PackVersionSelectorPopover', () => {
|
|||||||
})
|
})
|
||||||
await waitForPromises()
|
await waitForPromises()
|
||||||
|
|
||||||
|
// Clear previous calls from component mounting/rendering
|
||||||
|
mockCheckNodeCompatibility.mockClear()
|
||||||
|
|
||||||
// Trigger compatibility check by accessing getVersionCompatibility
|
// Trigger compatibility check by accessing getVersionCompatibility
|
||||||
const vm = wrapper.vm as any
|
const vm = wrapper.vm as any
|
||||||
vm.getVersionCompatibility('1.0.0')
|
vm.getVersionCompatibility('1.0.0')
|
||||||
|
|
||||||
// Verify that checkVersionCompatibility was called with correct data
|
// Verify that checkNodeCompatibility was called with correct data
|
||||||
// Since 1.0.0 is the latest version, it should use latest_version data
|
// Since 1.0.0 is the latest version, it should use latest_version data
|
||||||
expect(mockCheckVersionCompatibility).toHaveBeenCalledWith({
|
expect(mockCheckNodeCompatibility).toHaveBeenCalledWith({
|
||||||
supported_os: ['windows', 'linux'],
|
supported_os: ['windows', 'linux'],
|
||||||
supported_accelerators: ['CPU'], // latest_version data takes precedence
|
supported_accelerators: ['CPU'], // latest_version data takes precedence
|
||||||
supported_comfyui_version: '>=0.1.0',
|
supported_comfyui_version: '>=0.1.0',
|
||||||
supported_comfyui_frontend_version: '>=1.0.0',
|
supported_comfyui_frontend_version: '>=1.0.0',
|
||||||
supported_python_version: '>=3.8',
|
supported_python_version: '>=3.8',
|
||||||
is_banned: false,
|
is_banned: false,
|
||||||
has_registry_data: true
|
has_registry_data: true,
|
||||||
|
version: '1.0.0'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -491,7 +495,7 @@ describe('PackVersionSelectorPopover', () => {
|
|||||||
mockGetPackVersions.mockResolvedValueOnce(defaultMockVersions)
|
mockGetPackVersions.mockResolvedValueOnce(defaultMockVersions)
|
||||||
|
|
||||||
// Mock compatibility check to return version conflicts
|
// Mock compatibility check to return version conflicts
|
||||||
mockCheckVersionCompatibility.mockImplementation((versionData) => {
|
mockCheckNodeCompatibility.mockImplementation((versionData) => {
|
||||||
const conflicts = []
|
const conflicts = []
|
||||||
if (versionData.supported_comfyui_version) {
|
if (versionData.supported_comfyui_version) {
|
||||||
conflicts.push({
|
conflicts.push({
|
||||||
@@ -525,7 +529,7 @@ describe('PackVersionSelectorPopover', () => {
|
|||||||
await waitForPromises()
|
await waitForPromises()
|
||||||
|
|
||||||
// Check that compatibility checking function was called
|
// Check that compatibility checking function was called
|
||||||
expect(mockCheckVersionCompatibility).toHaveBeenCalled()
|
expect(mockCheckNodeCompatibility).toHaveBeenCalled()
|
||||||
|
|
||||||
// The warning icon should be shown for version incompatible packages
|
// The warning icon should be shown for version incompatible packages
|
||||||
const warningIcons = wrapper.findAll('.pi-exclamation-triangle')
|
const warningIcons = wrapper.findAll('.pi-exclamation-triangle')
|
||||||
@@ -559,76 +563,56 @@ describe('PackVersionSelectorPopover', () => {
|
|||||||
|
|
||||||
const vm = wrapper.vm as any
|
const vm = wrapper.vm as any
|
||||||
|
|
||||||
|
// Clear previous calls from component mounting/rendering
|
||||||
|
mockCheckNodeCompatibility.mockClear()
|
||||||
|
|
||||||
// Test latest version
|
// Test latest version
|
||||||
vm.getVersionCompatibility('latest')
|
vm.getVersionCompatibility('latest')
|
||||||
expect(mockCheckVersionCompatibility).toHaveBeenCalledWith({
|
expect(mockCheckNodeCompatibility).toHaveBeenCalledWith({
|
||||||
supported_os: ['windows'],
|
supported_os: ['windows'],
|
||||||
supported_accelerators: ['CPU'],
|
supported_accelerators: ['CPU'],
|
||||||
supported_comfyui_version: '>=0.1.0',
|
supported_comfyui_version: '>=0.1.0',
|
||||||
supported_comfyui_frontend_version: '>=1.0.0',
|
supported_comfyui_frontend_version: '>=1.0.0',
|
||||||
supported_python_version: '>=3.8',
|
supported_python_version: '>=3.8',
|
||||||
is_banned: false,
|
is_banned: false,
|
||||||
has_registry_data: true
|
has_registry_data: true,
|
||||||
|
version: '1.0.0'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Clear for next test call
|
||||||
|
mockCheckNodeCompatibility.mockClear()
|
||||||
|
|
||||||
// Test nightly version
|
// Test nightly version
|
||||||
vm.getVersionCompatibility('nightly')
|
vm.getVersionCompatibility('nightly')
|
||||||
expect(mockCheckVersionCompatibility).toHaveBeenCalledWith({
|
expect(mockCheckNodeCompatibility).toHaveBeenCalledWith({
|
||||||
|
id: 'test-pack',
|
||||||
|
name: 'Test Pack',
|
||||||
supported_os: ['windows'],
|
supported_os: ['windows'],
|
||||||
supported_accelerators: ['CPU'],
|
supported_accelerators: ['CPU'],
|
||||||
supported_comfyui_version: '>=0.1.0',
|
supported_comfyui_version: '>=0.1.0',
|
||||||
supported_comfyui_frontend_version: '>=1.0.0',
|
supported_comfyui_frontend_version: '>=1.0.0',
|
||||||
supported_python_version: undefined,
|
repository: 'https://github.com/user/repo',
|
||||||
is_banned: false,
|
has_registry_data: true,
|
||||||
has_registry_data: false
|
latest_version: {
|
||||||
})
|
supported_os: ['windows'],
|
||||||
})
|
supported_accelerators: ['CPU'],
|
||||||
|
supported_python_version: '>=3.8',
|
||||||
it('shows python version conflict warnings', async () => {
|
is_banned: false,
|
||||||
// Set up the mock for versions
|
has_registry_data: true,
|
||||||
mockGetPackVersions.mockResolvedValueOnce(defaultMockVersions)
|
version: '1.0.0',
|
||||||
|
supported_comfyui_version: '>=0.1.0',
|
||||||
// Mock compatibility check to return python version conflicts
|
supported_comfyui_frontend_version: '>=1.0.0'
|
||||||
mockCheckVersionCompatibility.mockImplementation((versionData) => {
|
|
||||||
if (versionData.supported_python_version) {
|
|
||||||
return {
|
|
||||||
hasConflict: true,
|
|
||||||
conflicts: [
|
|
||||||
{
|
|
||||||
type: 'python_version',
|
|
||||||
current_value: '3.8.0',
|
|
||||||
required_value: versionData.supported_python_version
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return { hasConflict: false, conflicts: [] }
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const nodePackWithPythonRequirement = {
|
|
||||||
...mockNodePack,
|
|
||||||
supported_python_version: '>=3.9.0'
|
|
||||||
}
|
|
||||||
|
|
||||||
const wrapper = mountComponent({
|
|
||||||
props: { nodePack: nodePackWithPythonRequirement }
|
|
||||||
})
|
|
||||||
await waitForPromises()
|
|
||||||
|
|
||||||
// Check that compatibility checking function was called
|
|
||||||
expect(mockCheckVersionCompatibility).toHaveBeenCalled()
|
|
||||||
|
|
||||||
// The warning icon should be shown for python version incompatible packages
|
|
||||||
const warningIcons = wrapper.findAll('.pi-exclamation-triangle')
|
|
||||||
expect(warningIcons.length).toBeGreaterThan(0)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
it('shows banned package warnings', async () => {
|
it('shows banned package warnings', async () => {
|
||||||
// Set up the mock for versions
|
// Set up the mock for versions
|
||||||
mockGetPackVersions.mockResolvedValueOnce(defaultMockVersions)
|
mockGetPackVersions.mockResolvedValueOnce(defaultMockVersions)
|
||||||
|
|
||||||
// Mock compatibility check to return banned conflicts
|
// Mock compatibility check to return banned conflicts
|
||||||
mockCheckVersionCompatibility.mockImplementation((versionData) => {
|
mockCheckNodeCompatibility.mockImplementation((versionData) => {
|
||||||
if (versionData.is_banned === true) {
|
if (versionData.is_banned === true) {
|
||||||
return {
|
return {
|
||||||
hasConflict: true,
|
hasConflict: true,
|
||||||
@@ -659,7 +643,7 @@ describe('PackVersionSelectorPopover', () => {
|
|||||||
await waitForPromises()
|
await waitForPromises()
|
||||||
|
|
||||||
// Check that compatibility checking function was called
|
// Check that compatibility checking function was called
|
||||||
expect(mockCheckVersionCompatibility).toHaveBeenCalled()
|
expect(mockCheckNodeCompatibility).toHaveBeenCalled()
|
||||||
|
|
||||||
// Open the dropdown to see the options
|
// Open the dropdown to see the options
|
||||||
const select = wrapper.find('.p-select')
|
const select = wrapper.find('.p-select')
|
||||||
@@ -684,13 +668,13 @@ describe('PackVersionSelectorPopover', () => {
|
|||||||
mockGetPackVersions.mockResolvedValueOnce(defaultMockVersions)
|
mockGetPackVersions.mockResolvedValueOnce(defaultMockVersions)
|
||||||
|
|
||||||
// Mock compatibility check to return security pending conflicts
|
// Mock compatibility check to return security pending conflicts
|
||||||
mockCheckVersionCompatibility.mockImplementation((versionData) => {
|
mockCheckNodeCompatibility.mockImplementation((versionData) => {
|
||||||
if (versionData.has_registry_data === false) {
|
if (versionData.has_registry_data === false) {
|
||||||
return {
|
return {
|
||||||
hasConflict: true,
|
hasConflict: true,
|
||||||
conflicts: [
|
conflicts: [
|
||||||
{
|
{
|
||||||
type: 'security_pending',
|
type: 'pending',
|
||||||
current_value: 'no_registry_data',
|
current_value: 'no_registry_data',
|
||||||
required_value: 'registry_data_available'
|
required_value: 'registry_data_available'
|
||||||
}
|
}
|
||||||
@@ -715,7 +699,7 @@ describe('PackVersionSelectorPopover', () => {
|
|||||||
await waitForPromises()
|
await waitForPromises()
|
||||||
|
|
||||||
// Check that compatibility checking function was called
|
// Check that compatibility checking function was called
|
||||||
expect(mockCheckVersionCompatibility).toHaveBeenCalled()
|
expect(mockCheckNodeCompatibility).toHaveBeenCalled()
|
||||||
|
|
||||||
// The warning icon should be shown for security pending packages
|
// The warning icon should be shown for security pending packages
|
||||||
const warningIcons = wrapper.findAll('.pi-exclamation-triangle')
|
const warningIcons = wrapper.findAll('.pi-exclamation-triangle')
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
v-model="selectedVersion"
|
v-model="selectedVersion"
|
||||||
option-label="label"
|
option-label="label"
|
||||||
option-value="value"
|
option-value="value"
|
||||||
:options="versionOptions"
|
:options="processedVersionOptions"
|
||||||
:highlight-on-select="false"
|
:highlight-on-select="false"
|
||||||
class="w-full max-h-[50vh] border-none shadow-none rounded-md"
|
class="w-full max-h-[50vh] border-none shadow-none rounded-md"
|
||||||
:pt="{
|
:pt="{
|
||||||
@@ -35,19 +35,14 @@
|
|||||||
<template #option="slotProps">
|
<template #option="slotProps">
|
||||||
<div class="flex justify-between items-center w-full p-1">
|
<div class="flex justify-between items-center w-full p-1">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<!-- Show no icon for nightly versions since compatibility is uncertain -->
|
|
||||||
<template v-if="slotProps.option.value === 'nightly'">
|
<template v-if="slotProps.option.value === 'nightly'">
|
||||||
<div class="w-4"></div>
|
<div class="w-4"></div>
|
||||||
<!-- Empty space to maintain alignment -->
|
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<i
|
<i
|
||||||
v-if="
|
v-if="slotProps.option.hasConflict"
|
||||||
getVersionCompatibility(slotProps.option.value).hasConflict
|
|
||||||
"
|
|
||||||
v-tooltip="{
|
v-tooltip="{
|
||||||
value: getVersionCompatibility(slotProps.option.value)
|
value: slotProps.option.conflictMessage,
|
||||||
.conflictMessage,
|
|
||||||
showDelay: 300
|
showDelay: 300
|
||||||
}"
|
}"
|
||||||
class="pi pi-exclamation-triangle text-yellow-500"
|
class="pi pi-exclamation-triangle text-yellow-500"
|
||||||
@@ -57,7 +52,7 @@
|
|||||||
<span>{{ slotProps.option.label }}</span>
|
<span>{{ slotProps.option.label }}</span>
|
||||||
</div>
|
</div>
|
||||||
<i
|
<i
|
||||||
v-if="selectedVersion === slotProps.option.value"
|
v-if="slotProps.option.isSelected"
|
||||||
class="pi pi-check text-highlight"
|
class="pi pi-check text-highlight"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -89,7 +84,7 @@ import { whenever } from '@vueuse/core'
|
|||||||
import Button from 'primevue/button'
|
import Button from 'primevue/button'
|
||||||
import Listbox from 'primevue/listbox'
|
import Listbox from 'primevue/listbox'
|
||||||
import ProgressSpinner from 'primevue/progressspinner'
|
import ProgressSpinner from 'primevue/progressspinner'
|
||||||
import { onMounted, ref } from 'vue'
|
import { computed, onMounted, ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
import ContentDivider from '@/components/common/ContentDivider.vue'
|
import ContentDivider from '@/components/common/ContentDivider.vue'
|
||||||
@@ -115,11 +110,12 @@ const emit = defineEmits<{
|
|||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const registryService = useComfyRegistryService()
|
const registryService = useComfyRegistryService()
|
||||||
const managerStore = useComfyManagerStore()
|
const managerStore = useComfyManagerStore()
|
||||||
const { checkVersionCompatibility } = useConflictDetection()
|
const { checkNodeCompatibility } = useConflictDetection()
|
||||||
|
|
||||||
const isQueueing = ref(false)
|
const isQueueing = ref(false)
|
||||||
|
|
||||||
const selectedVersion = ref<string>('latest')
|
const selectedVersion = ref<string>('latest')
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const initialVersion = getInitialSelectedVersion() ?? 'latest'
|
const initialVersion = getInitialSelectedVersion() ?? 'latest'
|
||||||
selectedVersion.value =
|
selectedVersion.value =
|
||||||
@@ -130,14 +126,14 @@ onMounted(() => {
|
|||||||
const getInitialSelectedVersion = () => {
|
const getInitialSelectedVersion = () => {
|
||||||
if (!nodePack.id) return
|
if (!nodePack.id) return
|
||||||
|
|
||||||
// If unclaimed, set selected version to nightly
|
|
||||||
if (nodePack.publisher?.name === 'Unclaimed')
|
|
||||||
return 'nightly' as ManagerComponents['schemas']['SelectedVersion']
|
|
||||||
|
|
||||||
// If node pack is installed, set selected version to the installed version
|
// If node pack is installed, set selected version to the installed version
|
||||||
if (managerStore.isPackInstalled(nodePack.id))
|
if (managerStore.isPackInstalled(nodePack.id))
|
||||||
return managerStore.getInstalledPackVersion(nodePack.id)
|
return managerStore.getInstalledPackVersion(nodePack.id)
|
||||||
|
|
||||||
|
// If unclaimed, set selected version to nightly
|
||||||
|
if (nodePack.publisher?.name === 'Unclaimed')
|
||||||
|
return 'nightly' as ManagerComponents['schemas']['SelectedVersion']
|
||||||
|
|
||||||
// If node pack is not installed, set selected version to latest
|
// If node pack is not installed, set selected version to latest
|
||||||
return nodePack.latest_version?.version
|
return nodePack.latest_version?.version
|
||||||
}
|
}
|
||||||
@@ -235,76 +231,35 @@ const handleSubmit = async () => {
|
|||||||
emit('submit')
|
emit('submit')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to get version data (either from nodePack or fetchedVersions)
|
|
||||||
const getVersionData = (version: string) => {
|
const getVersionData = (version: string) => {
|
||||||
// Use latest_version data for both "latest" and the actual latest version number
|
|
||||||
const latestVersionNumber = nodePack.latest_version?.version
|
const latestVersionNumber = nodePack.latest_version?.version
|
||||||
const useLatestVersionData =
|
const useLatestVersionData =
|
||||||
version === 'latest' || version === latestVersionNumber
|
version === 'latest' || version === latestVersionNumber
|
||||||
|
|
||||||
if (useLatestVersionData) {
|
if (useLatestVersionData) {
|
||||||
// For "latest" and the actual latest version number, use consistent data from latest_version
|
|
||||||
const latestVersionData = nodePack.latest_version
|
const latestVersionData = nodePack.latest_version
|
||||||
return {
|
return {
|
||||||
supported_os: latestVersionData?.supported_os ?? nodePack.supported_os,
|
...latestVersionData
|
||||||
supported_accelerators:
|
|
||||||
latestVersionData?.supported_accelerators ??
|
|
||||||
nodePack.supported_accelerators,
|
|
||||||
supported_comfyui_version:
|
|
||||||
latestVersionData?.supported_comfyui_version ??
|
|
||||||
nodePack.supported_comfyui_version,
|
|
||||||
supported_comfyui_frontend_version:
|
|
||||||
latestVersionData?.supported_comfyui_frontend_version ??
|
|
||||||
nodePack.supported_comfyui_frontend_version
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version === 'nightly') {
|
|
||||||
// For nightly, we can't determine exact compatibility since it's dynamic Git HEAD
|
|
||||||
// But we can assume it's generally compatible (nightly = latest development)
|
|
||||||
// Use nodePack data as fallback, but nightly is typically more permissive
|
|
||||||
return {
|
|
||||||
supported_os: nodePack.supported_os || [], // If no OS restrictions, assume all supported
|
|
||||||
supported_accelerators: nodePack.supported_accelerators || [], // If no accelerator restrictions, assume all supported
|
|
||||||
supported_comfyui_version: nodePack.supported_comfyui_version, // Use latest known requirement
|
|
||||||
supported_comfyui_frontend_version:
|
|
||||||
nodePack.supported_comfyui_frontend_version // Use latest known requirement
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For specific versions, find in fetched versions
|
|
||||||
const versionData = fetchedVersions.value.find((v) => v.version === version)
|
const versionData = fetchedVersions.value.find((v) => v.version === version)
|
||||||
if (versionData) {
|
if (versionData) {
|
||||||
return {
|
return {
|
||||||
supported_os: versionData.supported_os,
|
...versionData
|
||||||
supported_accelerators: versionData.supported_accelerators,
|
|
||||||
supported_comfyui_version: versionData.supported_comfyui_version,
|
|
||||||
supported_comfyui_frontend_version:
|
|
||||||
versionData.supported_comfyui_frontend_version
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to nodePack data
|
// Fallback to nodePack data
|
||||||
return {
|
return {
|
||||||
supported_os: nodePack.supported_os,
|
...nodePack
|
||||||
supported_accelerators: nodePack.supported_accelerators,
|
|
||||||
supported_comfyui_version: nodePack.supported_comfyui_version,
|
|
||||||
supported_comfyui_frontend_version:
|
|
||||||
nodePack.supported_comfyui_frontend_version
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to check version compatibility using centralized logic
|
|
||||||
const checkVersionCompatibilityLocal = (
|
|
||||||
versionData: ReturnType<typeof getVersionData>
|
|
||||||
) => {
|
|
||||||
return checkVersionCompatibility(versionData)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main function to get version compatibility info
|
// Main function to get version compatibility info
|
||||||
const getVersionCompatibility = (version: string) => {
|
const getVersionCompatibility = (version: string) => {
|
||||||
const versionData = getVersionData(version)
|
const versionData = getVersionData(version)
|
||||||
const compatibility = checkVersionCompatibilityLocal(versionData)
|
const compatibility = checkNodeCompatibility(versionData)
|
||||||
|
|
||||||
const conflictMessage = compatibility.hasConflict
|
const conflictMessage = compatibility.hasConflict
|
||||||
? getJoinedConflictMessages(compatibility.conflicts, t)
|
? getJoinedConflictMessages(compatibility.conflicts, t)
|
||||||
@@ -315,4 +270,33 @@ const getVersionCompatibility = (version: string) => {
|
|||||||
conflictMessage
|
conflictMessage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper to determine if an option is selected.
|
||||||
|
const isOptionSelected = (optionValue: string) => {
|
||||||
|
if (selectedVersion.value === optionValue) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
optionValue === 'latest' &&
|
||||||
|
selectedVersion.value === nodePack.latest_version?.version
|
||||||
|
) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if an option is selected, treating 'latest' as an alias for the actual latest version number.
|
||||||
|
const processedVersionOptions = computed(() => {
|
||||||
|
return versionOptions.value.map((option) => {
|
||||||
|
const compatibility = getVersionCompatibility(option.value)
|
||||||
|
const isSelected = isOptionSelected(option.value)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...option,
|
||||||
|
hasConflict: compatibility.hasConflict,
|
||||||
|
conflictMessage: compatibility.conflictMessage,
|
||||||
|
isSelected: isSelected
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -17,36 +17,24 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { inject, ref } from 'vue'
|
import { inject, ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
|
|
||||||
import PackActionButton from '@/components/dialog/content/manager/button/PackActionButton.vue'
|
import PackActionButton from '@/components/dialog/content/manager/button/PackActionButton.vue'
|
||||||
import { useConflictAcknowledgment } from '@/composables/useConflictAcknowledgment'
|
|
||||||
import { useConflictDetection } from '@/composables/useConflictDetection'
|
|
||||||
import { useDialogService } from '@/services/dialogService'
|
|
||||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||||
import { IsInstallingKey } from '@/types/comfyManagerTypes'
|
import { IsInstallingKey } from '@/types/comfyManagerTypes'
|
||||||
import type { components } from '@/types/comfyRegistryTypes'
|
import type { components } from '@/types/comfyRegistryTypes'
|
||||||
import type { ConflictDetectionResult } from '@/types/conflictDetectionTypes'
|
|
||||||
import { components as ManagerComponents } from '@/types/generatedManagerTypes'
|
import { components as ManagerComponents } from '@/types/generatedManagerTypes'
|
||||||
|
|
||||||
type NodePack = components['schemas']['Node']
|
type NodePack = components['schemas']['Node']
|
||||||
|
|
||||||
const { nodePacks, variant, label, hasConflict, skipConflictCheck } =
|
const { nodePacks, variant, label, hasConflict } = defineProps<{
|
||||||
defineProps<{
|
nodePacks: NodePack[]
|
||||||
nodePacks: NodePack[]
|
variant?: 'default' | 'black'
|
||||||
variant?: 'default' | 'black'
|
label?: string
|
||||||
label?: string
|
hasConflict?: boolean
|
||||||
hasConflict?: boolean
|
}>()
|
||||||
skipConflictCheck?: boolean
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
const isInstalling = inject(IsInstallingKey, ref(false))
|
const isInstalling = inject(IsInstallingKey, ref(false))
|
||||||
const managerStore = useComfyManagerStore()
|
const managerStore = useComfyManagerStore()
|
||||||
const { showNodeConflictDialog } = useDialogService()
|
|
||||||
const { checkVersionCompatibility } = useConflictDetection()
|
|
||||||
const { acknowledgeConflict, isConflictAcknowledged } =
|
|
||||||
useConflictAcknowledgment()
|
|
||||||
|
|
||||||
const onClick = (): void => {
|
const onClick = (): void => {
|
||||||
isInstalling.value = true
|
isInstalling.value = true
|
||||||
@@ -78,81 +66,37 @@ const createPayload = (
|
|||||||
const installPack = (item: NodePack) =>
|
const installPack = (item: NodePack) =>
|
||||||
managerStore.installPack.call(createPayload(item))
|
managerStore.installPack.call(createPayload(item))
|
||||||
|
|
||||||
// Function to check compatibility for uninstalled packages using centralized logic
|
|
||||||
function checkUninstalledPackageCompatibility(
|
|
||||||
pack: NodePack
|
|
||||||
): ConflictDetectionResult | null {
|
|
||||||
const compatibility = checkVersionCompatibility({
|
|
||||||
supported_os: pack.supported_os,
|
|
||||||
supported_accelerators: pack.supported_accelerators,
|
|
||||||
supported_comfyui_version: pack.supported_comfyui_version,
|
|
||||||
supported_comfyui_frontend_version: pack.supported_comfyui_frontend_version
|
|
||||||
})
|
|
||||||
|
|
||||||
if (compatibility.hasConflict) {
|
|
||||||
return {
|
|
||||||
package_id: pack.id || 'unknown',
|
|
||||||
package_name: pack.name || 'unknown',
|
|
||||||
has_conflict: true,
|
|
||||||
conflicts: compatibility.conflicts,
|
|
||||||
is_compatible: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
const installAllPacks = async () => {
|
const installAllPacks = async () => {
|
||||||
if (!nodePacks?.length) return
|
if (!nodePacks?.length) return
|
||||||
|
|
||||||
|
// TBD Install Anyway modal
|
||||||
|
// if (hasConflict && !isConflictAcknowledged) {
|
||||||
|
// showNodeConflictDialog({
|
||||||
|
// conflictedPackages: nodePacks,
|
||||||
|
// buttonText: t('manager.conflicts.installAnyway'),
|
||||||
|
// onButtonClick: async () => {
|
||||||
|
// // User chose "Install Anyway" - acknowledge all conflicts and proceed
|
||||||
|
// for (const conflictedPack of packsWithConflicts) {
|
||||||
|
// for (const conflict of conflictedPack.conflicts) {
|
||||||
|
// acknowledgeConflict(
|
||||||
|
// conflictedPack.package_id,
|
||||||
|
// conflict.type,
|
||||||
|
// '0.1.0'
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // Proceed with installation
|
||||||
|
// await performInstallation(uninstalledPacks)
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
const uninstalledPacks = nodePacks.filter(
|
const uninstalledPacks = nodePacks.filter(
|
||||||
(pack) => !managerStore.isPackInstalled(pack.id)
|
(pack) => !managerStore.isPackInstalled(pack.id)
|
||||||
)
|
)
|
||||||
if (!uninstalledPacks.length) return
|
if (!uninstalledPacks.length) return
|
||||||
|
|
||||||
// Skip conflict check if explicitly requested (e.g., from "Install Anyway" button)
|
|
||||||
if (!skipConflictCheck) {
|
|
||||||
// Check for conflicts in uninstalled packages
|
|
||||||
const packsWithConflicts: ConflictDetectionResult[] = []
|
|
||||||
|
|
||||||
for (const pack of uninstalledPacks) {
|
|
||||||
const conflicts = checkUninstalledPackageCompatibility(pack)
|
|
||||||
if (conflicts) {
|
|
||||||
// Check if conflicts have been acknowledged
|
|
||||||
const hasUnacknowledgedConflicts = conflicts.conflicts.some(
|
|
||||||
(conflict) => !isConflictAcknowledged(pack.id || '', conflict.type)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (hasUnacknowledgedConflicts) {
|
|
||||||
packsWithConflicts.push(conflicts)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there are unacknowledged conflicts, show modal
|
|
||||||
if (packsWithConflicts.length > 0) {
|
|
||||||
showNodeConflictDialog({
|
|
||||||
conflictedPackages: packsWithConflicts,
|
|
||||||
buttonText: t('manager.conflicts.installAnyway'),
|
|
||||||
onButtonClick: async () => {
|
|
||||||
// User chose "Install Anyway" - acknowledge all conflicts and proceed
|
|
||||||
for (const conflictedPack of packsWithConflicts) {
|
|
||||||
for (const conflict of conflictedPack.conflicts) {
|
|
||||||
acknowledgeConflict(
|
|
||||||
conflictedPack.package_id,
|
|
||||||
conflict.type,
|
|
||||||
'0.1.0'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Proceed with installation
|
|
||||||
await performInstallation(uninstalledPacks)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No conflicts or conflicts acknowledged - proceed with installation
|
// No conflicts or conflicts acknowledged - proceed with installation
|
||||||
await performInstallation(uninstalledPacks)
|
await performInstallation(uninstalledPacks)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ whenever(isInstalled, () => {
|
|||||||
isInstalling.value = false
|
isInstalling.value = false
|
||||||
})
|
})
|
||||||
|
|
||||||
const { checkVersionCompatibility } = useConflictDetection()
|
const { checkNodeCompatibility } = useConflictDetection()
|
||||||
const { getConflictsForPackageByID } = useConflictDetectionStore()
|
const { getConflictsForPackageByID } = useConflictDetectionStore()
|
||||||
|
|
||||||
const { t, d, n } = useI18n()
|
const { t, d, n } = useI18n()
|
||||||
@@ -107,22 +107,12 @@ const conflictResult = computed((): ConflictDetectionResult | null => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For non-installed packages, perform compatibility check
|
// For non-installed packages, perform compatibility check
|
||||||
const compatibility = checkVersionCompatibility({
|
const compatibility = checkNodeCompatibility(nodePack)
|
||||||
supported_os: nodePack.supported_os,
|
|
||||||
supported_accelerators: nodePack.supported_accelerators,
|
|
||||||
supported_comfyui_version: nodePack.supported_comfyui_version,
|
|
||||||
supported_comfyui_frontend_version:
|
|
||||||
nodePack.supported_comfyui_frontend_version
|
|
||||||
// TODO: Add when API provides these fields
|
|
||||||
// supported_python_version: nodePack.supported_python_version,
|
|
||||||
// is_banned: nodePack.is_banned,
|
|
||||||
// has_registry_data: nodePack.has_registry_data
|
|
||||||
})
|
|
||||||
|
|
||||||
if (compatibility.hasConflict && nodePack.id && nodePack.name) {
|
if (compatibility.hasConflict) {
|
||||||
return {
|
return {
|
||||||
package_id: nodePack.id,
|
package_id: nodePack.id || '',
|
||||||
package_name: nodePack.name,
|
package_name: nodePack.name || '',
|
||||||
has_conflict: true,
|
has_conflict: true,
|
||||||
conflicts: compatibility.conflicts,
|
conflicts: compatibility.conflicts,
|
||||||
is_compatible: false
|
is_compatible: false
|
||||||
@@ -133,7 +123,7 @@ const conflictResult = computed((): ConflictDetectionResult | null => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const hasCompatibilityIssues = computed(() => {
|
const hasCompatibilityIssues = computed(() => {
|
||||||
return isInstalled.value && conflictResult.value?.has_conflict ? true : false
|
return conflictResult.value?.has_conflict
|
||||||
})
|
})
|
||||||
|
|
||||||
const infoItems = computed<InfoItem[]>(() => [
|
const infoItems = computed<InfoItem[]>(() => [
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
:key="index"
|
:key="index"
|
||||||
class="p-3 bg-yellow-800/20 rounded-md"
|
class="p-3 bg-yellow-800/20 rounded-md"
|
||||||
>
|
>
|
||||||
<div class="text-sm">
|
<div class="text-sm break-words">
|
||||||
{{ getConflictMessage(conflict, $t) }}
|
{{ getConflictMessage(conflict, $t) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ const formattedDownloads = computed(() =>
|
|||||||
)
|
)
|
||||||
|
|
||||||
const { getConflictsForPackageByID } = useConflictDetectionStore()
|
const { getConflictsForPackageByID } = useConflictDetectionStore()
|
||||||
const { checkVersionCompatibility } = useConflictDetection()
|
const { checkNodeCompatibility } = useConflictDetection()
|
||||||
|
|
||||||
const hasConflict = computed(() => {
|
const hasConflict = computed(() => {
|
||||||
if (!nodePack.id) return false
|
if (!nodePack.id) return false
|
||||||
@@ -60,21 +60,7 @@ const hasConflict = computed(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For uninstalled packages, check compatibility directly
|
// For uninstalled packages, check compatibility directly
|
||||||
if (
|
const compatibility = checkNodeCompatibility(nodePack)
|
||||||
nodePack.supported_os ||
|
return compatibility.hasConflict
|
||||||
nodePack.supported_accelerators ||
|
|
||||||
nodePack.supported_comfyui_version
|
|
||||||
) {
|
|
||||||
const compatibility = checkVersionCompatibility({
|
|
||||||
supported_os: nodePack.supported_os,
|
|
||||||
supported_accelerators: nodePack.supported_accelerators,
|
|
||||||
supported_comfyui_version: nodePack.supported_comfyui_version,
|
|
||||||
supported_comfyui_frontend_version:
|
|
||||||
nodePack.supported_comfyui_frontend_version
|
|
||||||
})
|
|
||||||
return compatibility.hasConflict
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -17,15 +17,14 @@ import type {
|
|||||||
ConflictDetectionResult,
|
ConflictDetectionResult,
|
||||||
ConflictDetectionSummary,
|
ConflictDetectionSummary,
|
||||||
ConflictType,
|
ConflictType,
|
||||||
|
Node,
|
||||||
NodePackRequirements,
|
NodePackRequirements,
|
||||||
SupportedAccelerator,
|
|
||||||
SupportedOS,
|
|
||||||
SystemEnvironment
|
SystemEnvironment
|
||||||
} from '@/types/conflictDetectionTypes'
|
} from '@/types/conflictDetectionTypes'
|
||||||
import {
|
import {
|
||||||
cleanVersion,
|
cleanVersion,
|
||||||
satisfiesVersion,
|
satisfiesVersion,
|
||||||
checkVersionCompatibility as utilCheckVersionCompatibility
|
utilCheckVersionCompatibility
|
||||||
} from '@/utils/versionUtil'
|
} from '@/utils/versionUtil'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,10 +32,8 @@ import {
|
|||||||
* Error-resilient and asynchronous to avoid affecting other components.
|
* Error-resilient and asynchronous to avoid affecting other components.
|
||||||
*/
|
*/
|
||||||
export function useConflictDetection() {
|
export function useConflictDetection() {
|
||||||
// Store references
|
|
||||||
const managerStore = useComfyManagerStore()
|
const managerStore = useComfyManagerStore()
|
||||||
|
|
||||||
// Use installed packs composable instead of direct API calls
|
|
||||||
const {
|
const {
|
||||||
startFetchInstalled,
|
startFetchInstalled,
|
||||||
installedPacks,
|
installedPacks,
|
||||||
@@ -44,15 +41,12 @@ export function useConflictDetection() {
|
|||||||
isReady: installedPacksReady
|
isReady: installedPacksReady
|
||||||
} = useInstalledPacks()
|
} = useInstalledPacks()
|
||||||
|
|
||||||
// State management
|
|
||||||
const isDetecting = ref(false)
|
const isDetecting = ref(false)
|
||||||
const lastDetectionTime = ref<string | null>(null)
|
const lastDetectionTime = ref<string | null>(null)
|
||||||
const detectionError = ref<string | null>(null)
|
const detectionError = ref<string | null>(null)
|
||||||
|
|
||||||
// System environment information
|
|
||||||
const systemEnvironment = ref<SystemEnvironment | null>(null)
|
const systemEnvironment = ref<SystemEnvironment | null>(null)
|
||||||
|
|
||||||
// Conflict detection results
|
|
||||||
const detectionResults = ref<ConflictDetectionResult[]>([])
|
const detectionResults = ref<ConflictDetectionResult[]>([])
|
||||||
// Store merged conflicts separately for testing
|
// Store merged conflicts separately for testing
|
||||||
const storedMergedConflicts = ref<ConflictDetectionResult[]>([])
|
const storedMergedConflicts = ref<ConflictDetectionResult[]>([])
|
||||||
@@ -61,13 +55,10 @@ export function useConflictDetection() {
|
|||||||
// Registry API request cancellation
|
// Registry API request cancellation
|
||||||
const abortController = ref<AbortController | null>(null)
|
const abortController = ref<AbortController | null>(null)
|
||||||
|
|
||||||
// Acknowledgment management
|
|
||||||
const acknowledgment = useConflictAcknowledgment()
|
const acknowledgment = useConflictAcknowledgment()
|
||||||
|
|
||||||
// Store management
|
|
||||||
const conflictStore = useConflictDetectionStore()
|
const conflictStore = useConflictDetectionStore()
|
||||||
|
|
||||||
// Computed properties - use store instead of local state
|
|
||||||
const hasConflicts = computed(() => conflictStore.hasConflicts)
|
const hasConflicts = computed(() => conflictStore.hasConflicts)
|
||||||
const conflictedPackages = computed(() => {
|
const conflictedPackages = computed(() => {
|
||||||
return conflictStore.conflictedPackages
|
return conflictStore.conflictedPackages
|
||||||
@@ -97,7 +88,6 @@ export function useConflictDetection() {
|
|||||||
// Extract system information from system stats
|
// Extract system information from system stats
|
||||||
const systemStats = systemStatsStore.systemStats
|
const systemStats = systemStatsStore.systemStats
|
||||||
const comfyuiVersion = systemStats?.system?.comfyui_version || 'unknown'
|
const comfyuiVersion = systemStats?.system?.comfyui_version || 'unknown'
|
||||||
const pythonVersion = systemStats?.system?.python_version || 'unknown'
|
|
||||||
|
|
||||||
// Use system stats for OS detection (more accurate than browser detection)
|
// Use system stats for OS detection (more accurate than browser detection)
|
||||||
const systemOS = systemStats?.system?.os || 'unknown'
|
const systemOS = systemStats?.system?.os || 'unknown'
|
||||||
@@ -118,7 +108,6 @@ export function useConflictDetection() {
|
|||||||
frontendVersion.status === 'fulfilled'
|
frontendVersion.status === 'fulfilled'
|
||||||
? frontendVersion.value
|
? frontendVersion.value
|
||||||
: 'unknown',
|
: 'unknown',
|
||||||
python_version: pythonVersion,
|
|
||||||
|
|
||||||
// Platform information (from system stats)
|
// Platform information (from system stats)
|
||||||
os: detectedOS,
|
os: detectedOS,
|
||||||
@@ -159,7 +148,6 @@ export function useConflictDetection() {
|
|||||||
const fallbackEnvironment: SystemEnvironment = {
|
const fallbackEnvironment: SystemEnvironment = {
|
||||||
comfyui_version: 'unknown',
|
comfyui_version: 'unknown',
|
||||||
frontend_version: frontendVersion,
|
frontend_version: frontendVersion,
|
||||||
python_version: 'unknown',
|
|
||||||
os: detectOSFromSystemStats(navigator.platform),
|
os: detectOSFromSystemStats(navigator.platform),
|
||||||
platform_details: navigator.platform,
|
platform_details: navigator.platform,
|
||||||
architecture: getArchitecture(),
|
architecture: getArchitecture(),
|
||||||
@@ -283,18 +271,12 @@ export function useConflictDetection() {
|
|||||||
supported_comfyui_frontend_version:
|
supported_comfyui_frontend_version:
|
||||||
versionData.supported_comfyui_frontend_version,
|
versionData.supported_comfyui_frontend_version,
|
||||||
supported_os: normalizeOSValues(versionData.supported_os),
|
supported_os: normalizeOSValues(versionData.supported_os),
|
||||||
supported_accelerators:
|
supported_accelerators: versionData.supported_accelerators,
|
||||||
versionData.supported_accelerators as SupportedAccelerator[],
|
|
||||||
dependencies: versionData.dependencies || [],
|
|
||||||
|
|
||||||
// Status information
|
// Status information
|
||||||
registry_status: undefined, // Node status - not critical for conflict detection
|
|
||||||
version_status: versionData.status,
|
version_status: versionData.status,
|
||||||
is_banned: versionData.status === 'NodeVersionStatusBanned',
|
is_banned: versionData.status === 'NodeVersionStatusBanned',
|
||||||
|
is_pending: versionData.status === 'NodeVersionStatusPending'
|
||||||
// Metadata
|
|
||||||
registry_fetch_time: new Date().toISOString(),
|
|
||||||
has_registry_data: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
requirements.push(requirement)
|
requirements.push(requirement)
|
||||||
@@ -310,8 +292,7 @@ export function useConflictDetection() {
|
|||||||
installed_version: installedVersion,
|
installed_version: installedVersion,
|
||||||
is_enabled: isEnabled,
|
is_enabled: isEnabled,
|
||||||
is_banned: false,
|
is_banned: false,
|
||||||
registry_fetch_time: new Date().toISOString(),
|
is_pending: false
|
||||||
has_registry_data: false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
requirements.push(fallbackRequirement)
|
requirements.push(fallbackRequirement)
|
||||||
@@ -350,10 +331,7 @@ export function useConflictDetection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 1. ComfyUI version conflict check
|
// 1. ComfyUI version conflict check
|
||||||
if (
|
if (!isCompatibleWithAll(packageReq.supported_comfyui_version)) {
|
||||||
packageReq.has_registry_data &&
|
|
||||||
!isCompatibleWithAll(packageReq.supported_comfyui_version)
|
|
||||||
) {
|
|
||||||
const versionConflict = checkVersionConflict(
|
const versionConflict = checkVersionConflict(
|
||||||
'comfyui_version',
|
'comfyui_version',
|
||||||
sysEnv.comfyui_version,
|
sysEnv.comfyui_version,
|
||||||
@@ -363,10 +341,7 @@ export function useConflictDetection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. Frontend version conflict check
|
// 2. Frontend version conflict check
|
||||||
if (
|
if (!isCompatibleWithAll(packageReq.supported_comfyui_frontend_version)) {
|
||||||
packageReq.has_registry_data &&
|
|
||||||
!isCompatibleWithAll(packageReq.supported_comfyui_frontend_version)
|
|
||||||
) {
|
|
||||||
const versionConflict = checkVersionConflict(
|
const versionConflict = checkVersionConflict(
|
||||||
'frontend_version',
|
'frontend_version',
|
||||||
sysEnv.frontend_version,
|
sysEnv.frontend_version,
|
||||||
@@ -376,19 +351,13 @@ export function useConflictDetection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3. OS compatibility check
|
// 3. OS compatibility check
|
||||||
if (
|
if (!isCompatibleWithAll(packageReq.supported_os)) {
|
||||||
packageReq.has_registry_data &&
|
|
||||||
!isCompatibleWithAll(packageReq.supported_os)
|
|
||||||
) {
|
|
||||||
const osConflict = checkOSConflict(packageReq.supported_os!, sysEnv.os)
|
const osConflict = checkOSConflict(packageReq.supported_os!, sysEnv.os)
|
||||||
if (osConflict) conflicts.push(osConflict)
|
if (osConflict) conflicts.push(osConflict)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Accelerator compatibility check
|
// 4. Accelerator compatibility check
|
||||||
if (
|
if (!isCompatibleWithAll(packageReq.supported_accelerators)) {
|
||||||
packageReq.has_registry_data &&
|
|
||||||
!isCompatibleWithAll(packageReq.supported_accelerators)
|
|
||||||
) {
|
|
||||||
const acceleratorConflict = checkAcceleratorConflict(
|
const acceleratorConflict = checkAcceleratorConflict(
|
||||||
packageReq.supported_accelerators!,
|
packageReq.supported_accelerators!,
|
||||||
sysEnv.available_accelerators
|
sysEnv.available_accelerators
|
||||||
@@ -403,9 +372,9 @@ export function useConflictDetection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 6. Registry data availability check using shared logic
|
// 6. Registry data availability check using shared logic
|
||||||
const securityConflict = checkSecurityStatus(packageReq.has_registry_data)
|
const pendingConflict = checkPendingStatus(packageReq.is_pending)
|
||||||
if (securityConflict) {
|
if (pendingConflict) {
|
||||||
conflicts.push(securityConflict)
|
conflicts.push(pendingConflict)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate result
|
// Generate result
|
||||||
@@ -481,11 +450,13 @@ export function useConflictDetection() {
|
|||||||
* @param importFailInfo Import failure data from Manager API
|
* @param importFailInfo Import failure data from Manager API
|
||||||
* @returns Array of conflict detection results for failed imports
|
* @returns Array of conflict detection results for failed imports
|
||||||
*/
|
*/
|
||||||
function detectPythonImportConflicts(
|
function detectImportFailConflicts(
|
||||||
importFailInfo: Record<string, any>
|
importFailInfo: Record<string, { msg: string; name: string; path: string }>
|
||||||
): ConflictDetectionResult[] {
|
): ConflictDetectionResult[] {
|
||||||
const results: ConflictDetectionResult[] = []
|
const results: ConflictDetectionResult[] = []
|
||||||
|
|
||||||
|
console.log('@@@', importFailInfo)
|
||||||
|
|
||||||
if (!importFailInfo || typeof importFailInfo !== 'object') {
|
if (!importFailInfo || typeof importFailInfo !== 'object') {
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
@@ -497,22 +468,17 @@ export function useConflictDetection() {
|
|||||||
const errorMsg = failureInfo.msg || 'Unknown import error'
|
const errorMsg = failureInfo.msg || 'Unknown import error'
|
||||||
const modulePath = failureInfo.path || ''
|
const modulePath = failureInfo.path || ''
|
||||||
|
|
||||||
// Parse error message to extract missing dependency
|
|
||||||
const missingDependency = extractMissingDependency(errorMsg)
|
|
||||||
|
|
||||||
const conflicts: ConflictDetail[] = [
|
|
||||||
{
|
|
||||||
type: 'python_dependency',
|
|
||||||
current_value: 'missing',
|
|
||||||
required_value: missingDependency
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
results.push({
|
results.push({
|
||||||
package_id: packageId,
|
package_id: packageId,
|
||||||
package_name: packageId,
|
package_name: packageId,
|
||||||
has_conflict: true,
|
has_conflict: true,
|
||||||
conflicts,
|
conflicts: [
|
||||||
|
{
|
||||||
|
type: 'import_failed',
|
||||||
|
current_value: 'installed',
|
||||||
|
required_value: failureInfo.msg
|
||||||
|
}
|
||||||
|
],
|
||||||
is_compatible: false
|
is_compatible: false
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -520,8 +486,7 @@ export function useConflictDetection() {
|
|||||||
`[ConflictDetection] Python import failure detected for ${packageId}:`,
|
`[ConflictDetection] Python import failure detected for ${packageId}:`,
|
||||||
{
|
{
|
||||||
path: modulePath,
|
path: modulePath,
|
||||||
error: errorMsg,
|
error: errorMsg
|
||||||
missingDependency
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -579,7 +544,7 @@ export function useConflictDetection() {
|
|||||||
|
|
||||||
// 4. Detect Python import failures
|
// 4. Detect Python import failures
|
||||||
const importFailInfo = await fetchImportFailInfo()
|
const importFailInfo = await fetchImportFailInfo()
|
||||||
const importFailResults = detectPythonImportConflicts(importFailInfo)
|
const importFailResults = detectImportFailConflicts(importFailInfo)
|
||||||
console.log(
|
console.log(
|
||||||
'[ConflictDetection] Python import failures detected:',
|
'[ConflictDetection] Python import failures detected:',
|
||||||
importFailResults
|
importFailResults
|
||||||
@@ -769,18 +734,12 @@ export function useConflictDetection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check compatibility for a specific version of a package.
|
* Check compatibility for a node.
|
||||||
* Used by components like PackVersionSelectorPopover.
|
* Used by components like PackVersionSelectorPopover.
|
||||||
*/
|
*/
|
||||||
function checkVersionCompatibility(versionData: {
|
function checkNodeCompatibility(
|
||||||
supported_os?: string[]
|
node: Node | components['schemas']['NodeVersion']
|
||||||
supported_accelerators?: string[]
|
) {
|
||||||
supported_comfyui_version?: string
|
|
||||||
supported_comfyui_frontend_version?: string
|
|
||||||
supported_python_version?: string
|
|
||||||
is_banned?: boolean
|
|
||||||
has_registry_data?: boolean
|
|
||||||
}) {
|
|
||||||
const systemStatsStore = useSystemStatsStore()
|
const systemStatsStore = useSystemStatsStore()
|
||||||
const systemStats = systemStatsStore.systemStats
|
const systemStats = systemStatsStore.systemStats
|
||||||
if (!systemStats) return { hasConflict: false, conflicts: [] }
|
if (!systemStats) return { hasConflict: false, conflicts: [] }
|
||||||
@@ -788,34 +747,28 @@ export function useConflictDetection() {
|
|||||||
const conflicts: ConflictDetail[] = []
|
const conflicts: ConflictDetail[] = []
|
||||||
|
|
||||||
// Check OS compatibility using centralized function
|
// Check OS compatibility using centralized function
|
||||||
if (versionData.supported_os && versionData.supported_os.length > 0) {
|
if (node.supported_os && node.supported_os.length > 0) {
|
||||||
const currentOS = systemStats.system?.os || 'unknown'
|
const currentOS = systemStats.system?.os || 'unknown'
|
||||||
const osConflict = checkOSConflict(
|
const osConflict = checkOSConflict(node.supported_os, currentOS)
|
||||||
versionData.supported_os as SupportedOS[],
|
|
||||||
currentOS as SupportedOS
|
|
||||||
)
|
|
||||||
if (osConflict) {
|
if (osConflict) {
|
||||||
conflicts.push(osConflict)
|
conflicts.push(osConflict)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check accelerator compatibility using centralized function
|
// Check accelerator compatibility using centralized function
|
||||||
if (
|
if (node.supported_accelerators && node.supported_accelerators.length > 0) {
|
||||||
versionData.supported_accelerators &&
|
|
||||||
versionData.supported_accelerators.length > 0
|
|
||||||
) {
|
|
||||||
// Extract available accelerators from system stats
|
// Extract available accelerators from system stats
|
||||||
const acceleratorInfo = extractAcceleratorInfo(systemStats)
|
const acceleratorInfo = extractAcceleratorInfo(systemStats)
|
||||||
const availableAccelerators: SupportedAccelerator[] = []
|
const availableAccelerators: Node['supported_accelerators'] = []
|
||||||
|
|
||||||
acceleratorInfo.available.forEach((accel) => {
|
acceleratorInfo.available?.forEach((accel) => {
|
||||||
if (accel === 'CUDA') availableAccelerators.push('CUDA')
|
if (accel === 'CUDA') availableAccelerators.push('CUDA')
|
||||||
if (accel === 'Metal') availableAccelerators.push('Metal')
|
if (accel === 'Metal') availableAccelerators.push('Metal')
|
||||||
if (accel === 'CPU') availableAccelerators.push('CPU')
|
if (accel === 'CPU') availableAccelerators.push('CPU')
|
||||||
})
|
})
|
||||||
|
|
||||||
const acceleratorConflict = checkAcceleratorConflict(
|
const acceleratorConflict = checkAcceleratorConflict(
|
||||||
versionData.supported_accelerators as SupportedAccelerator[],
|
node.supported_accelerators,
|
||||||
availableAccelerators
|
availableAccelerators
|
||||||
)
|
)
|
||||||
if (acceleratorConflict) {
|
if (acceleratorConflict) {
|
||||||
@@ -824,13 +777,13 @@ export function useConflictDetection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check ComfyUI version compatibility
|
// Check ComfyUI version compatibility
|
||||||
if (versionData.supported_comfyui_version) {
|
if (node.supported_comfyui_version) {
|
||||||
const currentComfyUIVersion = systemStats.system?.comfyui_version
|
const currentComfyUIVersion = systemStats.system?.comfyui_version
|
||||||
if (currentComfyUIVersion && currentComfyUIVersion !== 'unknown') {
|
if (currentComfyUIVersion && currentComfyUIVersion !== 'unknown') {
|
||||||
const versionConflict = utilCheckVersionCompatibility(
|
const versionConflict = utilCheckVersionCompatibility(
|
||||||
'comfyui_version',
|
'comfyui_version',
|
||||||
currentComfyUIVersion,
|
currentComfyUIVersion,
|
||||||
versionData.supported_comfyui_version
|
node.supported_comfyui_version
|
||||||
)
|
)
|
||||||
if (versionConflict) {
|
if (versionConflict) {
|
||||||
conflicts.push(versionConflict)
|
conflicts.push(versionConflict)
|
||||||
@@ -839,28 +792,13 @@ export function useConflictDetection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check ComfyUI Frontend version compatibility
|
// Check ComfyUI Frontend version compatibility
|
||||||
if (versionData.supported_comfyui_frontend_version) {
|
if (node.supported_comfyui_frontend_version) {
|
||||||
const currentFrontendVersion = config.app_version
|
const currentFrontendVersion = config.app_version
|
||||||
if (currentFrontendVersion && currentFrontendVersion !== 'unknown') {
|
if (currentFrontendVersion && currentFrontendVersion !== 'unknown') {
|
||||||
const versionConflict = utilCheckVersionCompatibility(
|
const versionConflict = utilCheckVersionCompatibility(
|
||||||
'frontend_version',
|
'frontend_version',
|
||||||
currentFrontendVersion,
|
currentFrontendVersion,
|
||||||
versionData.supported_comfyui_frontend_version
|
node.supported_comfyui_frontend_version
|
||||||
)
|
|
||||||
if (versionConflict) {
|
|
||||||
conflicts.push(versionConflict)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check Python version compatibility
|
|
||||||
if (versionData.supported_python_version) {
|
|
||||||
const currentPythonVersion = systemStats.system?.python_version
|
|
||||||
if (currentPythonVersion && currentPythonVersion !== 'unknown') {
|
|
||||||
const versionConflict = utilCheckVersionCompatibility(
|
|
||||||
'python_version',
|
|
||||||
currentPythonVersion,
|
|
||||||
versionData.supported_python_version
|
|
||||||
)
|
)
|
||||||
if (versionConflict) {
|
if (versionConflict) {
|
||||||
conflicts.push(versionConflict)
|
conflicts.push(versionConflict)
|
||||||
@@ -869,15 +807,20 @@ export function useConflictDetection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check banned package status using shared logic
|
// Check banned package status using shared logic
|
||||||
const bannedConflict = checkBannedStatus(versionData.is_banned)
|
const bannedConflict = checkBannedStatus(
|
||||||
|
node.status === 'NodeStatusBanned' ||
|
||||||
|
node.status === 'NodeVersionStatusBanned'
|
||||||
|
)
|
||||||
if (bannedConflict) {
|
if (bannedConflict) {
|
||||||
conflicts.push(bannedConflict)
|
conflicts.push(bannedConflict)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check security/registry data status using shared logic
|
// Check pending status using shared logic
|
||||||
const securityConflict = checkSecurityStatus(versionData.has_registry_data)
|
const pendingConflict = checkPendingStatus(
|
||||||
if (securityConflict) {
|
node.status === 'NodeVersionStatusPending'
|
||||||
conflicts.push(securityConflict)
|
)
|
||||||
|
if (pendingConflict) {
|
||||||
|
conflicts.push(pendingConflict)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -917,7 +860,7 @@ export function useConflictDetection() {
|
|||||||
acknowledgePackageConflict,
|
acknowledgePackageConflict,
|
||||||
|
|
||||||
// Helper functions for other components
|
// Helper functions for other components
|
||||||
checkVersionCompatibility
|
checkNodeCompatibility
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -973,44 +916,6 @@ function mergeConflictsByPackageName(
|
|||||||
return Array.from(mergedMap.values())
|
return Array.from(mergedMap.values())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts missing dependency name from Python error message.
|
|
||||||
* @param errorMsg Error message from Python import failure
|
|
||||||
* @returns Name of missing dependency
|
|
||||||
*/
|
|
||||||
function extractMissingDependency(errorMsg: string): string {
|
|
||||||
// Try to extract module name from common error patterns
|
|
||||||
|
|
||||||
// Pattern 1: "ModuleNotFoundError: No module named 'module_name'"
|
|
||||||
const moduleNotFoundMatch = errorMsg.match(/No module named '([^']+)'/)
|
|
||||||
if (moduleNotFoundMatch) {
|
|
||||||
return moduleNotFoundMatch[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pattern 2: "ImportError: cannot import name 'something' from 'module_name'"
|
|
||||||
const importErrorMatch = errorMsg.match(
|
|
||||||
/cannot import name '[^']+' from '([^']+)'/
|
|
||||||
)
|
|
||||||
if (importErrorMatch) {
|
|
||||||
return importErrorMatch[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pattern 3: "from module_name import something" in the traceback
|
|
||||||
const fromImportMatch = errorMsg.match(/from ([a-zA-Z_][a-zA-Z0-9_]*) import/)
|
|
||||||
if (fromImportMatch) {
|
|
||||||
return fromImportMatch[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pattern 4: "import module_name" in the traceback
|
|
||||||
const importMatch = errorMsg.match(/import ([a-zA-Z_][a-zA-Z0-9_]*)/)
|
|
||||||
if (importMatch) {
|
|
||||||
return importMatch[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback: return generic message
|
|
||||||
return 'unknown dependency'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches frontend version from config.
|
* Fetches frontend version from config.
|
||||||
* @returns Promise that resolves to frontend version string
|
* @returns Promise that resolves to frontend version string
|
||||||
@@ -1044,7 +949,9 @@ function getArchitecture(): string {
|
|||||||
* @param osValues OS values from Registry API
|
* @param osValues OS values from Registry API
|
||||||
* @returns Normalized OS values
|
* @returns Normalized OS values
|
||||||
*/
|
*/
|
||||||
function normalizeOSValues(osValues: string[] | undefined): SupportedOS[] {
|
function normalizeOSValues(
|
||||||
|
osValues: string[] | undefined
|
||||||
|
): Node['supported_os'] {
|
||||||
if (!osValues || osValues.length === 0) {
|
if (!osValues || osValues.length === 0) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@@ -1065,7 +972,7 @@ function normalizeOSValues(osValues: string[] | undefined): SupportedOS[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return as-is if it matches standard format
|
// Return as-is if it matches standard format
|
||||||
return os as SupportedOS
|
return os
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1078,7 +985,7 @@ function normalizeOSValues(osValues: string[] | undefined): SupportedOS[] {
|
|||||||
function detectOSFromSystemStats(
|
function detectOSFromSystemStats(
|
||||||
systemOS: string,
|
systemOS: string,
|
||||||
systemStats?: SystemStats | null
|
systemStats?: SystemStats | null
|
||||||
): SupportedOS {
|
): string {
|
||||||
const os = systemOS.toLowerCase()
|
const os = systemOS.toLowerCase()
|
||||||
|
|
||||||
// Handle specific OS strings (return Registry standard format)
|
// Handle specific OS strings (return Registry standard format)
|
||||||
@@ -1100,14 +1007,7 @@ function detectOSFromSystemStats(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method 2: Check Python version string for platform hints
|
// Method 2: Check user agent as fallback
|
||||||
if (systemStats?.system?.python_version) {
|
|
||||||
const pythonVersion = systemStats.system.python_version.toLowerCase()
|
|
||||||
if (pythonVersion.includes('darwin')) return 'macOS'
|
|
||||||
if (pythonVersion.includes('linux')) return 'Linux'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method 3: Check user agent as fallback
|
|
||||||
const userAgent = navigator.userAgent.toLowerCase()
|
const userAgent = navigator.userAgent.toLowerCase()
|
||||||
if (userAgent.includes('mac')) return 'macOS'
|
if (userAgent.includes('mac')) return 'macOS'
|
||||||
if (userAgent.includes('linux')) return 'Linux'
|
if (userAgent.includes('linux')) return 'Linux'
|
||||||
@@ -1187,14 +1087,14 @@ function extractArchitectureFromSystemStats(
|
|||||||
* @returns Accelerator information object
|
* @returns Accelerator information object
|
||||||
*/
|
*/
|
||||||
function extractAcceleratorInfo(systemStats: SystemStats | null): {
|
function extractAcceleratorInfo(systemStats: SystemStats | null): {
|
||||||
available: SupportedAccelerator[]
|
available: Node['supported_accelerators']
|
||||||
primary: SupportedAccelerator
|
primary: string
|
||||||
memory_mb?: number
|
memory_mb?: number
|
||||||
} {
|
} {
|
||||||
try {
|
try {
|
||||||
if (systemStats?.devices && systemStats.devices.length > 0) {
|
if (systemStats?.devices && systemStats.devices.length > 0) {
|
||||||
const accelerators = new Set<SupportedAccelerator>()
|
const accelerators = new Set<string>()
|
||||||
let primaryDevice: SupportedAccelerator = 'CPU'
|
let primaryDevice: string = 'CPU'
|
||||||
let totalMemory = 0
|
let totalMemory = 0
|
||||||
let maxDevicePriority = 0
|
let maxDevicePriority = 0
|
||||||
|
|
||||||
@@ -1226,7 +1126,7 @@ function extractAcceleratorInfo(systemStats: SystemStats | null): {
|
|||||||
const priority = getDevicePriority(deviceType)
|
const priority = getDevicePriority(deviceType)
|
||||||
|
|
||||||
// Map device type to SupportedAccelerator (Registry standard format)
|
// Map device type to SupportedAccelerator (Registry standard format)
|
||||||
let acceleratorType: SupportedAccelerator = 'CPU'
|
let acceleratorType: string = 'CPU'
|
||||||
if (deviceType === 'cuda') {
|
if (deviceType === 'cuda') {
|
||||||
acceleratorType = 'CUDA'
|
acceleratorType = 'CUDA'
|
||||||
} else if (deviceType === 'mps') {
|
} else if (deviceType === 'mps') {
|
||||||
@@ -1329,17 +1229,17 @@ function checkVersionConflict(
|
|||||||
* Checks for OS compatibility conflicts.
|
* Checks for OS compatibility conflicts.
|
||||||
*/
|
*/
|
||||||
function checkOSConflict(
|
function checkOSConflict(
|
||||||
supportedOS: SupportedOS[],
|
supportedOS: Node['supported_os'],
|
||||||
currentOS: SupportedOS
|
currentOS: string
|
||||||
): ConflictDetail | null {
|
): ConflictDetail | null {
|
||||||
if (supportedOS.includes('any') || supportedOS.includes(currentOS)) {
|
if (supportedOS?.includes('any') || supportedOS?.includes(currentOS)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'os',
|
type: 'os',
|
||||||
current_value: currentOS,
|
current_value: currentOS,
|
||||||
required_value: supportedOS.join(', ')
|
required_value: supportedOS ? supportedOS?.join(', ') : ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1347,20 +1247,24 @@ function checkOSConflict(
|
|||||||
* Checks for accelerator compatibility conflicts.
|
* Checks for accelerator compatibility conflicts.
|
||||||
*/
|
*/
|
||||||
function checkAcceleratorConflict(
|
function checkAcceleratorConflict(
|
||||||
supportedAccelerators: SupportedAccelerator[],
|
supportedAccelerators: Node['supported_accelerators'],
|
||||||
availableAccelerators: SupportedAccelerator[]
|
availableAccelerators: Node['supported_accelerators']
|
||||||
): ConflictDetail | null {
|
): ConflictDetail | null {
|
||||||
if (
|
if (
|
||||||
supportedAccelerators.includes('any') ||
|
supportedAccelerators?.includes('any') ||
|
||||||
supportedAccelerators.some((acc) => availableAccelerators.includes(acc))
|
supportedAccelerators?.some((acc) => availableAccelerators?.includes(acc))
|
||||||
) {
|
) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'accelerator',
|
type: 'accelerator',
|
||||||
current_value: availableAccelerators.join(', '),
|
current_value: availableAccelerators
|
||||||
required_value: supportedAccelerators.join(', ')
|
? availableAccelerators.join(', ')
|
||||||
|
: '',
|
||||||
|
required_value: supportedAccelerators
|
||||||
|
? supportedAccelerators.join(', ')
|
||||||
|
: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1379,14 +1283,14 @@ function checkBannedStatus(isBanned?: boolean): ConflictDetail | null {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks for security/registry data availability conflicts.
|
* Checks for pending package status conflicts.
|
||||||
*/
|
*/
|
||||||
function checkSecurityStatus(hasRegistryData?: boolean): ConflictDetail | null {
|
function checkPendingStatus(isPending?: boolean): ConflictDetail | null {
|
||||||
if (hasRegistryData === false) {
|
if (isPending === true) {
|
||||||
return {
|
return {
|
||||||
type: 'security_pending',
|
type: 'pending',
|
||||||
current_value: 'no_registry_data',
|
current_value: 'installed',
|
||||||
required_value: 'registry_data_available'
|
required_value: 'not_pending'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
@@ -1402,23 +1306,23 @@ function generateSummary(
|
|||||||
const conflictsByType: Record<ConflictType, number> = {
|
const conflictsByType: Record<ConflictType, number> = {
|
||||||
comfyui_version: 0,
|
comfyui_version: 0,
|
||||||
frontend_version: 0,
|
frontend_version: 0,
|
||||||
python_version: 0,
|
import_failed: 0,
|
||||||
os: 0,
|
os: 0,
|
||||||
accelerator: 0,
|
accelerator: 0,
|
||||||
banned: 0,
|
banned: 0,
|
||||||
security_pending: 0,
|
pending: 0
|
||||||
python_dependency: 0
|
// python_version: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const conflictsByTypeDetails: Record<ConflictType, string[]> = {
|
const conflictsByTypeDetails: Record<ConflictType, string[]> = {
|
||||||
comfyui_version: [],
|
comfyui_version: [],
|
||||||
frontend_version: [],
|
frontend_version: [],
|
||||||
python_version: [],
|
import_failed: [],
|
||||||
os: [],
|
os: [],
|
||||||
accelerator: [],
|
accelerator: [],
|
||||||
banned: [],
|
banned: [],
|
||||||
security_pending: [],
|
pending: []
|
||||||
python_dependency: []
|
// python_version: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
let bannedCount = 0
|
let bannedCount = 0
|
||||||
@@ -1433,7 +1337,7 @@ function generateSummary(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (conflict.type === 'banned') bannedCount++
|
if (conflict.type === 'banned') bannedCount++
|
||||||
if (conflict.type === 'security_pending') securityPendingCount++
|
if (conflict.type === 'pending') securityPendingCount++
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1442,7 +1346,7 @@ function generateSummary(
|
|||||||
compatible_packages: results.filter((r) => r.is_compatible).length,
|
compatible_packages: results.filter((r) => r.is_compatible).length,
|
||||||
conflicted_packages: results.filter((r) => r.has_conflict).length,
|
conflicted_packages: results.filter((r) => r.has_conflict).length,
|
||||||
banned_packages: bannedCount,
|
banned_packages: bannedCount,
|
||||||
security_pending_packages: securityPendingCount,
|
pending_packages: securityPendingCount,
|
||||||
conflicts_by_type_details: conflictsByTypeDetails,
|
conflicts_by_type_details: conflictsByTypeDetails,
|
||||||
last_check_timestamp: new Date().toISOString(),
|
last_check_timestamp: new Date().toISOString(),
|
||||||
check_duration_ms: durationMs
|
check_duration_ms: durationMs
|
||||||
@@ -1458,16 +1362,16 @@ function getEmptySummary(): ConflictDetectionSummary {
|
|||||||
compatible_packages: 0,
|
compatible_packages: 0,
|
||||||
conflicted_packages: 0,
|
conflicted_packages: 0,
|
||||||
banned_packages: 0,
|
banned_packages: 0,
|
||||||
security_pending_packages: 0,
|
pending_packages: 0,
|
||||||
conflicts_by_type_details: {
|
conflicts_by_type_details: {
|
||||||
comfyui_version: [],
|
comfyui_version: [],
|
||||||
frontend_version: [],
|
frontend_version: [],
|
||||||
python_version: [],
|
import_failed: [],
|
||||||
os: [],
|
os: [],
|
||||||
accelerator: [],
|
accelerator: [],
|
||||||
banned: [],
|
banned: [],
|
||||||
security_pending: [],
|
pending: []
|
||||||
python_dependency: []
|
// python_version: [],
|
||||||
},
|
},
|
||||||
last_check_timestamp: new Date().toISOString(),
|
last_check_timestamp: new Date().toISOString(),
|
||||||
check_duration_ms: 0
|
check_duration_ms: 0
|
||||||
|
|||||||
@@ -227,13 +227,11 @@
|
|||||||
"conflictMessages": {
|
"conflictMessages": {
|
||||||
"comfyui_version": "ComfyUI version mismatch (current: {current}, required: {required})",
|
"comfyui_version": "ComfyUI version mismatch (current: {current}, required: {required})",
|
||||||
"frontend_version": "Frontend version mismatch (current: {current}, required: {required})",
|
"frontend_version": "Frontend version mismatch (current: {current}, required: {required})",
|
||||||
"python_version": "Python version mismatch (current: {current}, required: {required})",
|
|
||||||
"os": "Operating system not supported (current: {current}, required: {required})",
|
"os": "Operating system not supported (current: {current}, required: {required})",
|
||||||
"accelerator": "GPU/Accelerator not supported (available: {current}, required: {required})",
|
"accelerator": "GPU/Accelerator not supported (available: {current}, required: {required})",
|
||||||
"generic": "Compatibility issue (current: {current}, required: {required})",
|
"generic": "Compatibility issue (current: {current}, required: {required})",
|
||||||
"banned": "This package is banned for security reasons",
|
"banned": "This package is banned for security reasons",
|
||||||
"security_pending": "Security verification pending - compatibility cannot be verified",
|
"pending": "Security verification pending - compatibility cannot be verified"
|
||||||
"python_dependency": "Missing Python dependency: {required}"
|
|
||||||
},
|
},
|
||||||
"warningTooltip": "This package may have compatibility issues with your current environment"
|
"warningTooltip": "This package may have compatibility issues with your current environment"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export const useConflictDetectionStore = defineStore(
|
|||||||
|
|
||||||
const securityPendingPackages = computed(() =>
|
const securityPendingPackages = computed(() =>
|
||||||
conflictedPackages.value.filter((pkg) =>
|
conflictedPackages.value.filter((pkg) =>
|
||||||
pkg.conflicts.some((conflict) => conflict.type === 'security_pending')
|
pkg.conflicts.some((conflict) => conflict.type === 'pending')
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,17 @@
|
|||||||
/**
|
/**
|
||||||
* Type definitions for the conflict detection system.
|
* Type definitions for the conflict detection system.
|
||||||
* These types are used to detect compatibility issues between Node Packs and the system environment.
|
* These types are used to detect compatibility issues between Node Packs and the system environment.
|
||||||
|
*
|
||||||
|
* This file extends and uses types from comfyRegistryTypes.ts to maintain consistency
|
||||||
|
* with the Registry API schema.
|
||||||
*/
|
*/
|
||||||
|
import type { components } from './comfyRegistryTypes'
|
||||||
|
|
||||||
|
// Re-export core types from Registry API
|
||||||
|
export type Node = components['schemas']['Node']
|
||||||
|
export type NodeVersion = components['schemas']['NodeVersion']
|
||||||
|
export type NodeStatus = components['schemas']['NodeStatus']
|
||||||
|
export type NodeVersionStatus = components['schemas']['NodeVersionStatus']
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conflict types that can be detected in the system
|
* Conflict types that can be detected in the system
|
||||||
@@ -10,30 +20,12 @@
|
|||||||
export type ConflictType =
|
export type ConflictType =
|
||||||
| 'comfyui_version' // ComfyUI version mismatch
|
| 'comfyui_version' // ComfyUI version mismatch
|
||||||
| 'frontend_version' // Frontend version mismatch
|
| 'frontend_version' // Frontend version mismatch
|
||||||
| 'python_version' // Python version mismatch
|
| 'import_failed'
|
||||||
|
// | 'python_version' // Python version mismatch
|
||||||
| 'os' // Operating system incompatibility
|
| 'os' // Operating system incompatibility
|
||||||
| 'accelerator' // GPU/accelerator incompatibility
|
| 'accelerator' // GPU/accelerator incompatibility
|
||||||
| 'banned' // Banned package
|
| 'banned' // Banned package
|
||||||
| 'security_pending' // Security verification pending
|
| 'pending' // Security verification pending
|
||||||
| 'python_dependency' // Python module dependency missing
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Security scan status for packages
|
|
||||||
* @enum {string}
|
|
||||||
*/
|
|
||||||
export type SecurityScanStatus = 'pending' | 'passed' | 'failed' | 'unknown'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Supported operating systems (as per Registry Admin guide)
|
|
||||||
* @enum {string}
|
|
||||||
*/
|
|
||||||
export type SupportedOS = 'Windows' | 'macOS' | 'Linux' | 'any'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Supported accelerators for GPU computation (as per Registry Admin guide)
|
|
||||||
* @enum {string}
|
|
||||||
*/
|
|
||||||
export type SupportedAccelerator = 'CUDA' | 'ROCm' | 'Metal' | 'CPU' | 'any'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Version comparison operators
|
* Version comparison operators
|
||||||
@@ -53,48 +45,17 @@ export interface VersionRequirement {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Node Pack requirements from Registry API
|
* Node Pack requirements from Registry API
|
||||||
|
* Extends Node type with additional installation and compatibility metadata
|
||||||
*/
|
*/
|
||||||
export interface NodePackRequirements {
|
export interface NodePackRequirements extends Node {
|
||||||
/** @description Unique package identifier */
|
|
||||||
package_id: string
|
|
||||||
/** @description Human-readable package name */
|
|
||||||
package_name: string
|
|
||||||
/** @description Currently installed version */
|
|
||||||
installed_version: string
|
installed_version: string
|
||||||
/** @description Whether the package is enabled locally */
|
|
||||||
is_enabled: boolean
|
is_enabled: boolean
|
||||||
|
|
||||||
/** @description Supported ComfyUI version from Registry */
|
|
||||||
supported_comfyui_version?: string
|
|
||||||
/** @description Supported frontend version from Registry */
|
|
||||||
supported_comfyui_frontend_version?: string
|
|
||||||
/** @description List of supported operating systems from Registry */
|
|
||||||
supported_os?: SupportedOS[]
|
|
||||||
/** @description List of supported accelerators from Registry */
|
|
||||||
supported_accelerators?: SupportedAccelerator[]
|
|
||||||
/** @description Package dependencies from Registry */
|
|
||||||
dependencies?: string[]
|
|
||||||
|
|
||||||
/** @description Node status from Registry (Active/Banned/Deleted) */
|
|
||||||
registry_status?:
|
|
||||||
| 'NodeStatusActive'
|
|
||||||
| 'NodeStatusBanned'
|
|
||||||
| 'NodeStatusDeleted'
|
|
||||||
/** @description Node version status from Registry */
|
|
||||||
version_status?:
|
|
||||||
| 'NodeVersionStatusActive'
|
|
||||||
| 'NodeVersionStatusBanned'
|
|
||||||
| 'NodeVersionStatusDeleted'
|
|
||||||
| 'NodeVersionStatusPending'
|
|
||||||
| 'NodeVersionStatusFlagged'
|
|
||||||
/** @description Whether package is banned (derived from status) */
|
|
||||||
is_banned: boolean
|
is_banned: boolean
|
||||||
|
is_pending: boolean
|
||||||
// Metadata
|
// Aliases for backwards compatibility with existing code
|
||||||
/** @description Registry data fetch timestamp */
|
package_id: string
|
||||||
registry_fetch_time: string
|
package_name: string
|
||||||
/** @description Whether Registry data was successfully fetched */
|
version_status?: string
|
||||||
has_registry_data: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -102,33 +63,22 @@ export interface NodePackRequirements {
|
|||||||
*/
|
*/
|
||||||
export interface SystemEnvironment {
|
export interface SystemEnvironment {
|
||||||
// Version information
|
// Version information
|
||||||
/** @description Current ComfyUI version */
|
|
||||||
comfyui_version: string
|
comfyui_version: string
|
||||||
/** @description Current frontend version */
|
|
||||||
frontend_version: string
|
frontend_version: string
|
||||||
/** @description Current Python version */
|
// python_version: string
|
||||||
python_version: string
|
|
||||||
|
|
||||||
// Platform information
|
// Platform information
|
||||||
/** @description Operating system type */
|
os: string
|
||||||
os: SupportedOS
|
|
||||||
/** @description Detailed platform information (e.g., 'Darwin 24.5.0', 'Windows 10') */
|
|
||||||
platform_details: string
|
platform_details: string
|
||||||
/** @description System architecture (e.g., 'x64', 'arm64') */
|
|
||||||
architecture: string
|
architecture: string
|
||||||
|
|
||||||
// GPU/accelerator information
|
// GPU/accelerator information
|
||||||
/** @description List of available accelerators */
|
available_accelerators: Node['supported_accelerators']
|
||||||
available_accelerators: SupportedAccelerator[]
|
primary_accelerator: string
|
||||||
/** @description Primary accelerator in use */
|
|
||||||
primary_accelerator: SupportedAccelerator
|
|
||||||
/** @description GPU memory in megabytes, if available */
|
|
||||||
gpu_memory_mb?: number
|
gpu_memory_mb?: number
|
||||||
|
|
||||||
// Runtime information
|
// Runtime information
|
||||||
/** @description Node.js environment mode */
|
|
||||||
node_env: 'development' | 'production'
|
node_env: 'development' | 'production'
|
||||||
/** @description Browser user agent string */
|
|
||||||
user_agent: string
|
user_agent: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,15 +86,10 @@ export interface SystemEnvironment {
|
|||||||
* Individual conflict detection result for a package
|
* Individual conflict detection result for a package
|
||||||
*/
|
*/
|
||||||
export interface ConflictDetectionResult {
|
export interface ConflictDetectionResult {
|
||||||
/** @description Package identifier */
|
|
||||||
package_id: string
|
package_id: string
|
||||||
/** @description Package name */
|
|
||||||
package_name: string
|
package_name: string
|
||||||
/** @description Whether any conflicts were detected */
|
|
||||||
has_conflict: boolean
|
has_conflict: boolean
|
||||||
/** @description List of detected conflicts */
|
|
||||||
conflicts: ConflictDetail[]
|
conflicts: ConflictDetail[]
|
||||||
/** @description Overall compatibility status */
|
|
||||||
is_compatible: boolean
|
is_compatible: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,11 +97,8 @@ export interface ConflictDetectionResult {
|
|||||||
* Detailed information about a specific conflict
|
* Detailed information about a specific conflict
|
||||||
*/
|
*/
|
||||||
export interface ConflictDetail {
|
export interface ConflictDetail {
|
||||||
/** @description Type of conflict detected */
|
|
||||||
type: ConflictType
|
type: ConflictType
|
||||||
/** @description Human-readable description of the conflict */
|
|
||||||
current_value: string
|
current_value: string
|
||||||
/** @description Required value for compatibility */
|
|
||||||
required_value: string
|
required_value: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,21 +106,13 @@ export interface ConflictDetail {
|
|||||||
* Overall conflict detection summary
|
* Overall conflict detection summary
|
||||||
*/
|
*/
|
||||||
export interface ConflictDetectionSummary {
|
export interface ConflictDetectionSummary {
|
||||||
/** @description Total number of packages checked */
|
|
||||||
total_packages: number
|
total_packages: number
|
||||||
/** @description Number of compatible packages */
|
|
||||||
compatible_packages: number
|
compatible_packages: number
|
||||||
/** @description Number of packages with conflicts */
|
|
||||||
conflicted_packages: number
|
conflicted_packages: number
|
||||||
/** @description Number of banned packages */
|
|
||||||
banned_packages: number
|
banned_packages: number
|
||||||
/** @description Number of packages pending security verification */
|
pending_packages: number
|
||||||
security_pending_packages: number
|
|
||||||
/** @description Node IDs grouped by conflict type */
|
|
||||||
conflicts_by_type_details: Record<ConflictType, string[]>
|
conflicts_by_type_details: Record<ConflictType, string[]>
|
||||||
/** @description Timestamp of the last conflict check */
|
|
||||||
last_check_timestamp: string
|
last_check_timestamp: string
|
||||||
/** @description Duration of the conflict check in milliseconds */
|
|
||||||
check_duration_ms: number
|
check_duration_ms: number
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,16 +120,9 @@ export interface ConflictDetectionSummary {
|
|||||||
* Response payload from conflict detection API
|
* Response payload from conflict detection API
|
||||||
*/
|
*/
|
||||||
export interface ConflictDetectionResponse {
|
export interface ConflictDetectionResponse {
|
||||||
/** @description Whether the API request was successful */
|
|
||||||
success: boolean
|
success: boolean
|
||||||
/** @description Error message if the request failed */
|
|
||||||
error_message?: string
|
error_message?: string
|
||||||
|
|
||||||
/** @description Summary of the conflict detection results */
|
|
||||||
summary: ConflictDetectionSummary
|
summary: ConflictDetectionSummary
|
||||||
/** @description Detailed results for each package */
|
|
||||||
results: ConflictDetectionResult[]
|
results: ConflictDetectionResult[]
|
||||||
|
|
||||||
/** @description System environment information detected by the server (for comparison) */
|
|
||||||
detected_system_environment?: Partial<SystemEnvironment>
|
detected_system_environment?: Partial<SystemEnvironment>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ export function getConflictMessage(
|
|||||||
if (
|
if (
|
||||||
conflict.type === 'comfyui_version' ||
|
conflict.type === 'comfyui_version' ||
|
||||||
conflict.type === 'frontend_version' ||
|
conflict.type === 'frontend_version' ||
|
||||||
conflict.type === 'python_version' ||
|
|
||||||
conflict.type === 'os' ||
|
conflict.type === 'os' ||
|
||||||
conflict.type === 'accelerator'
|
conflict.type === 'accelerator'
|
||||||
) {
|
) {
|
||||||
@@ -28,15 +27,8 @@ export function getConflictMessage(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// For dependency conflicts, show the missing dependency
|
// For banned and pending, use simple message
|
||||||
if (conflict.type === 'python_dependency') {
|
if (conflict.type === 'banned' || conflict.type === 'pending') {
|
||||||
return t(messageKey, {
|
|
||||||
required: conflict.required_value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// For banned and security_pending, use simple message
|
|
||||||
if (conflict.type === 'banned' || conflict.type === 'security_pending') {
|
|
||||||
return t(messageKey)
|
return t(messageKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export function isValidVersion(version: string): boolean {
|
|||||||
* @param supportedVersion Required version range string
|
* @param supportedVersion Required version range string
|
||||||
* @returns ConflictDetail object if incompatible, null if compatible
|
* @returns ConflictDetail object if incompatible, null if compatible
|
||||||
*/
|
*/
|
||||||
export function checkVersionCompatibility(
|
export function utilCheckVersionCompatibility(
|
||||||
type: ConflictType,
|
type: ConflictType,
|
||||||
currentVersion: string,
|
currentVersion: string,
|
||||||
supportedVersion: string
|
supportedVersion: string
|
||||||
|
|||||||
@@ -98,7 +98,6 @@ describe.skip('useConflictDetection with Registry Store', () => {
|
|||||||
systemStats: {
|
systemStats: {
|
||||||
system: {
|
system: {
|
||||||
comfyui_version: '0.3.41',
|
comfyui_version: '0.3.41',
|
||||||
python_version: '3.12.11',
|
|
||||||
os: 'Darwin'
|
os: 'Darwin'
|
||||||
},
|
},
|
||||||
devices: [
|
devices: [
|
||||||
@@ -120,7 +119,6 @@ describe.skip('useConflictDetection with Registry Store', () => {
|
|||||||
mockSystemStatsStore.systemStats = {
|
mockSystemStatsStore.systemStats = {
|
||||||
system: {
|
system: {
|
||||||
comfyui_version: '0.3.41',
|
comfyui_version: '0.3.41',
|
||||||
python_version: '3.12.11',
|
|
||||||
os: 'Darwin'
|
os: 'Darwin'
|
||||||
},
|
},
|
||||||
devices: [
|
devices: [
|
||||||
@@ -178,7 +176,6 @@ describe.skip('useConflictDetection with Registry Store', () => {
|
|||||||
|
|
||||||
expect(environment.comfyui_version).toBe('0.3.41')
|
expect(environment.comfyui_version).toBe('0.3.41')
|
||||||
expect(environment.frontend_version).toBe('1.24.0-1')
|
expect(environment.frontend_version).toBe('1.24.0-1')
|
||||||
expect(environment.python_version).toBe('3.12.11')
|
|
||||||
expect(environment.available_accelerators).toContain('Metal')
|
expect(environment.available_accelerators).toContain('Metal')
|
||||||
expect(environment.available_accelerators).toContain('CPU')
|
expect(environment.available_accelerators).toContain('CPU')
|
||||||
expect(environment.primary_accelerator).toBe('Metal')
|
expect(environment.primary_accelerator).toBe('Metal')
|
||||||
@@ -196,7 +193,6 @@ describe.skip('useConflictDetection with Registry Store', () => {
|
|||||||
|
|
||||||
expect(environment.comfyui_version).toBe('unknown')
|
expect(environment.comfyui_version).toBe('unknown')
|
||||||
expect(environment.frontend_version).toBe('1.24.0-1')
|
expect(environment.frontend_version).toBe('1.24.0-1')
|
||||||
expect(environment.python_version).toBe('unknown')
|
|
||||||
expect(environment.available_accelerators).toEqual(['CPU'])
|
expect(environment.available_accelerators).toEqual(['CPU'])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -325,7 +321,7 @@ describe.skip('useConflictDetection with Registry Store', () => {
|
|||||||
expect(unknownPackage.conflicts).toEqual(
|
expect(unknownPackage.conflicts).toEqual(
|
||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
type: 'security_pending',
|
type: 'pending',
|
||||||
current_value: 'no_registry_data',
|
current_value: 'no_registry_data',
|
||||||
required_value: 'registry_data_available'
|
required_value: 'registry_data_available'
|
||||||
})
|
})
|
||||||
@@ -1001,7 +997,6 @@ describe.skip('useConflictDetection with Registry Store', () => {
|
|||||||
mockSystemStatsStore.systemStats = {
|
mockSystemStatsStore.systemStats = {
|
||||||
system: {
|
system: {
|
||||||
comfyui_version: '0.3.41',
|
comfyui_version: '0.3.41',
|
||||||
python_version: '3.12.11',
|
|
||||||
os: 'Darwin'
|
os: 'Darwin'
|
||||||
},
|
},
|
||||||
devices: []
|
devices: []
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ describe('useConflictDetectionStore', () => {
|
|||||||
is_compatible: false,
|
is_compatible: false,
|
||||||
conflicts: [
|
conflicts: [
|
||||||
{
|
{
|
||||||
type: 'security_pending',
|
type: 'pending',
|
||||||
current_value: 'no_registry_data',
|
current_value: 'no_registry_data',
|
||||||
required_value: 'registry_data_available'
|
required_value: 'registry_data_available'
|
||||||
}
|
}
|
||||||
@@ -130,7 +130,7 @@ describe('useConflictDetectionStore', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('securityPendingPackages', () => {
|
describe('securityPendingPackages', () => {
|
||||||
it('should filter packages with security_pending conflicts', () => {
|
it('should filter packages with pending conflicts', () => {
|
||||||
const store = useConflictDetectionStore()
|
const store = useConflictDetectionStore()
|
||||||
store.setConflictedPackages(mockConflictedPackages)
|
store.setConflictedPackages(mockConflictedPackages)
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ describe('useConflictDetectionStore', () => {
|
|||||||
required_value: 'not_banned'
|
required_value: 'not_banned'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'security_pending',
|
type: 'pending',
|
||||||
current_value: 'no_registry_data',
|
current_value: 'no_registry_data',
|
||||||
required_value: 'registry_data_available'
|
required_value: 'registry_data_available'
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user