refactor: service dependencies (#13108)

refactor(server): simplify service dependency management
This commit is contained in:
Jason Rasmussen 2024-10-02 10:54:35 -04:00 committed by GitHub
parent 1b7e4b4e52
commit 4ea281f854
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
77 changed files with 802 additions and 1862 deletions

View file

@ -1,4 +1,4 @@
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
import { BadRequestException, Injectable } from '@nestjs/common';
import { R_OK } from 'node:constants';
import path, { basename, parse } from 'node:path';
import picomatch from 'picomatch';
@ -17,24 +17,16 @@ import {
import { AssetEntity } from 'src/entities/asset.entity';
import { LibraryEntity } from 'src/entities/library.entity';
import { AssetType } from 'src/enum';
import { IAssetRepository } from 'src/interfaces/asset.interface';
import { IConfigRepository } from 'src/interfaces/config.interface';
import { ICryptoRepository } from 'src/interfaces/crypto.interface';
import { DatabaseLock, IDatabaseRepository } from 'src/interfaces/database.interface';
import { DatabaseLock } from 'src/interfaces/database.interface';
import { ArgOf } from 'src/interfaces/event.interface';
import {
IEntityJob,
IJobRepository,
ILibraryAssetJob,
ILibraryFileJob,
JobName,
JOBS_LIBRARY_PAGINATION_SIZE,
JobStatus,
} from 'src/interfaces/job.interface';
import { ILibraryRepository } from 'src/interfaces/library.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IStorageRepository } from 'src/interfaces/storage.interface';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
import { BaseService } from 'src/services/base.service';
import { mimeTypes } from 'src/utils/mime-types';
import { handlePromiseError } from 'src/utils/misc';
@ -47,21 +39,6 @@ export class LibraryService extends BaseService {
private watchLock = false;
private watchers: Record<string, () => Promise<void>> = {};
constructor(
@Inject(IAssetRepository) private assetRepository: IAssetRepository,
@Inject(IConfigRepository) configRepository: IConfigRepository,
@Inject(ICryptoRepository) private cryptoRepository: ICryptoRepository,
@Inject(IDatabaseRepository) private databaseRepository: IDatabaseRepository,
@Inject(IJobRepository) private jobRepository: IJobRepository,
@Inject(ILibraryRepository) private repository: ILibraryRepository,
@Inject(IStorageRepository) private storageRepository: IStorageRepository,
@Inject(ISystemMetadataRepository) systemMetadataRepository: ISystemMetadataRepository,
@Inject(ILoggerRepository) logger: ILoggerRepository,
) {
super(configRepository, systemMetadataRepository, logger);
this.logger.setContext(LibraryService.name);
}
@OnEvent({ name: 'app.bootstrap' })
async onBootstrap() {
const config = await this.getConfig({ withCache: false });
@ -217,14 +194,14 @@ export class LibraryService extends BaseService {
return false;
}
const libraries = await this.repository.getAll(false);
const libraries = await this.libraryRepository.getAll(false);
for (const library of libraries) {
await this.watch(library.id);
}
}
async getStatistics(id: string): Promise<LibraryStatsResponseDto> {
const statistics = await this.repository.getStatistics(id);
const statistics = await this.libraryRepository.getStatistics(id);
if (!statistics) {
throw new BadRequestException(`Library ${id} not found`);
}
@ -237,13 +214,13 @@ export class LibraryService extends BaseService {
}
async getAll(): Promise<LibraryResponseDto[]> {
const libraries = await this.repository.getAll(false);
const libraries = await this.libraryRepository.getAll(false);
return libraries.map((library) => mapLibrary(library));
}
async handleQueueCleanup(): Promise<JobStatus> {
this.logger.debug('Cleaning up any pending library deletions');
const pendingDeletion = await this.repository.getAllDeleted();
const pendingDeletion = await this.libraryRepository.getAllDeleted();
await this.jobRepository.queueAll(
pendingDeletion.map((libraryToDelete) => ({ name: JobName.LIBRARY_DELETE, data: { id: libraryToDelete.id } })),
);
@ -251,7 +228,7 @@ export class LibraryService extends BaseService {
}
async create(dto: CreateLibraryDto): Promise<LibraryResponseDto> {
const library = await this.repository.create({
const library = await this.libraryRepository.create({
ownerId: dto.ownerId,
name: dto.name ?? 'New External Library',
importPaths: dto.importPaths ?? [],
@ -326,7 +303,7 @@ export class LibraryService extends BaseService {
async update(id: string, dto: UpdateLibraryDto): Promise<LibraryResponseDto> {
await this.findOrFail(id);
const library = await this.repository.update({ id, ...dto });
const library = await this.libraryRepository.update({ id, ...dto });
if (dto.importPaths) {
const validation = await this.validate(id, { importPaths: dto.importPaths });
@ -349,7 +326,7 @@ export class LibraryService extends BaseService {
await this.unwatch(id);
}
await this.repository.softDelete(id);
await this.libraryRepository.softDelete(id);
await this.jobRepository.queue({ name: JobName.LIBRARY_DELETE, data: { id } });
}
@ -379,7 +356,7 @@ export class LibraryService extends BaseService {
if (!assetsFound) {
this.logger.log(`Deleting library ${libraryId}`);
await this.repository.delete(libraryId);
await this.libraryRepository.delete(libraryId);
}
return JobStatus.SUCCESS;
}
@ -407,7 +384,7 @@ export class LibraryService extends BaseService {
this.logger.log(`Importing new library asset: ${assetPath}`);
const library = await this.repository.get(job.id, true);
const library = await this.libraryRepository.get(job.id, true);
if (!library || library.deletedAt) {
this.logger.error('Cannot import asset into deleted library');
return JobStatus.FAILED;
@ -477,7 +454,7 @@ export class LibraryService extends BaseService {
await this.jobRepository.queue({ name: JobName.LIBRARY_QUEUE_CLEANUP, data: {} });
const libraries = await this.repository.getAll(true);
const libraries = await this.libraryRepository.getAll(true);
await this.jobRepository.queueAll(
libraries.map((library) => ({
name: JobName.LIBRARY_QUEUE_SYNC_FILES,
@ -553,7 +530,7 @@ export class LibraryService extends BaseService {
}
async handleQueueSyncFiles(job: IEntityJob): Promise<JobStatus> {
const library = await this.repository.get(job.id);
const library = await this.libraryRepository.get(job.id);
if (!library) {
this.logger.debug(`Library ${job.id} not found, skipping refresh`);
return JobStatus.SKIPPED;
@ -598,13 +575,13 @@ export class LibraryService extends BaseService {
this.logger.warn(`No valid import paths found for library ${library.id}`);
}
await this.repository.update({ id: job.id, refreshedAt: new Date() });
await this.libraryRepository.update({ id: job.id, refreshedAt: new Date() });
return JobStatus.SUCCESS;
}
async handleQueueSyncAssets(job: IEntityJob): Promise<JobStatus> {
const library = await this.repository.get(job.id);
const library = await this.libraryRepository.get(job.id);
if (!library) {
return JobStatus.SKIPPED;
}
@ -636,7 +613,7 @@ export class LibraryService extends BaseService {
}
private async findOrFail(id: string) {
const library = await this.repository.get(id);
const library = await this.libraryRepository.get(id);
if (!library) {
throw new BadRequestException('Library not found');
}