mirror of
https://github.com/immich-app/immich.git
synced 2026-03-01 18:19:10 +03:00
refactor: config repository (#15495)
* refactor: access repository * refactor: config repository
This commit is contained in:
@@ -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<DB>) {}
|
||||
|
||||
@GenerateSql({
|
||||
|
||||
@@ -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<ImmichTelemetry>;
|
||||
};
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -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<DB>,
|
||||
@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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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,
|
||||
) {
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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<MapDB>,
|
||||
|
||||
@@ -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<string> => {
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user