add defaultsByInstallVersion (#4354)

This commit is contained in:
Terry Jia
2025-07-06 16:28:58 -04:00
committed by GitHub
parent 469594e5cc
commit 4cbcded820
3 changed files with 285 additions and 0 deletions

View File

@@ -7,6 +7,7 @@ import { api } from '@/scripts/api'
import { app } from '@/scripts/app'
import type { SettingParams } from '@/types/settingTypes'
import type { TreeNode } from '@/types/treeExplorerTypes'
import { compareVersions } from '@/utils/formatUtil'
export const getSettingInfo = (setting: SettingParams) => {
const parts = setting.category || setting.id.split('.')
@@ -83,11 +84,56 @@ export const useSettingStore = defineStore('setting', () => {
*/
function getDefaultValue<K extends keyof Settings>(key: K): Settings[K] {
const param = settingsById.value[key]
const versionedDefault = getVersionedDefaultValue(key, param)
if (versionedDefault) {
return versionedDefault
}
return typeof param?.defaultValue === 'function'
? param.defaultValue()
: param?.defaultValue
}
function getVersionedDefaultValue<K extends keyof Settings>(
key: K,
param: SettingParams
): Settings[K] | null {
// get default versioned value, skipping if the key is 'Comfy.InstalledVersion' to prevent infinite loop
if (param?.defaultsByInstallVersion && key !== 'Comfy.InstalledVersion') {
const installedVersion = get('Comfy.InstalledVersion')
if (installedVersion) {
const sortedVersions = Object.keys(param.defaultsByInstallVersion).sort(
(a, b) => compareVersions(a, b)
)
for (const version of sortedVersions.reverse()) {
// Ensure the version is in a valid format before comparing
if (!isValidVersionFormat(version)) {
continue
}
if (compareVersions(installedVersion, version) >= 0) {
const versionedDefault = param.defaultsByInstallVersion[version]
return typeof versionedDefault === 'function'
? versionedDefault()
: versionedDefault
}
}
}
}
return null
}
function isValidVersionFormat(
version: string
): version is `${number}.${number}.${number}` {
return /^\d+\.\d+\.\d+$/.test(version)
}
/**
* Register a setting.
* @param setting - The setting to register.

View File

@@ -35,6 +35,10 @@ export interface Setting {
export interface SettingParams extends FormItem {
id: keyof Settings
defaultValue: any | (() => any)
defaultsByInstallVersion?: Record<
`${number}.${number}.${number}`,
any | (() => any)
>
onChange?: (newValue: any, oldValue?: any) => void
// By default category is id.split('.'). However, changing id to assign
// new category has poor backward compatibility. Use this field to overwrite

View File

@@ -109,6 +109,241 @@ describe('useSettingStore', () => {
})
})
describe('getDefaultValue', () => {
beforeEach(() => {
// Set up installed version for most tests
store.settingValues['Comfy.InstalledVersion'] = '1.30.0'
})
it('should return regular default value when no defaultsByInstallVersion', () => {
const setting: SettingParams = {
id: 'test.setting',
name: 'Test Setting',
type: 'text',
defaultValue: 'regular-default'
}
store.addSetting(setting)
const result = store.getDefaultValue('test.setting')
expect(result).toBe('regular-default')
})
it('should return versioned default when user version matches', () => {
const setting: SettingParams = {
id: 'test.setting',
name: 'Test Setting',
type: 'text',
defaultValue: 'regular-default',
defaultsByInstallVersion: {
'1.21.3': 'version-1.21.3-default',
'1.40.3': 'version-1.40.3-default'
}
}
store.addSetting(setting)
const result = store.getDefaultValue('test.setting')
// installedVersion is 1.30.0, so should get 1.21.3 default
expect(result).toBe('version-1.21.3-default')
})
it('should return latest versioned default when user version is higher', () => {
store.settingValues['Comfy.InstalledVersion'] = '1.50.0'
const setting: SettingParams = {
id: 'test.setting',
name: 'Test Setting',
type: 'text',
defaultValue: 'regular-default',
defaultsByInstallVersion: {
'1.21.3': 'version-1.21.3-default',
'1.40.3': 'version-1.40.3-default'
}
}
store.addSetting(setting)
const result = store.getDefaultValue('test.setting')
// installedVersion is 1.50.0, so should get 1.40.3 default
expect(result).toBe('version-1.40.3-default')
})
it('should return regular default when user version is lower than all versioned defaults', () => {
store.settingValues['Comfy.InstalledVersion'] = '1.10.0'
const setting: SettingParams = {
id: 'test.setting',
name: 'Test Setting',
type: 'text',
defaultValue: 'regular-default',
defaultsByInstallVersion: {
'1.21.3': 'version-1.21.3-default',
'1.40.3': 'version-1.40.3-default'
}
}
store.addSetting(setting)
const result = store.getDefaultValue('test.setting')
// installedVersion is 1.10.0, lower than all versioned defaults
expect(result).toBe('regular-default')
})
it('should return regular default when no installed version (existing users)', () => {
// Clear installed version to simulate existing user
delete store.settingValues['Comfy.InstalledVersion']
const setting: SettingParams = {
id: 'test.setting',
name: 'Test Setting',
type: 'text',
defaultValue: 'regular-default',
defaultsByInstallVersion: {
'1.21.3': 'version-1.21.3-default',
'1.40.3': 'version-1.40.3-default'
}
}
store.addSetting(setting)
const result = store.getDefaultValue('test.setting')
// No installed version, should use backward compatibility
expect(result).toBe('regular-default')
})
it('should handle function-based versioned defaults', () => {
const setting: SettingParams = {
id: 'test.setting',
name: 'Test Setting',
type: 'text',
defaultValue: 'regular-default',
defaultsByInstallVersion: {
'1.21.3': () => 'dynamic-version-1.21.3-default',
'1.40.3': () => 'dynamic-version-1.40.3-default'
}
}
store.addSetting(setting)
const result = store.getDefaultValue('test.setting')
// installedVersion is 1.30.0, so should get 1.21.3 default (executed)
expect(result).toBe('dynamic-version-1.21.3-default')
})
it('should handle function-based regular defaults with versioned defaults', () => {
store.settingValues['Comfy.InstalledVersion'] = '1.10.0'
const setting: SettingParams = {
id: 'test.setting',
name: 'Test Setting',
type: 'text',
defaultValue: () => 'dynamic-regular-default',
defaultsByInstallVersion: {
'1.21.3': 'version-1.21.3-default',
'1.40.3': 'version-1.40.3-default'
}
}
store.addSetting(setting)
const result = store.getDefaultValue('test.setting')
// installedVersion is 1.10.0, should fallback to function-based regular default
expect(result).toBe('dynamic-regular-default')
})
it('should handle complex version comparison correctly', () => {
const setting: SettingParams = {
id: 'test.setting',
name: 'Test Setting',
type: 'text',
defaultValue: 'regular-default',
defaultsByInstallVersion: {
'1.21.3': 'version-1.21.3-default',
'1.21.10': 'version-1.21.10-default',
'1.40.3': 'version-1.40.3-default'
}
}
store.addSetting(setting)
// Test with 1.21.5 - should get 1.21.3 default
store.settingValues['Comfy.InstalledVersion'] = '1.21.5'
expect(store.getDefaultValue('test.setting')).toBe(
'version-1.21.3-default'
)
// Test with 1.21.15 - should get 1.21.10 default
store.settingValues['Comfy.InstalledVersion'] = '1.21.15'
expect(store.getDefaultValue('test.setting')).toBe(
'version-1.21.10-default'
)
// Test with 1.21.3 exactly - should get 1.21.3 default
store.settingValues['Comfy.InstalledVersion'] = '1.21.3'
expect(store.getDefaultValue('test.setting')).toBe(
'version-1.21.3-default'
)
})
it('should work with get() method using versioned defaults', () => {
const setting: SettingParams = {
id: 'test.setting',
name: 'Test Setting',
type: 'text',
defaultValue: 'regular-default',
defaultsByInstallVersion: {
'1.21.3': 'version-1.21.3-default',
'1.40.3': 'version-1.40.3-default'
}
}
store.addSetting(setting)
// get() should use getDefaultValue internally
const result = store.get('test.setting')
expect(result).toBe('version-1.21.3-default')
})
it('should handle mixed function and static versioned defaults', () => {
const setting: SettingParams = {
id: 'test.setting',
name: 'Test Setting',
type: 'text',
defaultValue: 'regular-default',
defaultsByInstallVersion: {
'1.21.3': () => 'dynamic-1.21.3-default',
'1.40.3': 'static-1.40.3-default'
}
}
store.addSetting(setting)
// Test with 1.30.0 - should get dynamic 1.21.3 default
store.settingValues['Comfy.InstalledVersion'] = '1.30.0'
expect(store.getDefaultValue('test.setting')).toBe(
'dynamic-1.21.3-default'
)
// Test with 1.50.0 - should get static 1.40.3 default
store.settingValues['Comfy.InstalledVersion'] = '1.50.0'
expect(store.getDefaultValue('test.setting')).toBe(
'static-1.40.3-default'
)
})
it('should handle version sorting correctly', () => {
const setting: SettingParams = {
id: 'test.setting',
name: 'Test Setting',
type: 'text',
defaultValue: 'regular-default',
defaultsByInstallVersion: {
'1.40.3': 'version-1.40.3-default',
'1.21.3': 'version-1.21.3-default', // Unsorted order
'1.35.0': 'version-1.35.0-default'
}
}
store.addSetting(setting)
// Test with 1.37.0 - should get 1.35.0 default (highest version <= 1.37.0)
store.settingValues['Comfy.InstalledVersion'] = '1.37.0'
expect(store.getDefaultValue('test.setting')).toBe(
'version-1.35.0-default'
)
})
})
describe('get and set', () => {
it('should get default value when setting not exists', () => {
const setting: SettingParams = {