From ce0431589935d03548caef8ca9579f804b5290bd Mon Sep 17 00:00:00 2001 From: fallenbagel <98979876+Fallenbagel@users.noreply.github.com> Date: Sat, 1 Jun 2024 03:31:50 +0500 Subject: [PATCH] refactor(settingsmigrator): settings migration handler and the migrations --- server/lib/settings/index.ts | 20 +++-------- ...-migration.ts => 0001_migrate_hostname.ts} | 11 +++---- server/lib/settings/migrator.ts | 21 ++++++++++++ server/lib/settings/settingsMigrator.ts | 33 ------------------- 4 files changed, 30 insertions(+), 55 deletions(-) rename server/lib/settings/migrations/{remove-jellyfin-hostname-migration.ts => 0001_migrate_hostname.ts} (90%) create mode 100644 server/lib/settings/migrator.ts delete mode 100644 server/lib/settings/settingsMigrator.ts diff --git a/server/lib/settings/index.ts b/server/lib/settings/index.ts index bb7e1ca5a..ad613cc30 100644 --- a/server/lib/settings/index.ts +++ b/server/lib/settings/index.ts @@ -1,7 +1,6 @@ import { MediaServerType } from '@server/constants/server'; import { Permission } from '@server/lib/permissions'; -import { SettingsMigrator } from '@server/lib/settings/settingsMigrator'; -import logger from '@server/logger'; +import { runMigrations } from '@server/lib/settings/migrator'; import { randomUUID } from 'crypto'; import fs from 'fs'; import { merge } from 'lodash'; @@ -295,7 +294,7 @@ export interface AllSettings { const SETTINGS_PATH = process.env.CONFIG_DIRECTORY ? `${process.env.CONFIG_DIRECTORY}/settings.json` - : path.join(__dirname, '../../config/settings.json'); + : path.join(__dirname, '../../../config/settings.json'); class Settings { private data: AllSettings; @@ -643,20 +642,11 @@ class Settings { if (data) { const parsedJson = JSON.parse(data); + this.data = runMigrations(parsedJson); - SettingsMigrator.migrateSettings(parsedJson) - .then((migrated) => { - this.data = Object.assign(this.data, migrated); - this.data = merge(this.data, migrated); + this.data = merge(this.data, parsedJson); - this.save(); - }) - .catch((error) => { - logger.error('Error migrating settings', { - label: 'Settings', - error: error, - }); - }); + this.save(); } return this; } diff --git a/server/lib/settings/migrations/remove-jellyfin-hostname-migration.ts b/server/lib/settings/migrations/0001_migrate_hostname.ts similarity index 90% rename from server/lib/settings/migrations/remove-jellyfin-hostname-migration.ts rename to server/lib/settings/migrations/0001_migrate_hostname.ts index b3ce56378..c514ac2db 100644 --- a/server/lib/settings/migrations/remove-jellyfin-hostname-migration.ts +++ b/server/lib/settings/migrations/0001_migrate_hostname.ts @@ -1,18 +1,15 @@ import type { AllSettings } from '@server/lib/settings'; -export default function removeHostnameMigration(settings: any): AllSettings { +const migrateHostname = (settings: any): AllSettings => { const oldJellyfinSettings = settings.jellyfin; - if (oldJellyfinSettings && oldJellyfinSettings.hostname) { const { hostname } = oldJellyfinSettings; const protocolMatch = hostname.match(/^(https?):\/\//i); const useSsl = protocolMatch && protocolMatch[1].toLowerCase() === 'https'; - const remainingUrl = hostname.replace(/^(https?):\/\//i, ''); const urlMatch = remainingUrl.match(/^([^:]+)(:([0-9]+))?(\/.*)?$/); delete oldJellyfinSettings.hostname; - if (urlMatch) { const [, ip, , port, urlBase] = urlMatch; settings.jellyfin = { @@ -24,10 +21,10 @@ export default function removeHostnameMigration(settings: any): AllSettings { }; } } - if (settings.jellyfin && settings.jellyfin.hostname) { delete settings.jellyfin.hostname; } - return settings; -} +}; + +export default migrateHostname; diff --git a/server/lib/settings/migrator.ts b/server/lib/settings/migrator.ts new file mode 100644 index 000000000..9d709590d --- /dev/null +++ b/server/lib/settings/migrator.ts @@ -0,0 +1,21 @@ +import type { AllSettings } from '@server/lib/settings'; +import fs from 'fs'; +import path from 'path'; + +const migrationsDir = path.join(__dirname, 'migrations'); + +export const runMigrations = (settings: AllSettings): AllSettings => { + const migrations = fs + .readdirSync(migrationsDir) + .filter((file) => file.endsWith('.js') || file.endsWith('.ts')) + // eslint-disable-next-line @typescript-eslint/no-var-requires + .map((file) => require(path.join(migrationsDir, file)).default); + + let migrated = settings; + + for (const migration of migrations) { + migrated = migration(migrated); + } + + return migrated; +}; diff --git a/server/lib/settings/settingsMigrator.ts b/server/lib/settings/settingsMigrator.ts deleted file mode 100644 index ba25b234e..000000000 --- a/server/lib/settings/settingsMigrator.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type { AllSettings } from '@server/lib/settings'; -import fs from 'fs'; -import path from 'path'; - -export class SettingsMigrator { - static async migrateSettings(settings: AllSettings): Promise { - const migrations = await this.loadMigrations(); - for (const migration of Object.values(migrations)) { - settings = await migration(settings); - } - return settings; - } - - private static async loadMigrations(): Promise< - ((settings: AllSettings) => AllSettings)[] - > { - const migrationDir = path.join(__dirname, 'migrations'); - const migrationFiles = fs.readdirSync(migrationDir); - const migrationScripts: ((settings: AllSettings) => AllSettings)[] = []; - - for (const file of migrationFiles) { - if (file.endsWith('.js') || file.endsWith('.ts')) { - const scriptPath = path.join(migrationDir, file); - const migrationScript = (await import(scriptPath)).default; - if (typeof migrationScript === 'function') { - migrationScripts.push(migrationScript); - } - } - } - - return migrationScripts; - } -}