|
import fs from 'node:fs'; |
|
import path from 'node:path'; |
|
import yaml from 'yaml'; |
|
import color from 'chalk'; |
|
import _ from 'lodash'; |
|
import { serverDirectory } from './server-directory.js'; |
|
import { setConfigFilePath } from './util.js'; |
|
|
|
const keyMigrationMap = [ |
|
{ |
|
oldKey: 'disableThumbnails', |
|
newKey: 'thumbnails.enabled', |
|
migrate: (value) => !value, |
|
}, |
|
{ |
|
oldKey: 'thumbnailsQuality', |
|
newKey: 'thumbnails.quality', |
|
migrate: (value) => value, |
|
}, |
|
{ |
|
oldKey: 'avatarThumbnailsPng', |
|
newKey: 'thumbnails.format', |
|
migrate: (value) => (value ? 'png' : 'jpg'), |
|
}, |
|
{ |
|
oldKey: 'disableChatBackup', |
|
newKey: 'backups.chat.enabled', |
|
migrate: (value) => !value, |
|
}, |
|
{ |
|
oldKey: 'numberOfBackups', |
|
newKey: 'backups.common.numberOfBackups', |
|
migrate: (value) => value, |
|
}, |
|
{ |
|
oldKey: 'maxTotalChatBackups', |
|
newKey: 'backups.chat.maxTotalBackups', |
|
migrate: (value) => value, |
|
}, |
|
{ |
|
oldKey: 'chatBackupThrottleInterval', |
|
newKey: 'backups.chat.throttleInterval', |
|
migrate: (value) => value, |
|
}, |
|
{ |
|
oldKey: 'enableExtensions', |
|
newKey: 'extensions.enabled', |
|
migrate: (value) => value, |
|
}, |
|
{ |
|
oldKey: 'enableExtensionsAutoUpdate', |
|
newKey: 'extensions.autoUpdate', |
|
migrate: (value) => value, |
|
}, |
|
{ |
|
oldKey: 'extras.disableAutoDownload', |
|
newKey: 'extensions.models.autoDownload', |
|
migrate: (value) => !value, |
|
}, |
|
{ |
|
oldKey: 'extras.classificationModel', |
|
newKey: 'extensions.models.classification', |
|
migrate: (value) => value, |
|
}, |
|
{ |
|
oldKey: 'extras.captioningModel', |
|
newKey: 'extensions.models.captioning', |
|
migrate: (value) => value, |
|
}, |
|
{ |
|
oldKey: 'extras.embeddingModel', |
|
newKey: 'extensions.models.embedding', |
|
migrate: (value) => value, |
|
}, |
|
{ |
|
oldKey: 'extras.speechToTextModel', |
|
newKey: 'extensions.models.speechToText', |
|
migrate: (value) => value, |
|
}, |
|
{ |
|
oldKey: 'extras.textToSpeechModel', |
|
newKey: 'extensions.models.textToSpeech', |
|
migrate: (value) => value, |
|
}, |
|
{ |
|
oldKey: 'minLogLevel', |
|
newKey: 'logging.minLogLevel', |
|
migrate: (value) => value, |
|
}, |
|
{ |
|
oldKey: 'cardsCacheCapacity', |
|
newKey: 'performance.memoryCacheCapacity', |
|
migrate: (value) => `${value}mb`, |
|
}, |
|
{ |
|
oldKey: 'cookieSecret', |
|
newKey: 'cookieSecret', |
|
migrate: () => void 0, |
|
remove: true, |
|
}, |
|
]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function getAllKeys(obj, prefix = '') { |
|
if (typeof obj !== 'object' || Array.isArray(obj) || obj === null) { |
|
return []; |
|
} |
|
|
|
return _.flatMap(Object.keys(obj), key => { |
|
const newPrefix = prefix ? `${prefix}.${key}` : key; |
|
if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) { |
|
return getAllKeys(obj[key], newPrefix); |
|
} else { |
|
return [newPrefix]; |
|
} |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
export function addMissingConfigValues(configPath) { |
|
try { |
|
const defaultConfig = yaml.parse(fs.readFileSync(path.join(serverDirectory, './default/config.yaml'), 'utf8')); |
|
let config = yaml.parse(fs.readFileSync(configPath, 'utf8')); |
|
|
|
|
|
const migratedKeys = []; |
|
for (const { oldKey, newKey, migrate, remove } of keyMigrationMap) { |
|
if (_.has(config, oldKey)) { |
|
if (remove) { |
|
_.unset(config, oldKey); |
|
migratedKeys.push({ |
|
oldKey, |
|
newValue: void 0, |
|
}); |
|
continue; |
|
} |
|
|
|
const oldValue = _.get(config, oldKey); |
|
const newValue = migrate(oldValue); |
|
_.set(config, newKey, newValue); |
|
_.unset(config, oldKey); |
|
|
|
migratedKeys.push({ |
|
oldKey, |
|
newKey, |
|
oldValue, |
|
newValue, |
|
}); |
|
} |
|
} |
|
|
|
|
|
const originalKeys = getAllKeys(config); |
|
|
|
|
|
config = _.defaultsDeep(config, defaultConfig); |
|
|
|
|
|
const updatedKeys = getAllKeys(config); |
|
|
|
|
|
const addedKeys = _.difference(updatedKeys, originalKeys); |
|
|
|
if (addedKeys.length === 0 && migratedKeys.length === 0) { |
|
return; |
|
} |
|
|
|
if (addedKeys.length > 0) { |
|
console.log('Adding missing config values to config.yaml:', addedKeys); |
|
} |
|
|
|
if (migratedKeys.length > 0) { |
|
console.log('Migrating config values in config.yaml:', migratedKeys); |
|
} |
|
|
|
fs.writeFileSync(configPath, yaml.stringify(config)); |
|
} catch (error) { |
|
console.error(color.red('FATAL: Could not add missing config values to config.yaml'), error); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
export function initConfig(configPath) { |
|
setConfigFilePath(configPath); |
|
addMissingConfigValues(configPath); |
|
} |
|
|