From 9a27a99cab41e630d561e80523ba1ef5647538b4 Mon Sep 17 00:00:00 2001 From: Jason Rasmussen Date: Tue, 21 Jan 2025 13:13:09 -0500 Subject: [PATCH] refactor: config repository (#15495) * refactor: access repository * refactor: config repository --- server/src/cores/storage.core.ts | 2 +- server/src/interfaces/audit.interface.ts | 14 --- server/src/interfaces/config.interface.ts | 98 ------------------ server/src/middleware/websocket.adapter.ts | 4 +- server/src/repositories/audit.repository.ts | 9 +- server/src/repositories/config.repository.ts | 99 +++++++++++++++++-- .../src/repositories/database.repository.ts | 4 +- server/src/repositories/event.repository.ts | 3 +- server/src/repositories/index.ts | 6 +- server/src/repositories/job.repository.ts | 6 +- .../repositories/logger.repository.spec.ts | 2 +- server/src/repositories/logger.repository.ts | 6 +- server/src/repositories/map.repository.ts | 4 +- .../repositories/server-info.repository.ts | 4 +- .../src/repositories/telemetry.repository.ts | 4 +- server/src/services/api.service.ts | 4 +- server/src/services/audit.service.spec.ts | 2 +- server/src/services/backup.service.spec.ts | 2 +- server/src/services/base.service.ts | 8 +- server/src/services/database.service.spec.ts | 2 +- server/src/services/job.service.spec.ts | 2 +- server/src/services/library.service.spec.ts | 2 +- server/src/services/metadata.service.spec.ts | 2 +- .../src/services/smart-info.service.spec.ts | 2 +- server/src/services/storage.service.spec.ts | 2 +- server/src/services/sync.service.spec.ts | 2 +- .../services/system-config.service.spec.ts | 2 +- server/src/services/version.service.spec.ts | 2 +- server/src/types.ts | 4 + server/src/utils/config.ts | 2 +- server/src/workers/api.ts | 3 +- server/src/workers/microservices.ts | 3 +- .../repositories/audit.repository.mock.ts | 2 +- .../repositories/config.repository.mock.ts | 3 +- server/test/utils.ts | 5 +- 35 files changed, 150 insertions(+), 171 deletions(-) delete mode 100644 server/src/interfaces/audit.interface.ts delete mode 100644 server/src/interfaces/config.interface.ts diff --git a/server/src/cores/storage.core.ts b/server/src/cores/storage.core.ts index d26829d633..7285ff2163 100644 --- a/server/src/cores/storage.core.ts +++ b/server/src/cores/storage.core.ts @@ -5,13 +5,13 @@ import { AssetEntity } from 'src/entities/asset.entity'; import { PersonEntity } from 'src/entities/person.entity'; import { AssetFileType, AssetPathType, ImageFormat, PathType, PersonPathType, StorageFolder } 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 { ILoggerRepository } from 'src/interfaces/logger.interface'; import { IMoveRepository } from 'src/interfaces/move.interface'; import { IPersonRepository } from 'src/interfaces/person.interface'; import { IStorageRepository } from 'src/interfaces/storage.interface'; import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface'; +import { IConfigRepository } from 'src/types'; import { getAssetFiles } from 'src/utils/asset.util'; import { getConfig } from 'src/utils/config'; diff --git a/server/src/interfaces/audit.interface.ts b/server/src/interfaces/audit.interface.ts deleted file mode 100644 index 0b9f19d8db..0000000000 --- a/server/src/interfaces/audit.interface.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { DatabaseAction, EntityType } from 'src/enum'; - -export const IAuditRepository = 'IAuditRepository'; - -export interface AuditSearch { - action?: DatabaseAction; - entityType?: EntityType; - userIds: string[]; -} - -export interface IAuditRepository { - getAfter(since: Date, options: AuditSearch): Promise; - removeBefore(before: Date): Promise; -} diff --git a/server/src/interfaces/config.interface.ts b/server/src/interfaces/config.interface.ts deleted file mode 100644 index 8b45078039..0000000000 --- a/server/src/interfaces/config.interface.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { RegisterQueueOptions } from '@nestjs/bullmq'; -import { QueueOptions } from 'bullmq'; -import { RedisOptions } from 'ioredis'; -import { KyselyConfig } from 'kysely'; -import { ClsModuleOptions } from 'nestjs-cls'; -import { OpenTelemetryModuleOptions } from 'nestjs-otel/lib/interfaces'; -import { ImmichEnvironment, ImmichTelemetry, ImmichWorker, LogLevel } from 'src/enum'; -import { DatabaseConnectionParams, VectorExtension } from 'src/interfaces/database.interface'; -import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions.js'; - -export const IConfigRepository = 'IConfigRepository'; - -export interface EnvData { - host?: string; - port: number; - environment: ImmichEnvironment; - configFile?: string; - logLevel?: LogLevel; - - buildMetadata: { - build?: string; - buildUrl?: string; - buildImage?: string; - buildImageUrl?: string; - repository?: string; - repositoryUrl?: string; - sourceRef?: string; - sourceCommit?: string; - sourceUrl?: string; - thirdPartySourceUrl?: string; - thirdPartyBugFeatureUrl?: string; - thirdPartyDocumentationUrl?: string; - thirdPartySupportUrl?: string; - }; - - bull: { - config: QueueOptions; - queues: RegisterQueueOptions[]; - }; - - cls: { - config: ClsModuleOptions; - }; - - database: { - config: { typeorm: PostgresConnectionOptions & DatabaseConnectionParams; kysely: KyselyConfig }; - skipMigrations: boolean; - vectorExtension: VectorExtension; - }; - - licensePublicKey: { - client: string; - server: string; - }; - - network: { - trustedProxies: string[]; - }; - - otel: OpenTelemetryModuleOptions; - - resourcePaths: { - lockFile: string; - geodata: { - dateFile: string; - admin1: string; - admin2: string; - cities500: string; - naturalEarthCountriesPath: string; - }; - web: { - root: string; - indexHtml: string; - }; - }; - - redis: RedisOptions; - - telemetry: { - apiPort: number; - microservicesPort: number; - metrics: Set; - }; - - storage: { - ignoreMountCheckErrors: boolean; - }; - - workers: ImmichWorker[]; - - noColor: boolean; - nodeVersion?: string; -} - -export interface IConfigRepository { - getEnv(): EnvData; - getWorker(): ImmichWorker | undefined; -} diff --git a/server/src/middleware/websocket.adapter.ts b/server/src/middleware/websocket.adapter.ts index da5e5e9816..64bb1f9ea5 100644 --- a/server/src/middleware/websocket.adapter.ts +++ b/server/src/middleware/websocket.adapter.ts @@ -3,7 +3,7 @@ import { IoAdapter } from '@nestjs/platform-socket.io'; import { createAdapter } from '@socket.io/redis-adapter'; import { Redis } from 'ioredis'; import { ServerOptions } from 'socket.io'; -import { IConfigRepository } from 'src/interfaces/config.interface'; +import { ConfigRepository } from 'src/repositories/config.repository'; export class WebSocketAdapter extends IoAdapter { constructor(private app: INestApplicationContext) { @@ -11,7 +11,7 @@ export class WebSocketAdapter extends IoAdapter { } createIOServer(port: number, options?: ServerOptions): any { - const { redis } = this.app.get(IConfigRepository).getEnv(); + const { redis } = this.app.get(ConfigRepository).getEnv(); const server = super.createIOServer(port, options); const pubClient = new Redis(redis); const subClient = pubClient.duplicate(); diff --git a/server/src/repositories/audit.repository.ts b/server/src/repositories/audit.repository.ts index 5731087aef..5961e4f25d 100644 --- a/server/src/repositories/audit.repository.ts +++ b/server/src/repositories/audit.repository.ts @@ -4,10 +4,15 @@ import { InjectKysely } from 'nestjs-kysely'; import { DB } from 'src/db'; import { DummyValue, GenerateSql } from 'src/decorators'; import { DatabaseAction, EntityType } from 'src/enum'; -import { AuditSearch, IAuditRepository } from 'src/interfaces/audit.interface'; + +export interface AuditSearch { + action?: DatabaseAction; + entityType?: EntityType; + userIds: string[]; +} @Injectable() -export class AuditRepository implements IAuditRepository { +export class AuditRepository { constructor(@InjectKysely() private db: Kysely) {} @GenerateSql({ diff --git a/server/src/repositories/config.repository.ts b/server/src/repositories/config.repository.ts index 67699880bd..d78e473da2 100644 --- a/server/src/repositories/config.repository.ts +++ b/server/src/repositories/config.repository.ts @@ -1,19 +1,106 @@ +import { RegisterQueueOptions } from '@nestjs/bullmq'; import { Inject, Injectable, Optional } from '@nestjs/common'; +import { QueueOptions } from 'bullmq'; import { plainToInstance } from 'class-transformer'; import { validateSync } from 'class-validator'; import { Request, Response } from 'express'; +import { RedisOptions } from 'ioredis'; +import { KyselyConfig } from 'kysely'; import { PostgresJSDialect } from 'kysely-postgres-js'; -import { CLS_ID } from 'nestjs-cls'; +import { CLS_ID, ClsModuleOptions } from 'nestjs-cls'; +import { OpenTelemetryModuleOptions } from 'nestjs-otel/lib/interfaces'; import { join, resolve } from 'node:path'; import postgres, { Notice } from 'postgres'; import { citiesFile, excludePaths, IWorker } from 'src/constants'; import { Telemetry } from 'src/decorators'; import { EnvDto } from 'src/dtos/env.dto'; -import { ImmichEnvironment, ImmichHeader, ImmichTelemetry, ImmichWorker } from 'src/enum'; -import { EnvData, IConfigRepository } from 'src/interfaces/config.interface'; -import { DatabaseExtension } from 'src/interfaces/database.interface'; +import { ImmichEnvironment, ImmichHeader, ImmichTelemetry, ImmichWorker, LogLevel } from 'src/enum'; +import { DatabaseConnectionParams, DatabaseExtension, VectorExtension } from 'src/interfaces/database.interface'; import { QueueName } from 'src/interfaces/job.interface'; import { setDifference } from 'src/utils/set'; +import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions.js'; + +export interface EnvData { + host?: string; + port: number; + environment: ImmichEnvironment; + configFile?: string; + logLevel?: LogLevel; + + buildMetadata: { + build?: string; + buildUrl?: string; + buildImage?: string; + buildImageUrl?: string; + repository?: string; + repositoryUrl?: string; + sourceRef?: string; + sourceCommit?: string; + sourceUrl?: string; + thirdPartySourceUrl?: string; + thirdPartyBugFeatureUrl?: string; + thirdPartyDocumentationUrl?: string; + thirdPartySupportUrl?: string; + }; + + bull: { + config: QueueOptions; + queues: RegisterQueueOptions[]; + }; + + cls: { + config: ClsModuleOptions; + }; + + database: { + config: { typeorm: PostgresConnectionOptions & DatabaseConnectionParams; kysely: KyselyConfig }; + skipMigrations: boolean; + vectorExtension: VectorExtension; + }; + + licensePublicKey: { + client: string; + server: string; + }; + + network: { + trustedProxies: string[]; + }; + + otel: OpenTelemetryModuleOptions; + + resourcePaths: { + lockFile: string; + geodata: { + dateFile: string; + admin1: string; + admin2: string; + cities500: string; + naturalEarthCountriesPath: string; + }; + web: { + root: string; + indexHtml: string; + }; + }; + + redis: RedisOptions; + + telemetry: { + apiPort: number; + microservicesPort: number; + metrics: Set; + }; + + storage: { + ignoreMountCheckErrors: boolean; + }; + + workers: ImmichWorker[]; + + noColor: boolean; + nodeVersion?: string; +} const productionKeys = { client: @@ -269,10 +356,10 @@ let cached: EnvData | undefined; @Injectable() @Telemetry({ enabled: false }) -export class ConfigRepository implements IConfigRepository { +export class ConfigRepository { constructor(@Inject(IWorker) @Optional() private worker?: ImmichWorker) {} - getEnv(): EnvData { + getEnv() { if (!cached) { cached = getEnv(); } diff --git a/server/src/repositories/database.repository.ts b/server/src/repositories/database.repository.ts index 7188678212..336da8f303 100644 --- a/server/src/repositories/database.repository.ts +++ b/server/src/repositories/database.repository.ts @@ -6,7 +6,6 @@ import { InjectKysely } from 'nestjs-kysely'; import semver from 'semver'; import { POSTGRES_VERSION_RANGE, VECTOR_VERSION_RANGE, VECTORS_VERSION_RANGE } from 'src/constants'; import { DB } from 'src/db'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { DatabaseExtension, DatabaseLock, @@ -18,6 +17,7 @@ import { VectorUpdateResult, } from 'src/interfaces/database.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface'; +import { ConfigRepository } from 'src/repositories/config.repository'; import { UPSERT_COLUMNS } from 'src/utils/database'; import { isValidInteger } from 'src/validation'; import { DataSource, EntityManager, EntityMetadata, QueryRunner } from 'typeorm'; @@ -31,7 +31,7 @@ export class DatabaseRepository implements IDatabaseRepository { @InjectKysely() private db: Kysely, @InjectDataSource() private dataSource: DataSource, @Inject(ILoggerRepository) private logger: ILoggerRepository, - @Inject(IConfigRepository) configRepository: IConfigRepository, + configRepository: ConfigRepository, ) { this.vectorExtension = configRepository.getEnv().database.vectorExtension; this.logger.setContext(DatabaseRepository.name); diff --git a/server/src/repositories/event.repository.ts b/server/src/repositories/event.repository.ts index 7de8defe6e..e1c31624d5 100644 --- a/server/src/repositories/event.repository.ts +++ b/server/src/repositories/event.repository.ts @@ -12,7 +12,6 @@ import _ from 'lodash'; import { Server, Socket } from 'socket.io'; import { EventConfig } from 'src/decorators'; import { ImmichWorker, MetadataKey } from 'src/enum'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { ArgsOf, ClientEventMap, @@ -52,7 +51,7 @@ export class EventRepository implements OnGatewayConnection, OnGatewayDisconnect constructor( private moduleRef: ModuleRef, - @Inject(IConfigRepository) private configRepository: ConfigRepository, + private configRepository: ConfigRepository, @Inject(ILoggerRepository) private logger: ILoggerRepository, ) { this.logger.setContext(EventRepository.name); diff --git a/server/src/repositories/index.ts b/server/src/repositories/index.ts index 434efa935f..68c79fbe98 100644 --- a/server/src/repositories/index.ts +++ b/server/src/repositories/index.ts @@ -1,8 +1,6 @@ import { IAlbumUserRepository } from 'src/interfaces/album-user.interface'; import { IAlbumRepository } from 'src/interfaces/album.interface'; import { IAssetRepository } from 'src/interfaces/asset.interface'; -import { IAuditRepository } from 'src/interfaces/audit.interface'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { ICronRepository } from 'src/interfaces/cron.interface'; import { ICryptoRepository } from 'src/interfaces/crypto.interface'; import { IDatabaseRepository } from 'src/interfaces/database.interface'; @@ -78,15 +76,15 @@ export const repositories = [ // AccessRepository, ActivityRepository, + AuditRepository, ApiKeyRepository, + ConfigRepository, ]; export const providers = [ { provide: IAlbumRepository, useClass: AlbumRepository }, { provide: IAlbumUserRepository, useClass: AlbumUserRepository }, { provide: IAssetRepository, useClass: AssetRepository }, - { provide: IAuditRepository, useClass: AuditRepository }, - { provide: IConfigRepository, useClass: ConfigRepository }, { provide: ICronRepository, useClass: CronRepository }, { provide: ICryptoRepository, useClass: CryptoRepository }, { provide: IDatabaseRepository, useClass: DatabaseRepository }, diff --git a/server/src/repositories/job.repository.ts b/server/src/repositories/job.repository.ts index c6c2947617..e57b5ee964 100644 --- a/server/src/repositories/job.repository.ts +++ b/server/src/repositories/job.repository.ts @@ -1,13 +1,11 @@ import { getQueueToken } from '@nestjs/bullmq'; import { Inject, Injectable } from '@nestjs/common'; import { ModuleRef, Reflector } from '@nestjs/core'; -import { SchedulerRegistry } from '@nestjs/schedule'; import { JobsOptions, Queue, Worker } from 'bullmq'; import { ClassConstructor } from 'class-transformer'; import { setTimeout } from 'node:timers/promises'; import { JobConfig } from 'src/decorators'; import { MetadataKey } from 'src/enum'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { IEventRepository } from 'src/interfaces/event.interface'; import { IEntityJob, @@ -22,6 +20,7 @@ import { QueueStatus, } from 'src/interfaces/job.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface'; +import { ConfigRepository } from 'src/repositories/config.repository'; import { getKeyByValue, getMethodNames, ImmichStartupError } from 'src/utils/misc'; type JobMapItem = { @@ -38,8 +37,7 @@ export class JobRepository implements IJobRepository { constructor( private moduleRef: ModuleRef, - private schedulerRegistry: SchedulerRegistry, - @Inject(IConfigRepository) private configRepository: IConfigRepository, + private configRepository: ConfigRepository, @Inject(IEventRepository) private eventRepository: IEventRepository, @Inject(ILoggerRepository) private logger: ILoggerRepository, ) { diff --git a/server/src/repositories/logger.repository.spec.ts b/server/src/repositories/logger.repository.spec.ts index dcb54ada7c..7354035763 100644 --- a/server/src/repositories/logger.repository.spec.ts +++ b/server/src/repositories/logger.repository.spec.ts @@ -1,7 +1,7 @@ import { ClsService } from 'nestjs-cls'; import { ImmichWorker } from 'src/enum'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { LoggerRepository } from 'src/repositories/logger.repository'; +import { IConfigRepository } from 'src/types'; import { mockEnvData, newConfigRepositoryMock } from 'test/repositories/config.repository.mock'; import { Mocked } from 'vitest'; diff --git a/server/src/repositories/logger.repository.ts b/server/src/repositories/logger.repository.ts index 4f1d3cac22..c4f0f91e15 100644 --- a/server/src/repositories/logger.repository.ts +++ b/server/src/repositories/logger.repository.ts @@ -1,10 +1,10 @@ -import { ConsoleLogger, Inject, Injectable, Scope } from '@nestjs/common'; +import { ConsoleLogger, Injectable, Scope } from '@nestjs/common'; import { isLogLevelEnabled } from '@nestjs/common/services/utils/is-log-level-enabled.util'; import { ClsService } from 'nestjs-cls'; import { Telemetry } from 'src/decorators'; import { LogLevel } from 'src/enum'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface'; +import { ConfigRepository } from 'src/repositories/config.repository'; const LOG_LEVELS = [LogLevel.VERBOSE, LogLevel.DEBUG, LogLevel.LOG, LogLevel.WARN, LogLevel.ERROR, LogLevel.FATAL]; @@ -25,7 +25,7 @@ export class LoggerRepository extends ConsoleLogger implements ILoggerRepository constructor( private cls: ClsService, - @Inject(IConfigRepository) configRepository: IConfigRepository, + configRepository: ConfigRepository, ) { super(LoggerRepository.name); diff --git a/server/src/repositories/map.repository.ts b/server/src/repositories/map.repository.ts index 00870e78eb..4f6e78487d 100644 --- a/server/src/repositories/map.repository.ts +++ b/server/src/repositories/map.repository.ts @@ -11,7 +11,6 @@ import { DB, GeodataPlaces, NaturalearthCountries } from 'src/db'; import { AssetEntity, withExif } from 'src/entities/asset.entity'; import { NaturalEarthCountriesTempEntity } from 'src/entities/natural-earth-countries.entity'; import { LogLevel, SystemMetadataKey } from 'src/enum'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface'; import { GeoPoint, @@ -21,6 +20,7 @@ import { ReverseGeocodeResult, } from 'src/interfaces/map.interface'; import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface'; +import { ConfigRepository } from 'src/repositories/config.repository'; interface MapDB extends DB { geodata_places_tmp: GeodataPlaces; @@ -30,7 +30,7 @@ interface MapDB extends DB { @Injectable() export class MapRepository implements IMapRepository { constructor( - @Inject(IConfigRepository) private configRepository: IConfigRepository, + private configRepository: ConfigRepository, @Inject(ISystemMetadataRepository) private metadataRepository: ISystemMetadataRepository, @Inject(ILoggerRepository) private logger: ILoggerRepository, @InjectKysely() private db: Kysely, diff --git a/server/src/repositories/server-info.repository.ts b/server/src/repositories/server-info.repository.ts index b4a4652871..13423d82b9 100644 --- a/server/src/repositories/server-info.repository.ts +++ b/server/src/repositories/server-info.repository.ts @@ -4,9 +4,9 @@ import { exec as execCallback } from 'node:child_process'; import { readFile } from 'node:fs/promises'; import { promisify } from 'node:util'; import sharp from 'sharp'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface'; import { GitHubRelease, IServerInfoRepository, ServerBuildVersions } from 'src/interfaces/server-info.interface'; +import { ConfigRepository } from 'src/repositories/config.repository'; const exec = promisify(execCallback); const maybeFirstLine = async (command: string): Promise => { @@ -36,7 +36,7 @@ const getLockfileVersion = (name: string, lockfile?: BuildLockfile) => { @Injectable() export class ServerInfoRepository implements IServerInfoRepository { constructor( - @Inject(IConfigRepository) private configRepository: IConfigRepository, + private configRepository: ConfigRepository, @Inject(ILoggerRepository) private logger: ILoggerRepository, ) { this.logger.setContext(ServerInfoRepository.name); diff --git a/server/src/repositories/telemetry.repository.ts b/server/src/repositories/telemetry.repository.ts index 2510460967..c4401c9da3 100644 --- a/server/src/repositories/telemetry.repository.ts +++ b/server/src/repositories/telemetry.repository.ts @@ -15,9 +15,9 @@ import { MetricService } from 'nestjs-otel'; import { copyMetadataFromFunctionToFunction } from 'nestjs-otel/lib/opentelemetry.utils'; import { serverVersion } from 'src/constants'; import { ImmichTelemetry, MetadataKey } from 'src/enum'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface'; import { IMetricGroupRepository, ITelemetryRepository, MetricGroupOptions } from 'src/interfaces/telemetry.interface'; +import { ConfigRepository } from 'src/repositories/config.repository'; class MetricGroupRepository implements IMetricGroupRepository { private enabled = false; @@ -95,7 +95,7 @@ export class TelemetryRepository implements ITelemetryRepository { constructor( private metricService: MetricService, private reflect: Reflector, - @Inject(IConfigRepository) private configRepository: IConfigRepository, + private configRepository: ConfigRepository, @Inject(ILoggerRepository) private logger: ILoggerRepository, ) { const { telemetry } = this.configRepository.getEnv(); diff --git a/server/src/services/api.service.ts b/server/src/services/api.service.ts index 66f8061d3c..3fec0dbc0a 100644 --- a/server/src/services/api.service.ts +++ b/server/src/services/api.service.ts @@ -3,8 +3,8 @@ import { Cron, CronExpression, Interval } from '@nestjs/schedule'; import { NextFunction, Request, Response } from 'express'; import { readFileSync } from 'node:fs'; import { ONE_HOUR } from 'src/constants'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface'; +import { ConfigRepository } from 'src/repositories/config.repository'; import { AuthService } from 'src/services/auth.service'; import { JobService } from 'src/services/job.service'; import { SharedLinkService } from 'src/services/shared-link.service'; @@ -38,7 +38,7 @@ export class ApiService { private jobService: JobService, private sharedLinkService: SharedLinkService, private versionService: VersionService, - @Inject(IConfigRepository) private configRepository: IConfigRepository, + private configRepository: ConfigRepository, @Inject(ILoggerRepository) private logger: ILoggerRepository, ) { this.logger.setContext(ApiService.name); diff --git a/server/src/services/audit.service.spec.ts b/server/src/services/audit.service.spec.ts index c7a51565af..dd853042fb 100644 --- a/server/src/services/audit.service.spec.ts +++ b/server/src/services/audit.service.spec.ts @@ -2,12 +2,12 @@ import { BadRequestException } from '@nestjs/common'; import { FileReportItemDto } from 'src/dtos/audit.dto'; import { AssetFileType, AssetPathType, DatabaseAction, EntityType, PersonPathType, UserPathType } from 'src/enum'; import { IAssetRepository } from 'src/interfaces/asset.interface'; -import { IAuditRepository } from 'src/interfaces/audit.interface'; import { ICryptoRepository } from 'src/interfaces/crypto.interface'; import { JobStatus } from 'src/interfaces/job.interface'; import { IPersonRepository } from 'src/interfaces/person.interface'; import { IUserRepository } from 'src/interfaces/user.interface'; import { AuditService } from 'src/services/audit.service'; +import { IAuditRepository } from 'src/types'; import { auditStub } from 'test/fixtures/audit.stub'; import { authStub } from 'test/fixtures/auth.stub'; import { newTestService } from 'test/utils'; diff --git a/server/src/services/backup.service.spec.ts b/server/src/services/backup.service.spec.ts index 41ba7c2153..29adf9d8e1 100644 --- a/server/src/services/backup.service.spec.ts +++ b/server/src/services/backup.service.spec.ts @@ -2,7 +2,6 @@ import { PassThrough } from 'node:stream'; import { defaults, SystemConfig } from 'src/config'; import { StorageCore } from 'src/cores/storage.core'; import { ImmichWorker, StorageFolder } from 'src/enum'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { ICronRepository } from 'src/interfaces/cron.interface'; import { IDatabaseRepository } from 'src/interfaces/database.interface'; import { JobStatus } from 'src/interfaces/job.interface'; @@ -10,6 +9,7 @@ import { IProcessRepository } from 'src/interfaces/process.interface'; import { IStorageRepository } from 'src/interfaces/storage.interface'; import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface'; import { BackupService } from 'src/services/backup.service'; +import { IConfigRepository } from 'src/types'; import { systemConfigStub } from 'test/fixtures/system-config.stub'; import { mockSpawn, newTestService } from 'test/utils'; import { describe, Mocked } from 'vitest'; diff --git a/server/src/services/base.service.ts b/server/src/services/base.service.ts index adcddd8d66..054cc2acfa 100644 --- a/server/src/services/base.service.ts +++ b/server/src/services/base.service.ts @@ -9,8 +9,6 @@ import { UserEntity } from 'src/entities/user.entity'; import { IAlbumUserRepository } from 'src/interfaces/album-user.interface'; import { IAlbumRepository } from 'src/interfaces/album.interface'; import { IAssetRepository } from 'src/interfaces/asset.interface'; -import { IAuditRepository } from 'src/interfaces/audit.interface'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { ICronRepository } from 'src/interfaces/cron.interface'; import { ICryptoRepository } from 'src/interfaces/crypto.interface'; import { IDatabaseRepository } from 'src/interfaces/database.interface'; @@ -45,6 +43,8 @@ import { IViewRepository } from 'src/interfaces/view.interface'; import { AccessRepository } from 'src/repositories/access.repository'; import { ActivityRepository } from 'src/repositories/activity.repository'; import { ApiKeyRepository } from 'src/repositories/api-key.repository'; +import { AuditRepository } from 'src/repositories/audit.repository'; +import { ConfigRepository } from 'src/repositories/config.repository'; import { AccessRequest, checkAccess, requireAccess } from 'src/utils/access'; import { getConfig, updateConfig } from 'src/utils/config'; @@ -55,11 +55,11 @@ export class BaseService { @Inject(ILoggerRepository) protected logger: ILoggerRepository, protected accessRepository: AccessRepository, protected activityRepository: ActivityRepository, - @Inject(IAuditRepository) protected auditRepository: IAuditRepository, + protected auditRepository: AuditRepository, @Inject(IAlbumRepository) protected albumRepository: IAlbumRepository, @Inject(IAlbumUserRepository) protected albumUserRepository: IAlbumUserRepository, @Inject(IAssetRepository) protected assetRepository: IAssetRepository, - @Inject(IConfigRepository) protected configRepository: IConfigRepository, + protected configRepository: ConfigRepository, @Inject(ICronRepository) protected cronRepository: ICronRepository, @Inject(ICryptoRepository) protected cryptoRepository: ICryptoRepository, @Inject(IDatabaseRepository) protected databaseRepository: IDatabaseRepository, diff --git a/server/src/services/database.service.spec.ts b/server/src/services/database.service.spec.ts index ef60415402..9458ba768b 100644 --- a/server/src/services/database.service.spec.ts +++ b/server/src/services/database.service.spec.ts @@ -1,5 +1,4 @@ import { PostgresJSDialect } from 'kysely-postgres-js'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { DatabaseExtension, EXTENSION_NAMES, @@ -8,6 +7,7 @@ import { } from 'src/interfaces/database.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface'; import { DatabaseService } from 'src/services/database.service'; +import { IConfigRepository } from 'src/types'; import { mockEnvData } from 'test/repositories/config.repository.mock'; import { newTestService } from 'test/utils'; import { Mocked } from 'vitest'; diff --git a/server/src/services/job.service.spec.ts b/server/src/services/job.service.spec.ts index a23b05073c..5714f7fdd5 100644 --- a/server/src/services/job.service.spec.ts +++ b/server/src/services/job.service.spec.ts @@ -2,11 +2,11 @@ import { BadRequestException } from '@nestjs/common'; import { defaults, SystemConfig } from 'src/config'; import { ImmichWorker } from 'src/enum'; import { IAssetRepository } from 'src/interfaces/asset.interface'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { IJobRepository, JobCommand, JobItem, JobName, JobStatus, QueueName } from 'src/interfaces/job.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface'; import { ITelemetryRepository } from 'src/interfaces/telemetry.interface'; import { JobService } from 'src/services/job.service'; +import { IConfigRepository } from 'src/types'; import { assetStub } from 'test/fixtures/asset.stub'; import { newTestService } from 'test/utils'; import { Mocked } from 'vitest'; diff --git a/server/src/services/library.service.spec.ts b/server/src/services/library.service.spec.ts index a08cb108a5..e2d805b865 100644 --- a/server/src/services/library.service.spec.ts +++ b/server/src/services/library.service.spec.ts @@ -5,7 +5,6 @@ import { mapLibrary } from 'src/dtos/library.dto'; import { UserEntity } from 'src/entities/user.entity'; import { AssetType, ImmichWorker } from 'src/enum'; import { IAssetRepository } from 'src/interfaces/asset.interface'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { ICronRepository } from 'src/interfaces/cron.interface'; import { IDatabaseRepository } from 'src/interfaces/database.interface'; import { @@ -19,6 +18,7 @@ import { import { ILibraryRepository } from 'src/interfaces/library.interface'; import { IStorageRepository } from 'src/interfaces/storage.interface'; import { LibraryService } from 'src/services/library.service'; +import { IConfigRepository } from 'src/types'; import { assetStub } from 'test/fixtures/asset.stub'; import { authStub } from 'test/fixtures/auth.stub'; import { libraryStub } from 'test/fixtures/library.stub'; diff --git a/server/src/services/metadata.service.spec.ts b/server/src/services/metadata.service.spec.ts index 24d2b0e17f..6617ec9e24 100644 --- a/server/src/services/metadata.service.spec.ts +++ b/server/src/services/metadata.service.spec.ts @@ -7,7 +7,6 @@ import { ExifEntity } from 'src/entities/exif.entity'; import { AssetType, ExifOrientation, ImmichWorker, SourceType } from 'src/enum'; import { IAlbumRepository } from 'src/interfaces/album.interface'; import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.interface'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { ICryptoRepository } from 'src/interfaces/crypto.interface'; import { IEventRepository } from 'src/interfaces/event.interface'; import { IJobRepository, JobName, JobStatus } from 'src/interfaces/job.interface'; @@ -20,6 +19,7 @@ import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interf import { ITagRepository } from 'src/interfaces/tag.interface'; import { IUserRepository } from 'src/interfaces/user.interface'; import { MetadataService } from 'src/services/metadata.service'; +import { IConfigRepository } from 'src/types'; import { assetStub } from 'test/fixtures/asset.stub'; import { fileStub } from 'test/fixtures/file.stub'; import { probeStub } from 'test/fixtures/media.stub'; diff --git a/server/src/services/smart-info.service.spec.ts b/server/src/services/smart-info.service.spec.ts index d485f4244b..ff0dcc3160 100644 --- a/server/src/services/smart-info.service.spec.ts +++ b/server/src/services/smart-info.service.spec.ts @@ -1,13 +1,13 @@ import { SystemConfig } from 'src/config'; import { ImmichWorker } from 'src/enum'; import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.interface'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { IDatabaseRepository } from 'src/interfaces/database.interface'; import { IJobRepository, JobName, JobStatus } from 'src/interfaces/job.interface'; import { IMachineLearningRepository } from 'src/interfaces/machine-learning.interface'; import { ISearchRepository } from 'src/interfaces/search.interface'; import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface'; import { SmartInfoService } from 'src/services/smart-info.service'; +import { IConfigRepository } from 'src/types'; import { getCLIPModelInfo } from 'src/utils/misc'; import { assetStub } from 'test/fixtures/asset.stub'; import { systemConfigStub } from 'test/fixtures/system-config.stub'; diff --git a/server/src/services/storage.service.spec.ts b/server/src/services/storage.service.spec.ts index dd97a063ae..7b5b2384e4 100644 --- a/server/src/services/storage.service.spec.ts +++ b/server/src/services/storage.service.spec.ts @@ -1,9 +1,9 @@ import { SystemMetadataKey } from 'src/enum'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface'; import { IStorageRepository } from 'src/interfaces/storage.interface'; import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface'; import { StorageService } from 'src/services/storage.service'; +import { IConfigRepository } from 'src/types'; import { ImmichStartupError } from 'src/utils/misc'; import { mockEnvData } from 'test/repositories/config.repository.mock'; import { newTestService } from 'test/utils'; diff --git a/server/src/services/sync.service.spec.ts b/server/src/services/sync.service.spec.ts index 8dc270d020..3bedd13d8f 100644 --- a/server/src/services/sync.service.spec.ts +++ b/server/src/services/sync.service.spec.ts @@ -1,9 +1,9 @@ import { mapAsset } from 'src/dtos/asset-response.dto'; import { AssetEntity } from 'src/entities/asset.entity'; import { IAssetRepository } from 'src/interfaces/asset.interface'; -import { IAuditRepository } from 'src/interfaces/audit.interface'; import { IPartnerRepository } from 'src/interfaces/partner.interface'; import { SyncService } from 'src/services/sync.service'; +import { IAuditRepository } from 'src/types'; import { assetStub } from 'test/fixtures/asset.stub'; import { authStub } from 'test/fixtures/auth.stub'; import { partnerStub } from 'test/fixtures/partner.stub'; diff --git a/server/src/services/system-config.service.spec.ts b/server/src/services/system-config.service.spec.ts index 2a20f32933..87991fc6c7 100644 --- a/server/src/services/system-config.service.spec.ts +++ b/server/src/services/system-config.service.spec.ts @@ -12,12 +12,12 @@ import { VideoCodec, VideoContainer, } from 'src/enum'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { IEventRepository } from 'src/interfaces/event.interface'; import { QueueName } from 'src/interfaces/job.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface'; import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface'; import { SystemConfigService } from 'src/services/system-config.service'; +import { IConfigRepository } from 'src/types'; import { mockEnvData } from 'test/repositories/config.repository.mock'; import { newTestService } from 'test/utils'; import { DeepPartial } from 'typeorm'; diff --git a/server/src/services/version.service.spec.ts b/server/src/services/version.service.spec.ts index 46f8f620c4..a49f721355 100644 --- a/server/src/services/version.service.spec.ts +++ b/server/src/services/version.service.spec.ts @@ -2,7 +2,6 @@ import { DateTime } from 'luxon'; import { SemVer } from 'semver'; import { serverVersion } from 'src/constants'; import { ImmichEnvironment, SystemMetadataKey } from 'src/enum'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { IEventRepository } from 'src/interfaces/event.interface'; import { IJobRepository, JobName, JobStatus } from 'src/interfaces/job.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface'; @@ -10,6 +9,7 @@ import { IServerInfoRepository } from 'src/interfaces/server-info.interface'; import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface'; import { IVersionHistoryRepository } from 'src/interfaces/version-history.interface'; import { VersionService } from 'src/services/version.service'; +import { IConfigRepository } from 'src/types'; import { mockEnvData } from 'test/repositories/config.repository.mock'; import { newTestService } from 'test/utils'; import { Mocked } from 'vitest'; diff --git a/server/src/types.ts b/server/src/types.ts index dd1fea710f..f6c1ae46dd 100644 --- a/server/src/types.ts +++ b/server/src/types.ts @@ -3,6 +3,8 @@ import { Permission } from 'src/enum'; import { AccessRepository } from 'src/repositories/access.repository'; import { ActivityRepository } from 'src/repositories/activity.repository'; import { ApiKeyRepository } from 'src/repositories/api-key.repository'; +import { AuditRepository } from 'src/repositories/audit.repository'; +import { ConfigRepository } from 'src/repositories/config.repository'; export type AuthApiKey = { id: string; @@ -16,6 +18,8 @@ export type RepositoryInterface = Pick; export type IActivityRepository = RepositoryInterface; export type IAccessRepository = { [K in keyof AccessRepository]: RepositoryInterface }; export type IApiKeyRepository = RepositoryInterface; +export type IAuditRepository = RepositoryInterface; +export type IConfigRepository = RepositoryInterface; export type ActivityItem = | Awaited> diff --git a/server/src/utils/config.ts b/server/src/utils/config.ts index ce8a2da839..645d0fe093 100644 --- a/server/src/utils/config.ts +++ b/server/src/utils/config.ts @@ -6,10 +6,10 @@ import * as _ from 'lodash'; import { SystemConfig, defaults } from 'src/config'; import { SystemConfigDto } from 'src/dtos/system-config.dto'; import { SystemMetadataKey } from 'src/enum'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { DatabaseLock } from 'src/interfaces/database.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface'; import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface'; +import { IConfigRepository } from 'src/types'; import { getKeysDeep, unsetDeep } from 'src/utils/misc'; import { DeepPartial } from 'typeorm'; diff --git a/server/src/workers/api.ts b/server/src/workers/api.ts index efc705deaf..14786497c8 100644 --- a/server/src/workers/api.ts +++ b/server/src/workers/api.ts @@ -7,7 +7,6 @@ import sirv from 'sirv'; import { ApiModule } from 'src/app.module'; import { excludePaths, serverVersion } from 'src/constants'; import { ImmichEnvironment } from 'src/enum'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface'; import { WebSocketAdapter } from 'src/middleware/websocket.adapter'; import { ConfigRepository } from 'src/repositories/config.repository'; @@ -25,7 +24,7 @@ async function bootstrap() { const app = await NestFactory.create(ApiModule, { bufferLogs: true }); const logger = await app.resolve(ILoggerRepository); - const configRepository = app.get(IConfigRepository); + const configRepository = app.get(ConfigRepository); const { environment, host, port, resourcePaths } = configRepository.getEnv(); const isDev = environment === ImmichEnvironment.DEVELOPMENT; diff --git a/server/src/workers/microservices.ts b/server/src/workers/microservices.ts index 0fa056d5d4..34ad41ae26 100644 --- a/server/src/workers/microservices.ts +++ b/server/src/workers/microservices.ts @@ -2,7 +2,6 @@ import { NestFactory } from '@nestjs/core'; import { isMainThread } from 'node:worker_threads'; import { MicroservicesModule } from 'src/app.module'; import { serverVersion } from 'src/constants'; -import { IConfigRepository } from 'src/interfaces/config.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface'; import { WebSocketAdapter } from 'src/middleware/websocket.adapter'; import { ConfigRepository } from 'src/repositories/config.repository'; @@ -23,7 +22,7 @@ export async function bootstrap() { await app.listen(0); - const configRepository = app.get(IConfigRepository); + const configRepository = app.get(ConfigRepository); const { environment } = configRepository.getEnv(); logger.log(`Immich Microservices is running [v${serverVersion}] [${environment}] `); } diff --git a/server/test/repositories/audit.repository.mock.ts b/server/test/repositories/audit.repository.mock.ts index 13af834ce9..96fe407c96 100644 --- a/server/test/repositories/audit.repository.mock.ts +++ b/server/test/repositories/audit.repository.mock.ts @@ -1,4 +1,4 @@ -import { IAuditRepository } from 'src/interfaces/audit.interface'; +import { IAuditRepository } from 'src/types'; import { Mocked, vitest } from 'vitest'; export const newAuditRepositoryMock = (): Mocked => { diff --git a/server/test/repositories/config.repository.mock.ts b/server/test/repositories/config.repository.mock.ts index 00cca308a7..ab8731ea4d 100644 --- a/server/test/repositories/config.repository.mock.ts +++ b/server/test/repositories/config.repository.mock.ts @@ -1,8 +1,9 @@ import { PostgresJSDialect } from 'kysely-postgres-js'; import postgres from 'postgres'; import { ImmichEnvironment, ImmichWorker } from 'src/enum'; -import { EnvData, IConfigRepository } from 'src/interfaces/config.interface'; import { DatabaseExtension } from 'src/interfaces/database.interface'; +import { EnvData } from 'src/repositories/config.repository'; +import { IConfigRepository } from 'src/types'; import { Mocked, vitest } from 'vitest'; const envData: EnvData = { diff --git a/server/test/utils.ts b/server/test/utils.ts index df8ca96c09..363f2fcda7 100644 --- a/server/test/utils.ts +++ b/server/test/utils.ts @@ -6,8 +6,9 @@ import { IMetadataRepository } from 'src/interfaces/metadata.interface'; import { AccessRepository } from 'src/repositories/access.repository'; import { ActivityRepository } from 'src/repositories/activity.repository'; import { ApiKeyRepository } from 'src/repositories/api-key.repository'; +import { AuditRepository } from 'src/repositories/audit.repository'; import { BaseService } from 'src/services/base.service'; -import { IAccessRepository, IActivityRepository, IApiKeyRepository } from 'src/types'; +import { IAccessRepository, IActivityRepository, IApiKeyRepository, IAuditRepository } from 'src/types'; import { newAccessRepositoryMock } from 'test/repositories/access.repository.mock'; import { newActivityRepositoryMock } from 'test/repositories/activity.repository.mock'; import { newAlbumUserRepositoryMock } from 'test/repositories/album-user.repository.mock'; @@ -109,7 +110,7 @@ export const newTestService = ( loggerMock, accessMock as IAccessRepository as AccessRepository, activityMock as IActivityRepository as ActivityRepository, - auditMock, + auditMock as IAuditRepository as AuditRepository, albumMock, albumUserMock, assetMock,