feat(server): use nestjs events to validate config (#7986)
* use events for config validation * chore: better types * add unit tests --------- Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { AssetEntity, AssetPathType, AssetType, SystemConfig } from '@app/infra/entities';
|
||||
import { ImmichLogger } from '@app/infra/logger';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { OnEvent } from '@nestjs/event-emitter';
|
||||
import handlebar from 'handlebars';
|
||||
import * as luxon from 'luxon';
|
||||
import path from 'node:path';
|
||||
@@ -18,6 +19,8 @@ import {
|
||||
IStorageRepository,
|
||||
ISystemConfigRepository,
|
||||
IUserRepository,
|
||||
InternalEvent,
|
||||
InternalEventMap,
|
||||
JobStatus,
|
||||
} from '../repositories';
|
||||
import { StorageCore, StorageFolder } from '../storage';
|
||||
@@ -74,7 +77,6 @@ export class StorageTemplateService {
|
||||
@Inject(IDatabaseRepository) private databaseRepository: IDatabaseRepository,
|
||||
) {
|
||||
this.configCore = SystemConfigCore.create(configRepository);
|
||||
this.configCore.addValidator((config) => this.validate(config));
|
||||
this.configCore.config$.subscribe((config) => this.onConfig(config));
|
||||
this.storageCore = StorageCore.create(
|
||||
assetRepository,
|
||||
@@ -86,6 +88,27 @@ export class StorageTemplateService {
|
||||
);
|
||||
}
|
||||
|
||||
@OnEvent(InternalEvent.VALIDATE_CONFIG)
|
||||
validate({ newConfig }: InternalEventMap[InternalEvent.VALIDATE_CONFIG]) {
|
||||
try {
|
||||
const { compiled } = this.compile(newConfig.storageTemplate.template);
|
||||
this.render(compiled, {
|
||||
asset: {
|
||||
fileCreatedAt: new Date(),
|
||||
originalPath: '/upload/test/IMG_123.jpg',
|
||||
type: AssetType.IMAGE,
|
||||
id: 'd587e44b-f8c0-4832-9ba3-43268bbf5d4e',
|
||||
} as AssetEntity,
|
||||
filename: 'IMG_123',
|
||||
extension: 'jpg',
|
||||
albumName: 'album',
|
||||
});
|
||||
} catch (error) {
|
||||
this.logger.warn(`Storage template validation failed: ${JSON.stringify(error)}`);
|
||||
throw new Error(`Invalid storage template: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
async handleMigrationSingle({ id }: IEntityJob): Promise<JobStatus> {
|
||||
const config = await this.configCore.getConfig();
|
||||
const storageTemplateEnabled = config.storageTemplate.enabled;
|
||||
@@ -259,26 +282,6 @@ export class StorageTemplateService {
|
||||
}
|
||||
}
|
||||
|
||||
private validate(config: SystemConfig) {
|
||||
try {
|
||||
const { compiled } = this.compile(config.storageTemplate.template);
|
||||
this.render(compiled, {
|
||||
asset: {
|
||||
fileCreatedAt: new Date(),
|
||||
originalPath: '/upload/test/IMG_123.jpg',
|
||||
type: AssetType.IMAGE,
|
||||
id: 'd587e44b-f8c0-4832-9ba3-43268bbf5d4e',
|
||||
} as AssetEntity,
|
||||
filename: 'IMG_123',
|
||||
extension: 'jpg',
|
||||
albumName: 'album',
|
||||
});
|
||||
} catch (error) {
|
||||
this.logger.warn(`Storage template validation failed: ${JSON.stringify(error)}`);
|
||||
throw new Error(`Invalid storage template: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
private onConfig(config: SystemConfig) {
|
||||
const template = config.storageTemplate.template;
|
||||
if (!this._template || template !== this.template.raw) {
|
||||
|
||||
Reference in New Issue
Block a user