refactor(settingsmigrator): settings migration handler and the migrations

This commit is contained in:
fallenbagel
2024-06-01 03:31:50 +05:00
parent 130bb298f7
commit ce04315899
4 changed files with 30 additions and 55 deletions

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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<AllSettings> {
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;
}
}