chore(server): move domain interfaces (#8124)

move domain interfaces
This commit is contained in:
Daniel Dietzler
2024-03-20 21:42:58 +01:00
committed by GitHub
parent 2dcce03352
commit 84f7ca855a
150 changed files with 436 additions and 447 deletions

View File

@@ -12,9 +12,9 @@ import {
mapActivity,
} from 'src/domain/activity/activity.dto';
import { AuthDto } from 'src/domain/auth/auth.dto';
import { IAccessRepository } from 'src/domain/repositories/access.repository';
import { IActivityRepository } from 'src/domain/repositories/activity.repository';
import { ActivityEntity } from 'src/infra/entities/activity.entity';
import { IAccessRepository } from 'src/interfaces/access.repository';
import { IActivityRepository } from 'src/interfaces/activity.repository';
@Injectable()
export class ActivityService {

View File

@@ -1,7 +1,7 @@
import { BadRequestException } from '@nestjs/common';
import { ReactionType } from 'src/domain/activity/activity.dto';
import { ActivityService } from 'src/domain/activity/activity.service';
import { IActivityRepository } from 'src/domain/repositories/activity.repository';
import { IActivityRepository } from 'src/interfaces/activity.repository';
import { activityStub } from 'test/fixtures/activity.stub';
import { authStub } from 'test/fixtures/auth.stub';
import { IAccessRepositoryMock, newAccessRepositoryMock } from 'test/repositories/access.repository.mock';

View File

@@ -2,9 +2,9 @@ import { BadRequestException } from '@nestjs/common';
import _ from 'lodash';
import { AlbumService } from 'src/domain/album/album.service';
import { BulkIdErrorReason } from 'src/domain/asset/response-dto/asset-ids-response.dto';
import { IAlbumRepository } from 'src/domain/repositories/album.repository';
import { IAssetRepository } from 'src/domain/repositories/asset.repository';
import { IUserRepository } from 'src/domain/repositories/user.repository';
import { IAlbumRepository } from 'src/interfaces/album.repository';
import { IAssetRepository } from 'src/interfaces/asset.repository';
import { IUserRepository } from 'src/interfaces/user.repository';
import { albumStub } from 'test/fixtures/album.stub';
import { authStub } from 'test/fixtures/auth.stub';
import { userStub } from 'test/fixtures/user.stub';

View File

@@ -14,13 +14,13 @@ import { AlbumInfoDto } from 'src/domain/album/dto/album.dto';
import { GetAlbumsDto } from 'src/domain/album/dto/get-albums.dto';
import { BulkIdErrorReason, BulkIdResponseDto, BulkIdsDto } from 'src/domain/asset/response-dto/asset-ids-response.dto';
import { AuthDto } from 'src/domain/auth/auth.dto';
import { IAccessRepository } from 'src/domain/repositories/access.repository';
import { AlbumAssetCount, AlbumInfoOptions, IAlbumRepository } from 'src/domain/repositories/album.repository';
import { IAssetRepository } from 'src/domain/repositories/asset.repository';
import { IUserRepository } from 'src/domain/repositories/user.repository';
import { AlbumEntity } from 'src/infra/entities/album.entity';
import { AssetEntity } from 'src/infra/entities/asset.entity';
import { UserEntity } from 'src/infra/entities/user.entity';
import { IAccessRepository } from 'src/interfaces/access.repository';
import { AlbumAssetCount, AlbumInfoOptions, IAlbumRepository } from 'src/interfaces/album.repository';
import { IAssetRepository } from 'src/interfaces/asset.repository';
import { IUserRepository } from 'src/interfaces/user.repository';
import { setUnion } from 'src/utils';
@Injectable()

View File

@@ -1,7 +1,7 @@
import { BadRequestException } from '@nestjs/common';
import { APIKeyService } from 'src/domain/api-key/api-key.service';
import { IKeyRepository } from 'src/domain/repositories/api-key.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { IKeyRepository } from 'src/interfaces/api-key.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { keyStub } from 'test/fixtures/api-key.stub';
import { authStub } from 'test/fixtures/auth.stub';
import { newKeyRepositoryMock } from 'test/repositories/api-key.repository.mock';

View File

@@ -1,9 +1,9 @@
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
import { APIKeyCreateDto, APIKeyCreateResponseDto, APIKeyResponseDto } from 'src/domain/api-key/api-key.dto';
import { AuthDto } from 'src/domain/auth/auth.dto';
import { IKeyRepository } from 'src/domain/repositories/api-key.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { APIKeyEntity } from 'src/infra/entities/api-key.entity';
import { IKeyRepository } from 'src/interfaces/api-key.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
@Injectable()
export class APIKeyService {

View File

@@ -5,15 +5,15 @@ import { AssetJobName } from 'src/domain/asset/dto/asset-ids.dto';
import { AssetStatsResponseDto } from 'src/domain/asset/dto/asset-statistics.dto';
import { mapAsset } from 'src/domain/asset/response-dto/asset-response.dto';
import { JobName } from 'src/domain/job/job.constants';
import { IAssetStackRepository } from 'src/domain/repositories/asset-stack.repository';
import { AssetStats, IAssetRepository, TimeBucketSize } from 'src/domain/repositories/asset.repository';
import { ClientEvent, ICommunicationRepository } from 'src/domain/repositories/communication.repository';
import { IJobRepository, JobItem } from 'src/domain/repositories/job.repository';
import { IPartnerRepository } from 'src/domain/repositories/partner.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { IUserRepository } from 'src/domain/repositories/user.repository';
import { AssetEntity, AssetType } from 'src/infra/entities/asset.entity';
import { IAssetStackRepository } from 'src/interfaces/asset-stack.repository';
import { AssetStats, IAssetRepository, TimeBucketSize } from 'src/interfaces/asset.repository';
import { ClientEvent, ICommunicationRepository } from 'src/interfaces/communication.repository';
import { IJobRepository, JobItem } from 'src/interfaces/job.repository';
import { IPartnerRepository } from 'src/interfaces/partner.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { IUserRepository } from 'src/interfaces/user.repository';
import { assetStackStub, assetStub } from 'test/fixtures/asset.stub';
import { authStub } from 'test/fixtures/auth.stub';
import { faceStub } from 'test/fixtures/face.stub';

View File

@@ -25,18 +25,18 @@ import { AuthDto } from 'src/domain/auth/auth.dto';
import { mimeTypes } from 'src/domain/domain.constant';
import { JOBS_ASSET_PAGINATION_SIZE, JobName } from 'src/domain/job/job.constants';
import { IAssetDeletionJob, ISidecarWriteJob } from 'src/domain/job/job.interface';
import { IAccessRepository } from 'src/domain/repositories/access.repository';
import { IAssetStackRepository } from 'src/domain/repositories/asset-stack.repository';
import { IAssetRepository, TimeBucketOptions } from 'src/domain/repositories/asset.repository';
import { ClientEvent, ICommunicationRepository } from 'src/domain/repositories/communication.repository';
import { IJobRepository, JobItem, JobStatus } from 'src/domain/repositories/job.repository';
import { IPartnerRepository } from 'src/domain/repositories/partner.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { IUserRepository } from 'src/domain/repositories/user.repository';
import { AssetEntity } from 'src/infra/entities/asset.entity';
import { LibraryType } from 'src/infra/entities/library.entity';
import { ImmichLogger } from 'src/infra/logger';
import { IAccessRepository } from 'src/interfaces/access.repository';
import { IAssetStackRepository } from 'src/interfaces/asset-stack.repository';
import { IAssetRepository, TimeBucketOptions } from 'src/interfaces/asset.repository';
import { ClientEvent, ICommunicationRepository } from 'src/interfaces/communication.repository';
import { IJobRepository, JobItem, JobStatus } from 'src/interfaces/job.repository';
import { IPartnerRepository } from 'src/interfaces/partner.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { IUserRepository } from 'src/interfaces/user.repository';
import { usePagination } from 'src/utils';
export enum UploadFieldName {

View File

@@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { AssetStats } from 'src/domain/repositories/asset.repository';
import { AssetType } from 'src/infra/entities/asset.entity';
import { AssetStats } from 'src/interfaces/asset.repository';
import { ValidateBoolean } from 'src/validation';
export class AssetStatsDto {

View File

@@ -1,7 +1,7 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
import { TimeBucketSize } from 'src/domain/repositories/asset.repository';
import { AssetOrder } from 'src/infra/entities/album.entity';
import { TimeBucketSize } from 'src/interfaces/asset.repository';
import { Optional, ValidateBoolean, ValidateUUID } from 'src/validation';
export class TimeBucketDto {

View File

@@ -1,12 +1,12 @@
import { AuditService } from 'src/domain/audit/audit.service';
import { IAssetRepository } from 'src/domain/repositories/asset.repository';
import { IAuditRepository } from 'src/domain/repositories/audit.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { JobStatus } from 'src/domain/repositories/job.repository';
import { IPersonRepository } from 'src/domain/repositories/person.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { IUserRepository } from 'src/domain/repositories/user.repository';
import { DatabaseAction, EntityType } from 'src/infra/entities/audit.entity';
import { IAssetRepository } from 'src/interfaces/asset.repository';
import { IAuditRepository } from 'src/interfaces/audit.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { JobStatus } from 'src/interfaces/job.repository';
import { IPersonRepository } from 'src/interfaces/person.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { IUserRepository } from 'src/interfaces/user.repository';
import { auditStub } from 'test/fixtures/audit.stub';
import { authStub } from 'test/fixtures/auth.stub';
import { IAccessRepositoryMock, newAccessRepositoryMock } from 'test/repositories/access.repository.mock';

View File

@@ -14,17 +14,17 @@ import {
import { AuthDto } from 'src/domain/auth/auth.dto';
import { AUDIT_LOG_MAX_DURATION } from 'src/domain/domain.constant';
import { JOBS_ASSET_PAGINATION_SIZE } from 'src/domain/job/job.constants';
import { IAccessRepository } from 'src/domain/repositories/access.repository';
import { IAssetRepository } from 'src/domain/repositories/asset.repository';
import { IAuditRepository } from 'src/domain/repositories/audit.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { JobStatus } from 'src/domain/repositories/job.repository';
import { IPersonRepository } from 'src/domain/repositories/person.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { IUserRepository } from 'src/domain/repositories/user.repository';
import { DatabaseAction } from 'src/infra/entities/audit.entity';
import { AssetPathType, PersonPathType, UserPathType } from 'src/infra/entities/move.entity';
import { ImmichLogger } from 'src/infra/logger';
import { IAccessRepository } from 'src/interfaces/access.repository';
import { IAssetRepository } from 'src/interfaces/asset.repository';
import { IAuditRepository } from 'src/interfaces/audit.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { JobStatus } from 'src/interfaces/job.repository';
import { IPersonRepository } from 'src/interfaces/person.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { IUserRepository } from 'src/interfaces/user.repository';
import { usePagination } from 'src/utils';
@Injectable()

View File

@@ -5,14 +5,14 @@ import { Socket } from 'socket.io';
import { AuthType } from 'src/domain/auth/auth.constant';
import { AuthDto, SignUpDto } from 'src/domain/auth/auth.dto';
import { AuthService } from 'src/domain/auth/auth.service';
import { IKeyRepository } from 'src/domain/repositories/api-key.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { ILibraryRepository } from 'src/domain/repositories/library.repository';
import { ISharedLinkRepository } from 'src/domain/repositories/shared-link.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { IUserTokenRepository } from 'src/domain/repositories/user-token.repository';
import { IUserRepository } from 'src/domain/repositories/user.repository';
import { UserEntity } from 'src/infra/entities/user.entity';
import { IKeyRepository } from 'src/interfaces/api-key.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { ILibraryRepository } from 'src/interfaces/library.repository';
import { ISharedLinkRepository } from 'src/interfaces/shared-link.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { IUserTokenRepository } from 'src/interfaces/user-token.repository';
import { IUserRepository } from 'src/interfaces/user.repository';
import { keyStub } from 'test/fixtures/api-key.stub';
import { authStub, loginResponseStub } from 'test/fixtures/auth.stub';
import { sharedLinkStub } from 'test/fixtures/shared-link.stub';

View File

@@ -36,18 +36,18 @@ import {
mapLoginResponse,
mapUserToken,
} from 'src/domain/auth/auth.dto';
import { IAccessRepository } from 'src/domain/repositories/access.repository';
import { IKeyRepository } from 'src/domain/repositories/api-key.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { ILibraryRepository } from 'src/domain/repositories/library.repository';
import { ISharedLinkRepository } from 'src/domain/repositories/shared-link.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { IUserTokenRepository } from 'src/domain/repositories/user-token.repository';
import { IUserRepository } from 'src/domain/repositories/user.repository';
import { UserResponseDto, mapUser } from 'src/domain/user/response-dto/user-response.dto';
import { SystemConfig } from 'src/infra/entities/system-config.entity';
import { UserEntity } from 'src/infra/entities/user.entity';
import { ImmichLogger } from 'src/infra/logger';
import { IAccessRepository } from 'src/interfaces/access.repository';
import { IKeyRepository } from 'src/interfaces/api-key.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { ILibraryRepository } from 'src/interfaces/library.repository';
import { ISharedLinkRepository } from 'src/interfaces/shared-link.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { IUserTokenRepository } from 'src/interfaces/user-token.repository';
import { IUserRepository } from 'src/interfaces/user.repository';
import { HumanReadableSize } from 'src/utils';
export interface LoginDetails {

View File

@@ -1,7 +1,7 @@
import { DatabaseService } from 'src/domain/database/database.service';
import { Version, VersionType } from 'src/domain/domain.constant';
import { DatabaseExtension, IDatabaseRepository, VectorIndex } from 'src/domain/repositories/database.repository';
import { ImmichLogger } from 'src/infra/logger';
import { DatabaseExtension, IDatabaseRepository, VectorIndex } from 'src/interfaces/database.repository';
import { newDatabaseRepositoryMock } from 'test/repositories/database.repository.mock';
describe(DatabaseService.name, () => {

View File

@@ -1,5 +1,6 @@
import { Inject, Injectable } from '@nestjs/common';
import { Version, VersionType } from 'src/domain/domain.constant';
import { ImmichLogger } from 'src/infra/logger';
import {
DatabaseExtension,
DatabaseLock,
@@ -7,8 +8,7 @@ import {
VectorExtension,
VectorIndex,
extName,
} from 'src/domain/repositories/database.repository';
import { ImmichLogger } from 'src/infra/logger';
} from 'src/interfaces/database.repository';
@Injectable()
export class DatabaseService {

View File

@@ -2,8 +2,8 @@ import { BadRequestException } from '@nestjs/common';
import { when } from 'jest-when';
import { DownloadResponseDto } from 'src/domain/download/download.dto';
import { DownloadService } from 'src/domain/download/download.service';
import { IAssetRepository } from 'src/domain/repositories/asset.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { IAssetRepository } from 'src/interfaces/asset.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { CacheControl, ImmichFileResponse } from 'src/utils';
import { assetStub } from 'test/fixtures/asset.stub';
import { authStub } from 'test/fixtures/auth.stub';

View File

@@ -5,10 +5,10 @@ import { AssetIdsDto } from 'src/domain/asset/dto/asset-ids.dto';
import { AuthDto } from 'src/domain/auth/auth.dto';
import { mimeTypes } from 'src/domain/domain.constant';
import { DownloadArchiveInfo, DownloadInfoDto, DownloadResponseDto } from 'src/domain/download/download.dto';
import { IAccessRepository } from 'src/domain/repositories/access.repository';
import { IAssetRepository } from 'src/domain/repositories/asset.repository';
import { IStorageRepository, ImmichReadStream } from 'src/domain/repositories/storage.repository';
import { AssetEntity } from 'src/infra/entities/asset.entity';
import { IAccessRepository } from 'src/interfaces/access.repository';
import { IAssetRepository } from 'src/interfaces/asset.repository';
import { IStorageRepository, ImmichReadStream } from 'src/interfaces/storage.repository';
import { CacheControl, HumanReadableSize, ImmichFileResponse, usePagination } from 'src/utils';
@Injectable()

View File

@@ -2,12 +2,12 @@ import { BadRequestException } from '@nestjs/common';
import { FeatureFlag, SystemConfigCore } from 'src/cores/system-config.core';
import { JobCommand, JobName, QueueName } from 'src/domain/job/job.constants';
import { JobService } from 'src/domain/job/job.service';
import { IAssetRepository } from 'src/domain/repositories/asset.repository';
import { ICommunicationRepository } from 'src/domain/repositories/communication.repository';
import { IJobRepository, JobHandler, JobItem, JobStatus } from 'src/domain/repositories/job.repository';
import { IPersonRepository } from 'src/domain/repositories/person.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { SystemConfig, SystemConfigKey } from 'src/infra/entities/system-config.entity';
import { IAssetRepository } from 'src/interfaces/asset.repository';
import { ICommunicationRepository } from 'src/interfaces/communication.repository';
import { IJobRepository, JobHandler, JobItem, JobStatus } from 'src/interfaces/job.repository';
import { IPersonRepository } from 'src/interfaces/person.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { assetStub } from 'test/fixtures/asset.stub';
import { newAssetRepositoryMock } from 'test/repositories/asset.repository.mock';
import { newCommunicationRepositoryMock } from 'test/repositories/communication.repository.mock';

View File

@@ -3,13 +3,13 @@ import { FeatureFlag, SystemConfigCore } from 'src/cores/system-config.core';
import { mapAsset } from 'src/domain/asset/response-dto/asset-response.dto';
import { ConcurrentQueueName, JobCommand, JobName, QueueName } from 'src/domain/job/job.constants';
import { AllJobStatusResponseDto, JobCommandDto, JobStatusDto } from 'src/domain/job/job.dto';
import { IAssetRepository } from 'src/domain/repositories/asset.repository';
import { ClientEvent, ICommunicationRepository } from 'src/domain/repositories/communication.repository';
import { IJobRepository, JobHandler, JobItem, JobStatus, QueueCleanType } from 'src/domain/repositories/job.repository';
import { IPersonRepository } from 'src/domain/repositories/person.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { AssetType } from 'src/infra/entities/asset.entity';
import { ImmichLogger } from 'src/infra/logger';
import { IAssetRepository } from 'src/interfaces/asset.repository';
import { ClientEvent, ICommunicationRepository } from 'src/interfaces/communication.repository';
import { IJobRepository, JobHandler, JobItem, JobStatus, QueueCleanType } from 'src/interfaces/job.repository';
import { IPersonRepository } from 'src/interfaces/person.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
@Injectable()
export class JobService {

View File

@@ -7,17 +7,17 @@ import { JobName } from 'src/domain/job/job.constants';
import { ILibraryFileJob, ILibraryRefreshJob } from 'src/domain/job/job.interface';
import { mapLibrary } from 'src/domain/library/library.dto';
import { LibraryService } from 'src/domain/library/library.service';
import { IAssetRepository } from 'src/domain/repositories/asset.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { IDatabaseRepository } from 'src/domain/repositories/database.repository';
import { IJobRepository, JobStatus } from 'src/domain/repositories/job.repository';
import { ILibraryRepository } from 'src/domain/repositories/library.repository';
import { IStorageRepository, StorageEventType } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { AssetType } from 'src/infra/entities/asset.entity';
import { LibraryType } from 'src/infra/entities/library.entity';
import { SystemConfig, SystemConfigKey } from 'src/infra/entities/system-config.entity';
import { UserEntity } from 'src/infra/entities/user.entity';
import { IAssetRepository } from 'src/interfaces/asset.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { IDatabaseRepository } from 'src/interfaces/database.repository';
import { IJobRepository, JobStatus } from 'src/interfaces/job.repository';
import { ILibraryRepository } from 'src/interfaces/library.repository';
import { IStorageRepository, StorageEventType } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { assetStub } from 'test/fixtures/asset.stub';
import { authStub } from 'test/fixtures/auth.stub';
import { libraryStub } from 'test/fixtures/library.stub';

View File

@@ -23,17 +23,17 @@ import {
ValidateLibraryResponseDto,
mapLibrary,
} from 'src/domain/library/library.dto';
import { IAssetRepository, WithProperty } from 'src/domain/repositories/asset.repository';
import { InternalEvent, InternalEventMap } from 'src/domain/repositories/communication.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { DatabaseLock, IDatabaseRepository } from 'src/domain/repositories/database.repository';
import { IJobRepository, JobStatus } from 'src/domain/repositories/job.repository';
import { ILibraryRepository } from 'src/domain/repositories/library.repository';
import { IStorageRepository, StorageEventType } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { AssetType } from 'src/infra/entities/asset.entity';
import { LibraryEntity, LibraryType } from 'src/infra/entities/library.entity';
import { ImmichLogger } from 'src/infra/logger';
import { IAssetRepository, WithProperty } from 'src/interfaces/asset.repository';
import { InternalEvent, InternalEventMap } from 'src/interfaces/communication.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { DatabaseLock, IDatabaseRepository } from 'src/interfaces/database.repository';
import { IJobRepository, JobStatus } from 'src/interfaces/job.repository';
import { ILibraryRepository } from 'src/interfaces/library.repository';
import { IStorageRepository, StorageEventType } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { handlePromiseError, usePagination } from 'src/utils';
import { validateCronExpression } from 'src/validation';

View File

@@ -1,14 +1,6 @@
import { Stats } from 'node:fs';
import { JobName } from 'src/domain/job/job.constants';
import { MediaService } from 'src/domain/media/media.service';
import { IAssetRepository, WithoutProperty } from 'src/domain/repositories/asset.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { IJobRepository, JobStatus } from 'src/domain/repositories/job.repository';
import { IMediaRepository } from 'src/domain/repositories/media.repository';
import { IMoveRepository } from 'src/domain/repositories/move.repository';
import { IPersonRepository } from 'src/domain/repositories/person.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { AssetType } from 'src/infra/entities/asset.entity';
import { ExifEntity } from 'src/infra/entities/exif.entity';
import {
@@ -20,6 +12,14 @@ import {
TranscodePolicy,
VideoCodec,
} from 'src/infra/entities/system-config.entity';
import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { IJobRepository, JobStatus } from 'src/interfaces/job.repository';
import { IMediaRepository } from 'src/interfaces/media.repository';
import { IMoveRepository } from 'src/interfaces/move.repository';
import { IPersonRepository } from 'src/interfaces/person.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { assetStub } from 'test/fixtures/asset.stub';
import { faceStub } from 'test/fixtures/face.stub';
import { probeStub } from 'test/fixtures/media.stub';

View File

@@ -13,19 +13,6 @@ import {
VAAPIConfig,
VP9Config,
} from 'src/domain/media/media.util';
import { IAssetRepository, WithoutProperty } from 'src/domain/repositories/asset.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { IJobRepository, JobItem, JobStatus } from 'src/domain/repositories/job.repository';
import {
AudioStreamInfo,
IMediaRepository,
VideoCodecHWConfig,
VideoStreamInfo,
} from 'src/domain/repositories/media.repository';
import { IMoveRepository } from 'src/domain/repositories/move.repository';
import { IPersonRepository } from 'src/domain/repositories/person.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { SystemConfigFFmpegDto } from 'src/domain/system-config/dto/system-config-ffmpeg.dto';
import { AssetEntity, AssetType } from 'src/infra/entities/asset.entity';
import { AssetPathType } from 'src/infra/entities/move.entity';
@@ -38,6 +25,19 @@ import {
VideoCodec,
} from 'src/infra/entities/system-config.entity';
import { ImmichLogger } from 'src/infra/logger';
import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { IJobRepository, JobItem, JobStatus } from 'src/interfaces/job.repository';
import {
AudioStreamInfo,
IMediaRepository,
VideoCodecHWConfig,
VideoStreamInfo,
} from 'src/interfaces/media.repository';
import { IMoveRepository } from 'src/interfaces/move.repository';
import { IPersonRepository } from 'src/interfaces/person.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { usePagination } from 'src/utils';
@Injectable()

View File

@@ -1,11 +1,3 @@
import {
AudioStreamInfo,
BitrateDistribution,
TranscodeOptions,
VideoCodecHWConfig,
VideoCodecSWConfig,
VideoStreamInfo,
} from 'src/domain/repositories/media.repository';
import { SystemConfigFFmpegDto } from 'src/domain/system-config/dto/system-config-ffmpeg.dto';
import {
CQMode,
@@ -14,6 +6,14 @@ import {
TranscodeTarget,
VideoCodec,
} from 'src/infra/entities/system-config.entity';
import {
AudioStreamInfo,
BitrateDistribution,
TranscodeOptions,
VideoCodecHWConfig,
VideoCodecSWConfig,
VideoStreamInfo,
} from 'src/interfaces/media.repository';
class BaseConfig implements VideoCodecSWConfig {
presets = ['veryslow', 'slower', 'slow', 'medium', 'fast', 'faster', 'veryfast', 'superfast', 'ultrafast'];

View File

@@ -5,21 +5,21 @@ import { Stats } from 'node:fs';
import { constants } from 'node:fs/promises';
import { JobName } from 'src/domain/job/job.constants';
import { MetadataService, Orientation } from 'src/domain/metadata/metadata.service';
import { IAlbumRepository } from 'src/domain/repositories/album.repository';
import { IAssetRepository, WithoutProperty } from 'src/domain/repositories/asset.repository';
import { ClientEvent, ICommunicationRepository } from 'src/domain/repositories/communication.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { IDatabaseRepository } from 'src/domain/repositories/database.repository';
import { IJobRepository, JobStatus } from 'src/domain/repositories/job.repository';
import { IMediaRepository } from 'src/domain/repositories/media.repository';
import { IMetadataRepository, ImmichTags } from 'src/domain/repositories/metadata.repository';
import { IMoveRepository } from 'src/domain/repositories/move.repository';
import { IPersonRepository } from 'src/domain/repositories/person.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { AssetType } from 'src/infra/entities/asset.entity';
import { ExifEntity } from 'src/infra/entities/exif.entity';
import { SystemConfigKey } from 'src/infra/entities/system-config.entity';
import { IAlbumRepository } from 'src/interfaces/album.repository';
import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.repository';
import { ClientEvent, ICommunicationRepository } from 'src/interfaces/communication.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { IDatabaseRepository } from 'src/interfaces/database.repository';
import { IJobRepository, JobStatus } from 'src/interfaces/job.repository';
import { IMediaRepository } from 'src/interfaces/media.repository';
import { IMetadataRepository, ImmichTags } from 'src/interfaces/metadata.repository';
import { IMoveRepository } from 'src/interfaces/move.repository';
import { IPersonRepository } from 'src/interfaces/person.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { assetStub } from 'test/fixtures/asset.stub';
import { fileStub } from 'test/fixtures/file.stub';
import { probeStub } from 'test/fixtures/media.stub';

View File

@@ -10,21 +10,21 @@ import { StorageCore } from 'src/cores/storage.core';
import { FeatureFlag, SystemConfigCore } from 'src/cores/system-config.core';
import { JOBS_ASSET_PAGINATION_SIZE, JobName, QueueName } from 'src/domain/job/job.constants';
import { IBaseJob, IEntityJob, ISidecarWriteJob } from 'src/domain/job/job.interface';
import { IAlbumRepository } from 'src/domain/repositories/album.repository';
import { IAssetRepository, WithoutProperty } from 'src/domain/repositories/asset.repository';
import { ClientEvent, ICommunicationRepository } from 'src/domain/repositories/communication.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { DatabaseLock, IDatabaseRepository } from 'src/domain/repositories/database.repository';
import { IJobRepository, JobStatus } from 'src/domain/repositories/job.repository';
import { IMediaRepository } from 'src/domain/repositories/media.repository';
import { IMetadataRepository, ImmichTags } from 'src/domain/repositories/metadata.repository';
import { IMoveRepository } from 'src/domain/repositories/move.repository';
import { IPersonRepository } from 'src/domain/repositories/person.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { AssetEntity, AssetType } from 'src/infra/entities/asset.entity';
import { ExifEntity } from 'src/infra/entities/exif.entity';
import { ImmichLogger } from 'src/infra/logger';
import { IAlbumRepository } from 'src/interfaces/album.repository';
import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.repository';
import { ClientEvent, ICommunicationRepository } from 'src/interfaces/communication.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { DatabaseLock, IDatabaseRepository } from 'src/interfaces/database.repository';
import { IJobRepository, JobStatus } from 'src/interfaces/job.repository';
import { IMediaRepository } from 'src/interfaces/media.repository';
import { IMetadataRepository, ImmichTags } from 'src/interfaces/metadata.repository';
import { IMoveRepository } from 'src/interfaces/move.repository';
import { IPersonRepository } from 'src/interfaces/person.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { handlePromiseError, usePagination } from 'src/utils';
/** look for a date from these tags (in order) */

View File

@@ -1,9 +1,9 @@
import { BadRequestException } from '@nestjs/common';
import { PartnerResponseDto } from 'src/domain/partner/partner.dto';
import { PartnerService } from 'src/domain/partner/partner.service';
import { IAccessRepository } from 'src/domain/repositories/access.repository';
import { IPartnerRepository, PartnerDirection } from 'src/domain/repositories/partner.repository';
import { UserAvatarColor } from 'src/infra/entities/user.entity';
import { IAccessRepository } from 'src/interfaces/access.repository';
import { IPartnerRepository, PartnerDirection } from 'src/interfaces/partner.repository';
import { authStub } from 'test/fixtures/auth.stub';
import { partnerStub } from 'test/fixtures/partner.stub';
import { newPartnerRepositoryMock } from 'test/repositories/partner.repository.mock';

View File

@@ -2,10 +2,10 @@ import { BadRequestException, Inject, Injectable } from '@nestjs/common';
import { AccessCore, Permission } from 'src/cores/access.core';
import { AuthDto } from 'src/domain/auth/auth.dto';
import { PartnerResponseDto, UpdatePartnerDto } from 'src/domain/partner/partner.dto';
import { IAccessRepository } from 'src/domain/repositories/access.repository';
import { IPartnerRepository, PartnerDirection, PartnerIds } from 'src/domain/repositories/partner.repository';
import { mapUser } from 'src/domain/user/response-dto/user-response.dto';
import { PartnerEntity } from 'src/infra/entities/partner.entity';
import { IAccessRepository } from 'src/interfaces/access.repository';
import { IPartnerRepository, PartnerDirection, PartnerIds } from 'src/interfaces/partner.repository';
@Injectable()
export class PartnerService {

View File

@@ -3,18 +3,18 @@ import { BulkIdErrorReason } from 'src/domain/asset/response-dto/asset-ids-respo
import { JobName } from 'src/domain/job/job.constants';
import { PersonResponseDto, mapFaces, mapPerson } from 'src/domain/person/person.dto';
import { PersonService } from 'src/domain/person/person.service';
import { IAssetRepository, WithoutProperty } from 'src/domain/repositories/asset.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { IJobRepository, JobStatus } from 'src/domain/repositories/job.repository';
import { IMachineLearningRepository } from 'src/domain/repositories/machine-learning.repository';
import { IMediaRepository } from 'src/domain/repositories/media.repository';
import { IMoveRepository } from 'src/domain/repositories/move.repository';
import { IPersonRepository } from 'src/domain/repositories/person.repository';
import { FaceSearchResult, ISearchRepository } from 'src/domain/repositories/search.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { AssetFaceEntity } from 'src/infra/entities/asset-face.entity';
import { Colorspace, SystemConfigKey } from 'src/infra/entities/system-config.entity';
import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { IJobRepository, JobStatus } from 'src/interfaces/job.repository';
import { IMachineLearningRepository } from 'src/interfaces/machine-learning.repository';
import { IMediaRepository } from 'src/interfaces/media.repository';
import { IMoveRepository } from 'src/interfaces/move.repository';
import { IPersonRepository } from 'src/interfaces/person.repository';
import { FaceSearchResult, ISearchRepository } from 'src/interfaces/search.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { CacheControl, ImmichFileResponse } from 'src/utils';
import { assetStub } from 'test/fixtures/asset.stub';
import { authStub } from 'test/fixtures/auth.stub';

View File

@@ -24,20 +24,20 @@ import {
mapFaces,
mapPerson,
} from 'src/domain/person/person.dto';
import { IAccessRepository } from 'src/domain/repositories/access.repository';
import { IAssetRepository, WithoutProperty } from 'src/domain/repositories/asset.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { IJobRepository, JobItem, JobStatus } from 'src/domain/repositories/job.repository';
import { IMachineLearningRepository } from 'src/domain/repositories/machine-learning.repository';
import { CropOptions, IMediaRepository } from 'src/domain/repositories/media.repository';
import { IMoveRepository } from 'src/domain/repositories/move.repository';
import { IPersonRepository, UpdateFacesData } from 'src/domain/repositories/person.repository';
import { ISearchRepository } from 'src/domain/repositories/search.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { PersonPathType } from 'src/infra/entities/move.entity';
import { PersonEntity } from 'src/infra/entities/person.entity';
import { ImmichLogger } from 'src/infra/logger';
import { IAccessRepository } from 'src/interfaces/access.repository';
import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { IJobRepository, JobItem, JobStatus } from 'src/interfaces/job.repository';
import { IMachineLearningRepository } from 'src/interfaces/machine-learning.repository';
import { CropOptions, IMediaRepository } from 'src/interfaces/media.repository';
import { IMoveRepository } from 'src/interfaces/move.repository';
import { IPersonRepository, UpdateFacesData } from 'src/interfaces/person.repository';
import { ISearchRepository } from 'src/interfaces/search.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { CacheControl, ImmichFileResponse, usePagination } from 'src/utils';
import { IsNull } from 'typeorm';

View File

@@ -1,43 +0,0 @@
export const IAccessRepository = 'IAccessRepository';
export interface IAccessRepository {
activity: {
checkOwnerAccess(userId: string, activityIds: Set<string>): Promise<Set<string>>;
checkAlbumOwnerAccess(userId: string, activityIds: Set<string>): Promise<Set<string>>;
checkCreateAccess(userId: string, albumIds: Set<string>): Promise<Set<string>>;
};
asset: {
checkOwnerAccess(userId: string, assetIds: Set<string>): Promise<Set<string>>;
checkAlbumAccess(userId: string, assetIds: Set<string>): Promise<Set<string>>;
checkPartnerAccess(userId: string, assetIds: Set<string>): Promise<Set<string>>;
checkSharedLinkAccess(sharedLinkId: string, assetIds: Set<string>): Promise<Set<string>>;
};
authDevice: {
checkOwnerAccess(userId: string, deviceIds: Set<string>): Promise<Set<string>>;
};
album: {
checkOwnerAccess(userId: string, albumIds: Set<string>): Promise<Set<string>>;
checkSharedAlbumAccess(userId: string, albumIds: Set<string>): Promise<Set<string>>;
checkSharedLinkAccess(sharedLinkId: string, albumIds: Set<string>): Promise<Set<string>>;
};
library: {
checkOwnerAccess(userId: string, libraryIds: Set<string>): Promise<Set<string>>;
};
timeline: {
checkPartnerAccess(userId: string, partnerIds: Set<string>): Promise<Set<string>>;
};
person: {
checkFaceOwnerAccess(userId: string, assetFaceId: Set<string>): Promise<Set<string>>;
checkOwnerAccess(userId: string, personIds: Set<string>): Promise<Set<string>>;
};
partner: {
checkUpdateAccess(userId: string, partnerIds: Set<string>): Promise<Set<string>>;
};
}

View File

@@ -1,11 +0,0 @@
import { ActivityEntity } from 'src/infra/entities/activity.entity';
import { ActivitySearch } from 'src/infra/repositories/activity.repository';
export const IActivityRepository = 'IActivityRepository';
export interface IActivityRepository {
search(options: ActivitySearch): Promise<ActivityEntity[]>;
create(activity: Partial<ActivityEntity>): Promise<ActivityEntity>;
delete(id: string): Promise<void>;
getStatistics(assetId: string | undefined, albumId: string): Promise<number>;
}

View File

@@ -1,48 +0,0 @@
import { AlbumEntity } from 'src/infra/entities/album.entity';
export const IAlbumRepository = 'IAlbumRepository';
export interface AlbumAssetCount {
albumId: string;
assetCount: number;
startDate: Date | undefined;
endDate: Date | undefined;
}
export interface AlbumInfoOptions {
withAssets: boolean;
}
export interface AlbumAsset {
albumId: string;
assetId: string;
}
export interface AlbumAssets {
albumId: string;
assetIds: string[];
}
export interface IAlbumRepository {
getById(id: string, options: AlbumInfoOptions): Promise<AlbumEntity | null>;
getByIds(ids: string[]): Promise<AlbumEntity[]>;
getByAssetId(ownerId: string, assetId: string): Promise<AlbumEntity[]>;
addAssets(assets: AlbumAssets): Promise<void>;
getAssetIds(albumId: string, assetIds?: string[]): Promise<Set<string>>;
hasAsset(asset: AlbumAsset): Promise<boolean>;
removeAsset(assetId: string): Promise<void>;
removeAssets(albumId: string, assetIds: string[]): Promise<void>;
getMetadataForIds(ids: string[]): Promise<AlbumAssetCount[]>;
getInvalidThumbnail(): Promise<string[]>;
getOwned(ownerId: string): Promise<AlbumEntity[]>;
getShared(ownerId: string): Promise<AlbumEntity[]>;
getNotShared(ownerId: string): Promise<AlbumEntity[]>;
restoreAll(userId: string): Promise<void>;
softDeleteAll(userId: string): Promise<void>;
deleteAll(userId: string): Promise<void>;
getAll(): Promise<AlbumEntity[]>;
create(album: Partial<AlbumEntity>): Promise<AlbumEntity>;
update(album: Partial<AlbumEntity>): Promise<AlbumEntity>;
delete(album: AlbumEntity): Promise<void>;
updateThumbnails(): Promise<number | undefined>;
}

View File

@@ -1,16 +0,0 @@
import { APIKeyEntity } from 'src/infra/entities/api-key.entity';
export const IKeyRepository = 'IKeyRepository';
export interface IKeyRepository {
create(dto: Partial<APIKeyEntity>): Promise<APIKeyEntity>;
update(userId: string, id: string, dto: Partial<APIKeyEntity>): Promise<APIKeyEntity>;
delete(userId: string, id: string): Promise<void>;
/**
* Includes the hashed `key` for verification
* @param id
*/
getKey(hashedToken: string): Promise<APIKeyEntity | null>;
getById(userId: string, id: string): Promise<APIKeyEntity | null>;
getByUserId(userId: string): Promise<APIKeyEntity[]>;
}

View File

@@ -1,10 +0,0 @@
import { AssetStackEntity } from 'src/infra/entities/asset-stack.entity';
export const IAssetStackRepository = 'IAssetStackRepository';
export interface IAssetStackRepository {
create(assetStack: Partial<AssetStackEntity>): Promise<AssetStackEntity>;
update(asset: Pick<AssetStackEntity, 'id'> & Partial<AssetStackEntity>): Promise<AssetStackEntity>;
delete(id: string): Promise<void>;
getById(id: string): Promise<AssetStackEntity | null>;
}

View File

@@ -1,179 +0,0 @@
import { ReverseGeocodeResult } from 'src/domain/repositories/metadata.repository';
import { AssetSearchOptions, SearchExploreItem } from 'src/domain/repositories/search.repository';
import { AssetOrder } from 'src/infra/entities/album.entity';
import { AssetJobStatusEntity } from 'src/infra/entities/asset-job-status.entity';
import { AssetEntity, AssetType } from 'src/infra/entities/asset.entity';
import { ExifEntity } from 'src/infra/entities/exif.entity';
import { Paginated, PaginationOptions } from 'src/utils';
import { FindOptionsRelations, FindOptionsSelect } from 'typeorm';
export type AssetStats = Record<AssetType, number>;
export interface AssetStatsOptions {
isFavorite?: boolean;
isArchived?: boolean;
isTrashed?: boolean;
}
export interface LivePhotoSearchOptions {
ownerId: string;
livePhotoCID: string;
otherAssetId: string;
type: AssetType;
}
export interface MapMarkerSearchOptions {
isArchived?: boolean;
isFavorite?: boolean;
fileCreatedBefore?: Date;
fileCreatedAfter?: Date;
}
export interface MapMarker extends ReverseGeocodeResult {
id: string;
lat: number;
lon: number;
}
export enum WithoutProperty {
THUMBNAIL = 'thumbnail',
ENCODED_VIDEO = 'encoded-video',
EXIF = 'exif',
SMART_SEARCH = 'smart-search',
OBJECT_TAGS = 'object-tags',
FACES = 'faces',
PERSON = 'person',
SIDECAR = 'sidecar',
}
export enum WithProperty {
SIDECAR = 'sidecar',
IS_OFFLINE = 'isOffline',
}
export enum TimeBucketSize {
DAY = 'DAY',
MONTH = 'MONTH',
}
export interface AssetBuilderOptions {
isArchived?: boolean;
isFavorite?: boolean;
isTrashed?: boolean;
albumId?: string;
personId?: string;
userIds?: string[];
withStacked?: boolean;
exifInfo?: boolean;
assetType?: AssetType;
}
export interface TimeBucketOptions extends AssetBuilderOptions {
size: TimeBucketSize;
order?: AssetOrder;
}
export interface TimeBucketItem {
timeBucket: string;
count: number;
}
export type AssetCreate = Pick<
AssetEntity,
| 'deviceAssetId'
| 'ownerId'
| 'libraryId'
| 'deviceId'
| 'type'
| 'originalPath'
| 'fileCreatedAt'
| 'localDateTime'
| 'fileModifiedAt'
| 'checksum'
| 'originalFileName'
> &
Partial<AssetEntity>;
export type AssetWithoutRelations = Omit<
AssetEntity,
| 'livePhotoVideo'
| 'stack'
| 'albums'
| 'faces'
| 'owner'
| 'library'
| 'exifInfo'
| 'sharedLinks'
| 'smartInfo'
| 'smartSearch'
| 'tags'
>;
export type AssetUpdateOptions = Pick<AssetWithoutRelations, 'id'> & Partial<AssetWithoutRelations>;
export type AssetUpdateAllOptions = Omit<Partial<AssetWithoutRelations>, 'id'>;
export interface MonthDay {
day: number;
month: number;
}
export interface AssetExploreFieldOptions {
maxFields: number;
minAssetsPerField: number;
}
export interface AssetExploreOptions extends AssetExploreFieldOptions {
relation: keyof AssetEntity;
relatedField: string;
unnest?: boolean;
}
export interface MetadataSearchOptions {
numResults: number;
}
export type AssetPathEntity = Pick<AssetEntity, 'id' | 'originalPath' | 'isOffline'>;
export const IAssetRepository = 'IAssetRepository';
export interface IAssetRepository {
create(asset: AssetCreate): Promise<AssetEntity>;
getByDate(ownerId: string, date: Date): Promise<AssetEntity[]>;
getByIds(
ids: string[],
relations?: FindOptionsRelations<AssetEntity>,
select?: FindOptionsSelect<AssetEntity>,
): Promise<AssetEntity[]>;
getByIdsWithAllRelations(ids: string[]): Promise<AssetEntity[]>;
getByDayOfYear(ownerIds: string[], monthDay: MonthDay): Promise<AssetEntity[]>;
getByChecksum(userId: string, checksum: Buffer): Promise<AssetEntity | null>;
getByAlbumId(pagination: PaginationOptions, albumId: string): Paginated<AssetEntity>;
getByUserId(pagination: PaginationOptions, userId: string, options?: AssetSearchOptions): Paginated<AssetEntity>;
getById(id: string, relations?: FindOptionsRelations<AssetEntity>): Promise<AssetEntity | null>;
getWithout(pagination: PaginationOptions, property: WithoutProperty): Paginated<AssetEntity>;
getWith(pagination: PaginationOptions, property: WithProperty, libraryId?: string): Paginated<AssetEntity>;
getRandom(userId: string, count: number): Promise<AssetEntity[]>;
getFirstAssetForAlbumId(albumId: string): Promise<AssetEntity | null>;
getLastUpdatedAssetForAlbumId(albumId: string): Promise<AssetEntity | null>;
getLibraryAssetPaths(pagination: PaginationOptions, libraryId: string): Paginated<AssetPathEntity>;
getByLibraryIdAndOriginalPath(libraryId: string, originalPath: string): Promise<AssetEntity | null>;
deleteAll(ownerId: string): Promise<void>;
getAll(pagination: PaginationOptions, options?: AssetSearchOptions): Paginated<AssetEntity>;
getAllByDeviceId(userId: string, deviceId: string): Promise<string[]>;
updateAll(ids: string[], options: Partial<AssetUpdateAllOptions>): Promise<void>;
update(asset: AssetUpdateOptions): Promise<void>;
remove(asset: AssetEntity): Promise<void>;
softDeleteAll(ids: string[]): Promise<void>;
restoreAll(ids: string[]): Promise<void>;
findLivePhotoMatch(options: LivePhotoSearchOptions): Promise<AssetEntity | null>;
getMapMarkers(ownerIds: string[], options?: MapMarkerSearchOptions): Promise<MapMarker[]>;
getStatistics(ownerId: string, options: AssetStatsOptions): Promise<AssetStats>;
getTimeBuckets(options: TimeBucketOptions): Promise<TimeBucketItem[]>;
getTimeBucket(timeBucket: string, options: TimeBucketOptions): Promise<AssetEntity[]>;
upsertExif(exif: Partial<ExifEntity>): Promise<void>;
upsertJobStatus(jobStatus: Partial<AssetJobStatusEntity>): Promise<void>;
getAssetIdByCity(userId: string, options: AssetExploreFieldOptions): Promise<SearchExploreItem<string>>;
getAssetIdByTag(userId: string, options: AssetExploreFieldOptions): Promise<SearchExploreItem<string>>;
searchMetadata(query: string, userIds: string[], options: MetadataSearchOptions): Promise<AssetEntity[]>;
}

View File

@@ -1,14 +0,0 @@
import { AuditEntity, DatabaseAction, EntityType } from 'src/infra/entities/audit.entity';
export const IAuditRepository = 'IAuditRepository';
export interface AuditSearch {
action?: DatabaseAction;
entityType?: EntityType;
ownerId?: string;
}
export interface IAuditRepository {
getAfter(since: Date, options: AuditSearch): Promise<AuditEntity[]>;
removeBefore(before: Date): Promise<void>;
}

View File

@@ -1,60 +0,0 @@
import { AssetResponseDto } from 'src/domain/asset/response-dto/asset-response.dto';
import { ReleaseNotification, ServerVersionResponseDto } from 'src/domain/server-info/server-info.dto';
import { SystemConfig } from 'src/infra/entities/system-config.entity';
export const ICommunicationRepository = 'ICommunicationRepository';
export enum ClientEvent {
UPLOAD_SUCCESS = 'on_upload_success',
USER_DELETE = 'on_user_delete',
ASSET_DELETE = 'on_asset_delete',
ASSET_TRASH = 'on_asset_trash',
ASSET_UPDATE = 'on_asset_update',
ASSET_HIDDEN = 'on_asset_hidden',
ASSET_RESTORE = 'on_asset_restore',
ASSET_STACK_UPDATE = 'on_asset_stack_update',
PERSON_THUMBNAIL = 'on_person_thumbnail',
SERVER_VERSION = 'on_server_version',
CONFIG_UPDATE = 'on_config_update',
NEW_RELEASE = 'on_new_release',
}
export enum ServerEvent {
CONFIG_UPDATE = 'config:update',
}
export enum InternalEvent {
VALIDATE_CONFIG = 'validate_config',
}
export interface InternalEventMap {
[InternalEvent.VALIDATE_CONFIG]: { newConfig: SystemConfig; oldConfig: SystemConfig };
}
export interface ClientEventMap {
[ClientEvent.UPLOAD_SUCCESS]: AssetResponseDto;
[ClientEvent.USER_DELETE]: string;
[ClientEvent.ASSET_DELETE]: string;
[ClientEvent.ASSET_TRASH]: string[];
[ClientEvent.ASSET_UPDATE]: AssetResponseDto;
[ClientEvent.ASSET_HIDDEN]: string;
[ClientEvent.ASSET_RESTORE]: string[];
[ClientEvent.ASSET_STACK_UPDATE]: string[];
[ClientEvent.PERSON_THUMBNAIL]: string;
[ClientEvent.SERVER_VERSION]: ServerVersionResponseDto;
[ClientEvent.CONFIG_UPDATE]: Record<string, never>;
[ClientEvent.NEW_RELEASE]: ReleaseNotification;
}
export type OnConnectCallback = (userId: string) => void | Promise<void>;
export type OnServerEventCallback = () => Promise<void>;
export interface ICommunicationRepository {
send<E extends keyof ClientEventMap>(event: E, userId: string, data: ClientEventMap[E]): void;
broadcast<E extends keyof ClientEventMap>(event: E, data: ClientEventMap[E]): void;
on(event: 'connect', callback: OnConnectCallback): void;
on(event: ServerEvent, callback: OnServerEventCallback): void;
sendServerEvent(event: ServerEvent): void;
emit<E extends keyof InternalEventMap>(event: E, data: InternalEventMap[E]): boolean;
emitAsync<E extends keyof InternalEventMap>(event: E, data: InternalEventMap[E]): Promise<any>;
}

View File

@@ -1,11 +0,0 @@
export const ICryptoRepository = 'ICryptoRepository';
export interface ICryptoRepository {
randomBytes(size: number): Buffer;
randomUUID(): string;
hashFile(filePath: string | Buffer): Promise<Buffer>;
hashSha256(data: string): string;
hashSha1(data: string | Buffer): Buffer;
hashBcrypt(data: string | Buffer, saltOrRounds: string | number): Promise<string>;
compareBcrypt(data: string | Buffer, encrypted: string): boolean;
}

View File

@@ -1,53 +0,0 @@
import { Version } from 'src/domain/domain.constant';
export enum DatabaseExtension {
CUBE = 'cube',
EARTH_DISTANCE = 'earthdistance',
VECTOR = 'vector',
VECTORS = 'vectors',
}
export type VectorExtension = DatabaseExtension.VECTOR | DatabaseExtension.VECTORS;
export enum VectorIndex {
CLIP = 'clip_index',
FACE = 'face_index',
}
export enum DatabaseLock {
GeodataImport = 100,
Migrations = 200,
StorageTemplateMigration = 420,
CLIPDimSize = 512,
LibraryWatch = 1337,
}
export const extName: Record<DatabaseExtension, string> = {
cube: 'cube',
earthdistance: 'earthdistance',
vector: 'pgvector',
vectors: 'pgvecto.rs',
} as const;
export interface VectorUpdateResult {
restartRequired: boolean;
}
export const IDatabaseRepository = 'IDatabaseRepository';
export interface IDatabaseRepository {
getExtensionVersion(extensionName: string): Promise<Version | null>;
getAvailableExtensionVersion(extension: DatabaseExtension): Promise<Version | null>;
getPreferredVectorExtension(): VectorExtension;
getPostgresVersion(): Promise<Version>;
createExtension(extension: DatabaseExtension): Promise<void>;
updateExtension(extension: DatabaseExtension, version?: Version): Promise<void>;
updateVectorExtension(extension: VectorExtension, version?: Version): Promise<VectorUpdateResult>;
reindex(index: VectorIndex): Promise<void>;
shouldReindex(name: VectorIndex): Promise<boolean>;
runMigrations(options?: { transaction?: 'all' | 'none' | 'each' }): Promise<void>;
withLock<R>(lock: DatabaseLock, callback: () => Promise<R>): Promise<R>;
tryLock(lock: DatabaseLock): Promise<boolean>;
isBusy(lock: DatabaseLock): boolean;
wait(lock: DatabaseLock): Promise<void>;
}

View File

@@ -1,122 +0,0 @@
import { JobName, QueueName } from 'src/domain/job/job.constants';
import {
IAssetDeletionJob,
IBaseJob,
IDeferrableJob,
IDeleteFilesJob,
IEntityJob,
ILibraryFileJob,
ILibraryRefreshJob,
ISidecarWriteJob,
} from 'src/domain/job/job.interface';
export interface JobCounts {
active: number;
completed: number;
failed: number;
delayed: number;
waiting: number;
paused: number;
}
export interface QueueStatus {
isActive: boolean;
isPaused: boolean;
}
export enum QueueCleanType {
FAILED = 'failed',
}
export type JobItem =
// Transcoding
| { name: JobName.QUEUE_VIDEO_CONVERSION; data: IBaseJob }
| { name: JobName.VIDEO_CONVERSION; data: IEntityJob }
// Thumbnails
| { name: JobName.QUEUE_GENERATE_THUMBNAILS; data: IBaseJob }
| { name: JobName.GENERATE_JPEG_THUMBNAIL; data: IEntityJob }
| { name: JobName.GENERATE_WEBP_THUMBNAIL; data: IEntityJob }
| { name: JobName.GENERATE_THUMBHASH_THUMBNAIL; data: IEntityJob }
// User
| { name: JobName.USER_DELETE_CHECK; data?: IBaseJob }
| { name: JobName.USER_DELETION; data: IEntityJob }
| { name: JobName.USER_SYNC_USAGE; data?: IBaseJob }
// Storage Template
| { name: JobName.STORAGE_TEMPLATE_MIGRATION; data?: IBaseJob }
| { name: JobName.STORAGE_TEMPLATE_MIGRATION_SINGLE; data: IEntityJob }
// Migration
| { name: JobName.QUEUE_MIGRATION; data?: IBaseJob }
| { name: JobName.MIGRATE_ASSET; data?: IEntityJob }
| { name: JobName.MIGRATE_PERSON; data?: IEntityJob }
// Metadata Extraction
| { name: JobName.QUEUE_METADATA_EXTRACTION; data: IBaseJob }
| { name: JobName.METADATA_EXTRACTION; data: IEntityJob }
| { name: JobName.LINK_LIVE_PHOTOS; data: IEntityJob }
// Sidecar Scanning
| { name: JobName.QUEUE_SIDECAR; data: IBaseJob }
| { name: JobName.SIDECAR_DISCOVERY; data: IEntityJob }
| { name: JobName.SIDECAR_SYNC; data: IEntityJob }
| { name: JobName.SIDECAR_WRITE; data: ISidecarWriteJob }
// Facial Recognition
| { name: JobName.QUEUE_FACE_DETECTION; data: IBaseJob }
| { name: JobName.FACE_DETECTION; data: IEntityJob }
| { name: JobName.QUEUE_FACIAL_RECOGNITION; data: IBaseJob }
| { name: JobName.FACIAL_RECOGNITION; data: IDeferrableJob }
| { name: JobName.GENERATE_PERSON_THUMBNAIL; data: IEntityJob }
// Smart Search
| { name: JobName.QUEUE_SMART_SEARCH; data: IBaseJob }
| { name: JobName.SMART_SEARCH; data: IEntityJob }
// Filesystem
| { name: JobName.DELETE_FILES; data: IDeleteFilesJob }
// Audit Log Cleanup
| { name: JobName.CLEAN_OLD_AUDIT_LOGS; data?: IBaseJob }
// Asset Deletion
| { name: JobName.PERSON_CLEANUP; data?: IBaseJob }
| { name: JobName.ASSET_DELETION; data: IAssetDeletionJob }
| { name: JobName.ASSET_DELETION_CHECK; data?: IBaseJob }
// Library Management
| { name: JobName.LIBRARY_SCAN_ASSET; data: ILibraryFileJob }
| { name: JobName.LIBRARY_SCAN; data: ILibraryRefreshJob }
| { name: JobName.LIBRARY_REMOVE_OFFLINE; data: IEntityJob }
| { name: JobName.LIBRARY_DELETE; data: IEntityJob }
| { name: JobName.LIBRARY_QUEUE_SCAN_ALL; data: IBaseJob }
| { name: JobName.LIBRARY_QUEUE_CLEANUP; data: IBaseJob };
export enum JobStatus {
SUCCESS = 'success',
FAILED = 'failed',
SKIPPED = 'skipped',
}
export type JobHandler<T = any> = (data: T) => Promise<JobStatus>;
export type JobItemHandler = (item: JobItem) => Promise<void>;
export const IJobRepository = 'IJobRepository';
export interface IJobRepository {
addHandler(queueName: QueueName, concurrency: number, handler: JobItemHandler): void;
addCronJob(name: string, expression: string, onTick: () => void, start?: boolean): void;
updateCronJob(name: string, expression?: string, start?: boolean): void;
deleteCronJob(name: string): void;
setConcurrency(queueName: QueueName, concurrency: number): void;
queue(item: JobItem): Promise<void>;
queueAll(items: JobItem[]): Promise<void>;
pause(name: QueueName): Promise<void>;
resume(name: QueueName): Promise<void>;
empty(name: QueueName): Promise<void>;
clear(name: QueueName, type: QueueCleanType): Promise<string[]>;
getQueueStatus(name: QueueName): Promise<QueueStatus>;
getJobCounts(name: QueueName): Promise<JobCounts>;
waitForQueueCompletion(...queues: QueueName[]): Promise<void>;
}

View File

@@ -1,19 +0,0 @@
import { LibraryStatsResponseDto } from 'src/domain/library/library.dto';
import { LibraryEntity, LibraryType } from 'src/infra/entities/library.entity';
export const ILibraryRepository = 'ILibraryRepository';
export interface ILibraryRepository {
getCountForUser(ownerId: string): Promise<number>;
getAll(withDeleted?: boolean, type?: LibraryType): Promise<LibraryEntity[]>;
getAllDeleted(): Promise<LibraryEntity[]>;
get(id: string, withDeleted?: boolean): Promise<LibraryEntity | null>;
create(library: Partial<LibraryEntity>): Promise<LibraryEntity>;
delete(id: string): Promise<void>;
softDelete(id: string): Promise<void>;
getDefaultUploadLibrary(ownerId: string): Promise<LibraryEntity | null>;
getUploadLibraryCount(ownerId: string): Promise<number>;
update(library: Partial<LibraryEntity>): Promise<LibraryEntity>;
getStatistics(id: string): Promise<LibraryStatsResponseDto>;
getAssetIds(id: string, withDeleted?: boolean): Promise<string[]>;
}

View File

@@ -1,42 +0,0 @@
import { CLIPConfig, RecognitionConfig } from 'src/domain/smart-info/dto/model-config.dto';
export const IMachineLearningRepository = 'IMachineLearningRepository';
export interface VisionModelInput {
imagePath: string;
}
export interface TextModelInput {
text: string;
}
export interface BoundingBox {
x1: number;
y1: number;
x2: number;
y2: number;
}
export interface DetectFaceResult {
imageWidth: number;
imageHeight: number;
boundingBox: BoundingBox;
score: number;
embedding: number[];
}
export enum ModelType {
FACIAL_RECOGNITION = 'facial-recognition',
CLIP = 'clip',
}
export enum CLIPMode {
VISION = 'vision',
TEXT = 'text',
}
export interface IMachineLearningRepository {
encodeImage(url: string, input: VisionModelInput, config: CLIPConfig): Promise<number[]>;
encodeText(url: string, input: TextModelInput, config: CLIPConfig): Promise<number[]>;
detectFaces(url: string, input: VisionModelInput, config: RecognitionConfig): Promise<DetectFaceResult[]>;
}

View File

@@ -1,80 +0,0 @@
import { Writable } from 'node:stream';
import { TranscodeTarget, VideoCodec } from 'src/infra/entities/system-config.entity';
export const IMediaRepository = 'IMediaRepository';
export interface ResizeOptions {
size: number;
format: 'webp' | 'jpeg';
colorspace: string;
quality: number;
}
export interface VideoStreamInfo {
index: number;
height: number;
width: number;
rotation: number;
codecName?: string;
frameCount: number;
isHDR: boolean;
bitrate: number;
}
export interface AudioStreamInfo {
index: number;
codecName?: string;
frameCount: number;
}
export interface VideoFormat {
formatName?: string;
formatLongName?: string;
duration: number;
bitrate: number;
}
export interface VideoInfo {
format: VideoFormat;
videoStreams: VideoStreamInfo[];
audioStreams: AudioStreamInfo[];
}
export interface CropOptions {
top: number;
left: number;
width: number;
height: number;
}
export interface TranscodeOptions {
inputOptions: string[];
outputOptions: string[];
twoPass: boolean;
}
export interface BitrateDistribution {
max: number;
target: number;
min: number;
unit: string;
}
export interface VideoCodecSWConfig {
getOptions(target: TranscodeTarget, videoStream: VideoStreamInfo, audioStream: AudioStreamInfo): TranscodeOptions;
}
export interface VideoCodecHWConfig extends VideoCodecSWConfig {
getSupportedCodecs(): Array<VideoCodec>;
}
export interface IMediaRepository {
// image
resize(input: string | Buffer, output: string, options: ResizeOptions): Promise<void>;
crop(input: string, options: CropOptions): Promise<Buffer>;
generateThumbhash(imagePath: string): Promise<Buffer>;
// video
probe(input: string): Promise<VideoInfo>;
transcode(input: string, output: string | Writable, options: TranscodeOptions): Promise<void>;
}

View File

@@ -1,47 +0,0 @@
import { BinaryField, Tags } from 'exiftool-vendored';
export const IMetadataRepository = 'IMetadataRepository';
export interface GeoPoint {
latitude: number;
longitude: number;
}
export interface ReverseGeocodeResult {
country: string | null;
state: string | null;
city: string | null;
}
export interface ExifDuration {
Value: number;
Scale?: number;
}
export interface ImmichTags extends Omit<Tags, 'FocalLength' | 'Duration'> {
ContentIdentifier?: string;
MotionPhoto?: number;
MotionPhotoVersion?: number;
MotionPhotoPresentationTimestampUs?: number;
MediaGroupUUID?: string;
ImagePixelDepth?: string;
FocalLength?: number;
Duration?: number | string | ExifDuration;
EmbeddedVideoType?: string;
EmbeddedVideoFile?: BinaryField;
MotionPhotoVideo?: BinaryField;
}
export interface IMetadataRepository {
init(): Promise<void>;
teardown(): Promise<void>;
reverseGeocode(point: GeoPoint): Promise<ReverseGeocodeResult | null>;
readTags(path: string): Promise<ImmichTags | null>;
writeTags(path: string, tags: Partial<Tags>): Promise<void>;
extractBinaryTag(tagName: string, path: string): Promise<Buffer>;
getCountries(userId: string): Promise<string[]>;
getStates(userId: string, country?: string): Promise<string[]>;
getCities(userId: string, country?: string, state?: string): Promise<string[]>;
getCameraMakes(userId: string, model?: string): Promise<string[]>;
getCameraModels(userId: string, make?: string): Promise<string[]>;
}

View File

@@ -1,12 +0,0 @@
import { MoveEntity, PathType } from 'src/infra/entities/move.entity';
export const IMoveRepository = 'IMoveRepository';
export type MoveCreate = Pick<MoveEntity, 'oldPath' | 'newPath' | 'entityId' | 'pathType'> & Partial<MoveEntity>;
export interface IMoveRepository {
create(entity: MoveCreate): Promise<MoveEntity>;
getByEntity(entityId: string, pathType: PathType): Promise<MoveEntity | null>;
update(entity: Partial<MoveEntity>): Promise<MoveEntity>;
delete(move: MoveEntity): Promise<MoveEntity>;
}

View File

@@ -1,21 +0,0 @@
import { PartnerEntity } from 'src/infra/entities/partner.entity';
export interface PartnerIds {
sharedById: string;
sharedWithId: string;
}
export enum PartnerDirection {
SharedBy = 'shared-by',
SharedWith = 'shared-with',
}
export const IPartnerRepository = 'IPartnerRepository';
export interface IPartnerRepository {
getAll(userId: string): Promise<PartnerEntity[]>;
get(partner: PartnerIds): Promise<PartnerEntity | null>;
create(partner: PartnerIds): Promise<PartnerEntity>;
remove(entity: PartnerEntity): Promise<void>;
update(entity: Partial<PartnerEntity>): Promise<PartnerEntity>;
}

View File

@@ -1,67 +0,0 @@
import { AssetFaceEntity } from 'src/infra/entities/asset-face.entity';
import { AssetEntity } from 'src/infra/entities/asset.entity';
import { PersonEntity } from 'src/infra/entities/person.entity';
import { Paginated, PaginationOptions } from 'src/utils';
import { FindManyOptions, FindOptionsRelations, FindOptionsSelect } from 'typeorm';
export const IPersonRepository = 'IPersonRepository';
export interface PersonSearchOptions {
minimumFaceCount: number;
withHidden: boolean;
}
export interface PersonNameSearchOptions {
withHidden?: boolean;
}
export interface AssetFaceId {
assetId: string;
personId: string;
}
export interface UpdateFacesData {
oldPersonId?: string;
faceIds?: string[];
newPersonId: string;
}
export interface PersonStatistics {
assets: number;
}
export interface PeopleStatistics {
total: number;
hidden: number;
}
export interface IPersonRepository {
getAll(pagination: PaginationOptions, options?: FindManyOptions<PersonEntity>): Paginated<PersonEntity>;
getAllForUser(userId: string, options: PersonSearchOptions): Promise<PersonEntity[]>;
getAllWithoutFaces(): Promise<PersonEntity[]>;
getById(personId: string): Promise<PersonEntity | null>;
getByName(userId: string, personName: string, options: PersonNameSearchOptions): Promise<PersonEntity[]>;
getAssets(personId: string): Promise<AssetEntity[]>;
create(entity: Partial<PersonEntity>): Promise<PersonEntity>;
createFaces(entities: Partial<AssetFaceEntity>[]): Promise<string[]>;
delete(entities: PersonEntity[]): Promise<void>;
deleteAll(): Promise<void>;
deleteAllFaces(): Promise<void>;
getAllFaces(pagination: PaginationOptions, options?: FindManyOptions<AssetFaceEntity>): Paginated<AssetFaceEntity>;
getFaceById(id: string): Promise<AssetFaceEntity>;
getFaceByIdWithAssets(
id: string,
relations?: FindOptionsRelations<AssetFaceEntity>,
select?: FindOptionsSelect<AssetFaceEntity>,
): Promise<AssetFaceEntity | null>;
getFaces(assetId: string): Promise<AssetFaceEntity[]>;
getFacesByIds(ids: AssetFaceId[]): Promise<AssetFaceEntity[]>;
getRandomFace(personId: string): Promise<AssetFaceEntity | null>;
getStatistics(personId: string): Promise<PersonStatistics>;
reassignFace(assetFaceId: string, newPersonId: string): Promise<number>;
getNumberOfPeople(userId: string): Promise<PeopleStatistics>;
reassignFaces(data: UpdateFacesData): Promise<number>;
update(entity: Partial<PersonEntity>): Promise<PersonEntity>;
}

View File

@@ -1,195 +0,0 @@
import { AssetFaceEntity } from 'src/infra/entities/asset-face.entity';
import { AssetEntity, AssetType } from 'src/infra/entities/asset.entity';
import { GeodataPlacesEntity } from 'src/infra/entities/geodata-places.entity';
import { SmartInfoEntity } from 'src/infra/entities/smart-info.entity';
import { Paginated } from 'src/utils';
export const ISearchRepository = 'ISearchRepository';
export enum SearchStrategy {
SMART = 'SMART',
TEXT = 'TEXT',
}
export interface SearchFilter {
id?: string;
userId: string;
type?: AssetType;
isFavorite?: boolean;
isArchived?: boolean;
city?: string;
state?: string;
country?: string;
make?: string;
model?: string;
objects?: string[];
tags?: string[];
recent?: boolean;
motion?: boolean;
debug?: boolean;
}
export interface SearchResult<T> {
/** total matches */
total: number;
/** collection size */
count: number;
/** current page */
page: number;
/** items for page */
items: T[];
/** score */
distances: number[];
facets: SearchFacet[];
}
export interface SearchFacet {
fieldName: string;
counts: Array<{
count: number;
value: string;
}>;
}
export type SearchExploreItemSet<T> = Array<{
value: string;
data: T;
}>;
export interface SearchExploreItem<T> {
fieldName: string;
items: SearchExploreItemSet<T>;
}
export type Embedding = number[];
export interface SearchAssetIDOptions {
checksum?: Buffer;
deviceAssetId?: string;
id?: string;
}
export interface SearchUserIdOptions {
deviceId?: string;
libraryId?: string;
userIds?: string[];
}
export type SearchIdOptions = SearchAssetIDOptions & SearchUserIdOptions;
export interface SearchStatusOptions {
isArchived?: boolean;
isEncoded?: boolean;
isExternal?: boolean;
isFavorite?: boolean;
isMotion?: boolean;
isOffline?: boolean;
isReadOnly?: boolean;
isVisible?: boolean;
isNotInAlbum?: boolean;
type?: AssetType;
withArchived?: boolean;
withDeleted?: boolean;
}
export interface SearchOneToOneRelationOptions {
withExif?: boolean;
withSmartInfo?: boolean;
withStacked?: boolean;
}
export interface SearchRelationOptions extends SearchOneToOneRelationOptions {
withFaces?: boolean;
withPeople?: boolean;
}
export interface SearchDateOptions {
createdBefore?: Date;
createdAfter?: Date;
takenBefore?: Date;
takenAfter?: Date;
trashedBefore?: Date;
trashedAfter?: Date;
updatedBefore?: Date;
updatedAfter?: Date;
}
export interface SearchPathOptions {
encodedVideoPath?: string;
originalFileName?: string;
originalPath?: string;
resizePath?: string;
webpPath?: string;
}
export interface SearchExifOptions {
city?: string;
country?: string;
lensModel?: string;
make?: string;
model?: string;
state?: string;
}
export interface SearchEmbeddingOptions {
embedding: Embedding;
userIds: string[];
}
export interface SearchPeopleOptions {
personIds?: string[];
}
export interface SearchOrderOptions {
orderDirection?: 'ASC' | 'DESC';
}
export interface SearchPaginationOptions {
page: number;
size: number;
}
type BaseAssetSearchOptions = SearchDateOptions &
SearchIdOptions &
SearchExifOptions &
SearchOrderOptions &
SearchPathOptions &
SearchStatusOptions &
SearchUserIdOptions &
SearchPeopleOptions;
export type AssetSearchOptions = BaseAssetSearchOptions & SearchRelationOptions;
export type AssetSearchOneToOneRelationOptions = BaseAssetSearchOptions & SearchOneToOneRelationOptions;
export type AssetSearchBuilderOptions = Omit<AssetSearchOptions, 'orderDirection'>;
export type SmartSearchOptions = SearchDateOptions &
SearchEmbeddingOptions &
SearchExifOptions &
SearchOneToOneRelationOptions &
SearchStatusOptions &
SearchUserIdOptions &
SearchPeopleOptions;
export interface FaceEmbeddingSearch extends SearchEmbeddingOptions {
hasPerson?: boolean;
numResults: number;
maxDistance?: number;
}
export interface FaceSearchResult {
distance: number;
face: AssetFaceEntity;
}
export interface ISearchRepository {
init(modelName: string): Promise<void>;
searchMetadata(pagination: SearchPaginationOptions, options: AssetSearchOptions): Paginated<AssetEntity>;
searchSmart(pagination: SearchPaginationOptions, options: SmartSearchOptions): Paginated<AssetEntity>;
searchFaces(search: FaceEmbeddingSearch): Promise<FaceSearchResult[]>;
upsert(smartInfo: Partial<SmartInfoEntity>, embedding?: Embedding): Promise<void>;
searchPlaces(placeName: string): Promise<GeodataPlacesEntity[]>;
getAssetsByCity(userIds: string[]): Promise<AssetEntity[]>;
deleteAllSearchEmbeddings(): Promise<void>;
}

View File

@@ -1,15 +0,0 @@
export interface GitHubRelease {
id: number;
url: string;
tag_name: string;
name: string;
created_at: string;
published_at: string;
body: string;
}
export const IServerInfoRepository = 'IServerInfoRepository';
export interface IServerInfoRepository {
getGitHubRelease(): Promise<GitHubRelease>;
}

View File

@@ -1,12 +0,0 @@
import { SharedLinkEntity } from 'src/infra/entities/shared-link.entity';
export const ISharedLinkRepository = 'ISharedLinkRepository';
export interface ISharedLinkRepository {
getAll(userId: string): Promise<SharedLinkEntity[]>;
get(userId: string, id: string): Promise<SharedLinkEntity | null>;
getByKey(key: Buffer): Promise<SharedLinkEntity | null>;
create(entity: Partial<SharedLinkEntity>): Promise<SharedLinkEntity>;
update(entity: Partial<SharedLinkEntity>): Promise<SharedLinkEntity>;
remove(entity: SharedLinkEntity): Promise<void>;
}

View File

@@ -1,61 +0,0 @@
import { WatchOptions } from 'chokidar';
import { Stats } from 'node:fs';
import { FileReadOptions } from 'node:fs/promises';
import { Readable } from 'node:stream';
import { CrawlOptionsDto } from 'src/domain/library/library.dto';
export interface ImmichReadStream {
stream: Readable;
type?: string;
length?: number;
}
export interface ImmichZipStream extends ImmichReadStream {
addFile: (inputPath: string, filename: string) => void;
finalize: () => Promise<void>;
}
export interface DiskUsage {
available: number;
free: number;
total: number;
}
export const IStorageRepository = 'IStorageRepository';
export interface WatchEvents {
onReady(): void;
onAdd(path: string): void;
onChange(path: string): void;
onUnlink(path: string): void;
onError(error: Error): void;
}
export enum StorageEventType {
READY = 'ready',
ADD = 'add',
CHANGE = 'change',
UNLINK = 'unlink',
ERROR = 'error',
}
export interface IStorageRepository {
createZipStream(): ImmichZipStream;
createReadStream(filepath: string, mimeType?: string | null): Promise<ImmichReadStream>;
readFile(filepath: string, options?: FileReadOptions<Buffer>): Promise<Buffer>;
writeFile(filepath: string, buffer: Buffer): Promise<void>;
unlink(filepath: string): Promise<void>;
unlinkDir(folder: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>;
removeEmptyDirs(folder: string, self?: boolean): Promise<void>;
checkFileExists(filepath: string, mode?: number): Promise<boolean>;
mkdirSync(filepath: string): void;
checkDiskUsage(folder: string): Promise<DiskUsage>;
readdir(folder: string): Promise<string[]>;
stat(filepath: string): Promise<Stats>;
crawl(crawlOptions: CrawlOptionsDto): Promise<string[]>;
walk(crawlOptions: CrawlOptionsDto): AsyncGenerator<string>;
copyFile(source: string, target: string): Promise<void>;
rename(source: string, target: string): Promise<void>;
watch(paths: string[], options: WatchOptions, events: Partial<WatchEvents>): () => Promise<void>;
utimes(filepath: string, atime: Date, mtime: Date): Promise<void>;
}

View File

@@ -1,11 +0,0 @@
import { SystemConfigEntity } from 'src/infra/entities/system-config.entity';
export const ISystemConfigRepository = 'ISystemConfigRepository';
export interface ISystemConfigRepository {
fetchStyle(url: string): Promise<any>;
load(): Promise<SystemConfigEntity[]>;
readFile(filename: string): Promise<string>;
saveAll(items: SystemConfigEntity[]): Promise<SystemConfigEntity[]>;
deleteKeys(keys: string[]): Promise<void>;
}

View File

@@ -1,8 +0,0 @@
import { SystemMetadata } from 'src/infra/entities/system-metadata.entity';
export const ISystemMetadataRepository = 'ISystemMetadataRepository';
export interface ISystemMetadataRepository {
get<T extends keyof SystemMetadata>(key: T): Promise<SystemMetadata[T] | null>;
set<T extends keyof SystemMetadata>(key: T, value: SystemMetadata[T]): Promise<void>;
}

View File

@@ -1,17 +0,0 @@
import { AssetEntity } from 'src/infra/entities/asset.entity';
import { TagEntity } from 'src/infra/entities/tag.entity';
export const ITagRepository = 'ITagRepository';
export interface ITagRepository {
getById(userId: string, tagId: string): Promise<TagEntity | null>;
getAll(userId: string): Promise<TagEntity[]>;
create(tag: Partial<TagEntity>): Promise<TagEntity>;
update(tag: Partial<TagEntity>): Promise<TagEntity>;
remove(tag: TagEntity): Promise<void>;
hasName(userId: string, name: string): Promise<boolean>;
hasAsset(userId: string, tagId: string, assetId: string): Promise<boolean>;
getAssets(userId: string, tagId: string): Promise<AssetEntity[]>;
addAssets(userId: string, tagId: string, assetIds: string[]): Promise<void>;
removeAssets(userId: string, tagId: string, assetIds: string[]): Promise<void>;
}

View File

@@ -1,11 +0,0 @@
import { UserTokenEntity } from 'src/infra/entities/user-token.entity';
export const IUserTokenRepository = 'IUserTokenRepository';
export interface IUserTokenRepository {
create(dto: Partial<UserTokenEntity>): Promise<UserTokenEntity>;
save(dto: Partial<UserTokenEntity>): Promise<UserTokenEntity>;
delete(id: string): Promise<void>;
getByToken(token: string): Promise<UserTokenEntity | null>;
getAll(userId: string): Promise<UserTokenEntity[]>;
}

View File

@@ -1,37 +0,0 @@
import { UserEntity } from 'src/infra/entities/user.entity';
export interface UserListFilter {
withDeleted?: boolean;
}
export interface UserStatsQueryResponse {
userId: string;
userName: string;
photos: number;
videos: number;
usage: number;
quotaSizeInBytes: number | null;
}
export interface UserFindOptions {
withDeleted?: boolean;
}
export const IUserRepository = 'IUserRepository';
export interface IUserRepository {
get(id: string, options: UserFindOptions): Promise<UserEntity | null>;
getAdmin(): Promise<UserEntity | null>;
hasAdmin(): Promise<boolean>;
getByEmail(email: string, withPassword?: boolean): Promise<UserEntity | null>;
getByStorageLabel(storageLabel: string): Promise<UserEntity | null>;
getByOAuthId(oauthId: string): Promise<UserEntity | null>;
getDeletedUsers(): Promise<UserEntity[]>;
getList(filter?: UserListFilter): Promise<UserEntity[]>;
getUserStats(): Promise<UserStatsQueryResponse[]>;
create(user: Partial<UserEntity>): Promise<UserEntity>;
update(id: string, user: Partial<UserEntity>): Promise<UserEntity>;
delete(user: UserEntity, hard?: boolean): Promise<UserEntity>;
updateUsage(id: string, delta: number): Promise<void>;
syncUsage(id?: string): Promise<void>;
}

View File

@@ -1,14 +1,14 @@
import { mapAsset } from 'src/domain/asset/response-dto/asset-response.dto';
import { IAssetRepository } from 'src/domain/repositories/asset.repository';
import { IMachineLearningRepository } from 'src/domain/repositories/machine-learning.repository';
import { IMetadataRepository } from 'src/domain/repositories/metadata.repository';
import { IPartnerRepository } from 'src/domain/repositories/partner.repository';
import { IPersonRepository } from 'src/domain/repositories/person.repository';
import { ISearchRepository } from 'src/domain/repositories/search.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { SearchDto } from 'src/domain/search/dto/search.dto';
import { SearchService } from 'src/domain/search/search.service';
import { SystemConfigKey } from 'src/infra/entities/system-config.entity';
import { IAssetRepository } from 'src/interfaces/asset.repository';
import { IMachineLearningRepository } from 'src/interfaces/machine-learning.repository';
import { IMetadataRepository } from 'src/interfaces/metadata.repository';
import { IPartnerRepository } from 'src/interfaces/partner.repository';
import { IPersonRepository } from 'src/interfaces/person.repository';
import { ISearchRepository } from 'src/interfaces/search.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { assetStub } from 'test/fixtures/asset.stub';
import { authStub } from 'test/fixtures/auth.stub';
import { personStub } from 'test/fixtures/person.stub';

View File

@@ -3,13 +3,6 @@ import { FeatureFlag, SystemConfigCore } from 'src/cores/system-config.core';
import { AssetResponseDto, mapAsset } from 'src/domain/asset/response-dto/asset-response.dto';
import { AuthDto } from 'src/domain/auth/auth.dto';
import { PersonResponseDto } from 'src/domain/person/person.dto';
import { IAssetRepository } from 'src/domain/repositories/asset.repository';
import { IMachineLearningRepository } from 'src/domain/repositories/machine-learning.repository';
import { IMetadataRepository } from 'src/domain/repositories/metadata.repository';
import { IPartnerRepository } from 'src/domain/repositories/partner.repository';
import { IPersonRepository } from 'src/domain/repositories/person.repository';
import { ISearchRepository, SearchExploreItem, SearchStrategy } from 'src/domain/repositories/search.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { SearchSuggestionRequestDto, SearchSuggestionType } from 'src/domain/search/dto/search-suggestion.dto';
import {
MetadataSearchDto,
@@ -23,6 +16,13 @@ import {
import { SearchResponseDto } from 'src/domain/search/response-dto/search-response.dto';
import { AssetOrder } from 'src/infra/entities/album.entity';
import { AssetEntity } from 'src/infra/entities/asset.entity';
import { IAssetRepository } from 'src/interfaces/asset.repository';
import { IMachineLearningRepository } from 'src/interfaces/machine-learning.repository';
import { IMetadataRepository } from 'src/interfaces/metadata.repository';
import { IPartnerRepository } from 'src/interfaces/partner.repository';
import { IPersonRepository } from 'src/interfaces/person.repository';
import { ISearchRepository, SearchExploreItem, SearchStrategy } from 'src/interfaces/search.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
@Injectable()
export class SearchService {

View File

@@ -1,12 +1,12 @@
import { serverVersion } from 'src/domain/domain.constant';
import { ICommunicationRepository } from 'src/domain/repositories/communication.repository';
import { IServerInfoRepository } from 'src/domain/repositories/server-info.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { ISystemMetadataRepository } from 'src/domain/repositories/system-metadata.repository';
import { IUserRepository } from 'src/domain/repositories/user.repository';
import { ServerInfoService } from 'src/domain/server-info/server-info.service';
import { SystemMetadataKey } from 'src/infra/entities/system-metadata.entity';
import { ICommunicationRepository } from 'src/interfaces/communication.repository';
import { IServerInfoRepository } from 'src/interfaces/server-info.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.repository';
import { IUserRepository } from 'src/interfaces/user.repository';
import { newCommunicationRepositoryMock } from 'test/repositories/communication.repository.mock';
import { newStorageRepositoryMock } from 'test/repositories/storage.repository.mock';
import { newSystemConfigRepositoryMock } from 'test/repositories/system-config.repository.mock';

View File

@@ -3,12 +3,6 @@ import { DateTime } from 'luxon';
import { StorageCore, StorageFolder } from 'src/cores/storage.core';
import { SystemConfigCore } from 'src/cores/system-config.core';
import { Version, isDev, mimeTypes, serverVersion } from 'src/domain/domain.constant';
import { ClientEvent, ICommunicationRepository } from 'src/domain/repositories/communication.repository';
import { IServerInfoRepository } from 'src/domain/repositories/server-info.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { ISystemMetadataRepository } from 'src/domain/repositories/system-metadata.repository';
import { IUserRepository, UserStatsQueryResponse } from 'src/domain/repositories/user.repository';
import {
ServerConfigDto,
ServerFeaturesDto,
@@ -20,6 +14,12 @@ import {
} from 'src/domain/server-info/server-info.dto';
import { SystemMetadataKey } from 'src/infra/entities/system-metadata.entity';
import { ImmichLogger } from 'src/infra/logger';
import { ClientEvent, ICommunicationRepository } from 'src/interfaces/communication.repository';
import { IServerInfoRepository } from 'src/interfaces/server-info.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.repository';
import { IUserRepository, UserStatsQueryResponse } from 'src/interfaces/user.repository';
import { asHumanReadable } from 'src/utils';
@Injectable()

View File

@@ -1,10 +1,10 @@
import { BadRequestException, ForbiddenException, UnauthorizedException } from '@nestjs/common';
import _ from 'lodash';
import { AssetIdErrorReason } from 'src/domain/asset/response-dto/asset-ids-response.dto';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { ISharedLinkRepository } from 'src/domain/repositories/shared-link.repository';
import { SharedLinkService } from 'src/domain/shared-link/shared-link.service';
import { SharedLinkType } from 'src/infra/entities/shared-link.entity';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { ISharedLinkRepository } from 'src/interfaces/shared-link.repository';
import { albumStub } from 'test/fixtures/album.stub';
import { assetStub } from 'test/fixtures/asset.stub';
import { authStub } from 'test/fixtures/auth.stub';

View File

@@ -3,9 +3,6 @@ import { AccessCore, Permission } from 'src/cores/access.core';
import { AssetIdsDto } from 'src/domain/asset/dto/asset-ids.dto';
import { AssetIdErrorReason, AssetIdsResponseDto } from 'src/domain/asset/response-dto/asset-ids-response.dto';
import { AuthDto } from 'src/domain/auth/auth.dto';
import { IAccessRepository } from 'src/domain/repositories/access.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { ISharedLinkRepository } from 'src/domain/repositories/shared-link.repository';
import {
SharedLinkResponseDto,
mapSharedLink,
@@ -14,6 +11,9 @@ import {
import { SharedLinkCreateDto, SharedLinkEditDto, SharedLinkPasswordDto } from 'src/domain/shared-link/shared-link.dto';
import { AssetEntity } from 'src/infra/entities/asset.entity';
import { SharedLinkEntity, SharedLinkType } from 'src/infra/entities/shared-link.entity';
import { IAccessRepository } from 'src/interfaces/access.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { ISharedLinkRepository } from 'src/interfaces/shared-link.repository';
import { OpenGraphTags } from 'src/utils';
@Injectable()

View File

@@ -1,7 +1,7 @@
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { IsEnum, IsNotEmpty, IsNumber, IsString, Max, Min } from 'class-validator';
import { CLIPMode, ModelType } from 'src/domain/repositories/machine-learning.repository';
import { CLIPMode, ModelType } from 'src/interfaces/machine-learning.repository';
import { Optional, ValidateBoolean } from 'src/validation';
export class ModelConfig {

View File

@@ -1,14 +1,14 @@
import { JobName } from 'src/domain/job/job.constants';
import { IAssetRepository, WithoutProperty } from 'src/domain/repositories/asset.repository';
import { IDatabaseRepository } from 'src/domain/repositories/database.repository';
import { IJobRepository } from 'src/domain/repositories/job.repository';
import { IMachineLearningRepository } from 'src/domain/repositories/machine-learning.repository';
import { ISearchRepository } from 'src/domain/repositories/search.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { cleanModelName, getCLIPModelInfo } from 'src/domain/smart-info/smart-info.constant';
import { SmartInfoService } from 'src/domain/smart-info/smart-info.service';
import { AssetEntity } from 'src/infra/entities/asset.entity';
import { SystemConfigKey } from 'src/infra/entities/system-config.entity';
import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.repository';
import { IDatabaseRepository } from 'src/interfaces/database.repository';
import { IJobRepository } from 'src/interfaces/job.repository';
import { IMachineLearningRepository } from 'src/interfaces/machine-learning.repository';
import { ISearchRepository } from 'src/interfaces/search.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { assetStub } from 'test/fixtures/asset.stub';
import { newAssetRepositoryMock } from 'test/repositories/asset.repository.mock';
import { newDatabaseRepositoryMock } from 'test/repositories/database.repository.mock';

View File

@@ -2,13 +2,13 @@ import { Inject, Injectable } from '@nestjs/common';
import { SystemConfigCore } from 'src/cores/system-config.core';
import { JOBS_ASSET_PAGINATION_SIZE, JobName, QueueName } from 'src/domain/job/job.constants';
import { IBaseJob, IEntityJob } from 'src/domain/job/job.interface';
import { IAssetRepository, WithoutProperty } from 'src/domain/repositories/asset.repository';
import { DatabaseLock, IDatabaseRepository } from 'src/domain/repositories/database.repository';
import { IJobRepository, JobStatus } from 'src/domain/repositories/job.repository';
import { IMachineLearningRepository } from 'src/domain/repositories/machine-learning.repository';
import { ISearchRepository } from 'src/domain/repositories/search.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { ImmichLogger } from 'src/infra/logger';
import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.repository';
import { DatabaseLock, IDatabaseRepository } from 'src/interfaces/database.repository';
import { IJobRepository, JobStatus } from 'src/interfaces/job.repository';
import { IMachineLearningRepository } from 'src/interfaces/machine-learning.repository';
import { ISearchRepository } from 'src/interfaces/search.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { usePagination } from 'src/utils';
@Injectable()

View File

@@ -1,19 +1,19 @@
import { when } from 'jest-when';
import { Stats } from 'node:fs';
import { SystemConfigCore, defaults } from 'src/cores/system-config.core';
import { IAlbumRepository } from 'src/domain/repositories/album.repository';
import { IAssetRepository } from 'src/domain/repositories/asset.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { IDatabaseRepository } from 'src/domain/repositories/database.repository';
import { JobStatus } from 'src/domain/repositories/job.repository';
import { IMoveRepository } from 'src/domain/repositories/move.repository';
import { IPersonRepository } from 'src/domain/repositories/person.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { IUserRepository } from 'src/domain/repositories/user.repository';
import { StorageTemplateService } from 'src/domain/storage-template/storage-template.service';
import { AssetPathType } from 'src/infra/entities/move.entity';
import { SystemConfig, SystemConfigKey } from 'src/infra/entities/system-config.entity';
import { IAlbumRepository } from 'src/interfaces/album.repository';
import { IAssetRepository } from 'src/interfaces/asset.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { IDatabaseRepository } from 'src/interfaces/database.repository';
import { JobStatus } from 'src/interfaces/job.repository';
import { IMoveRepository } from 'src/interfaces/move.repository';
import { IPersonRepository } from 'src/interfaces/person.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { IUserRepository } from 'src/interfaces/user.repository';
import { assetStub } from 'test/fixtures/asset.stub';
import { userStub } from 'test/fixtures/user.stub';
import { newAlbumRepositoryMock } from 'test/repositories/album.repository.mock';

View File

@@ -8,17 +8,6 @@ import { StorageCore, StorageFolder } from 'src/cores/storage.core';
import { SystemConfigCore } from 'src/cores/system-config.core';
import { JOBS_ASSET_PAGINATION_SIZE } from 'src/domain/job/job.constants';
import { IEntityJob } from 'src/domain/job/job.interface';
import { IAlbumRepository } from 'src/domain/repositories/album.repository';
import { IAssetRepository } from 'src/domain/repositories/asset.repository';
import { InternalEvent, InternalEventMap } from 'src/domain/repositories/communication.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { DatabaseLock, IDatabaseRepository } from 'src/domain/repositories/database.repository';
import { JobStatus } from 'src/domain/repositories/job.repository';
import { IMoveRepository } from 'src/domain/repositories/move.repository';
import { IPersonRepository } from 'src/domain/repositories/person.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { IUserRepository } from 'src/domain/repositories/user.repository';
import {
supportedDayTokens,
supportedHourTokens,
@@ -32,6 +21,17 @@ import { AssetEntity, AssetType } from 'src/infra/entities/asset.entity';
import { AssetPathType } from 'src/infra/entities/move.entity';
import { SystemConfig } from 'src/infra/entities/system-config.entity';
import { ImmichLogger } from 'src/infra/logger';
import { IAlbumRepository } from 'src/interfaces/album.repository';
import { IAssetRepository } from 'src/interfaces/asset.repository';
import { InternalEvent, InternalEventMap } from 'src/interfaces/communication.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { DatabaseLock, IDatabaseRepository } from 'src/interfaces/database.repository';
import { JobStatus } from 'src/interfaces/job.repository';
import { IMoveRepository } from 'src/interfaces/move.repository';
import { IPersonRepository } from 'src/interfaces/person.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { IUserRepository } from 'src/interfaces/user.repository';
import { getLivePhotoMotionFilename, usePagination } from 'src/utils';
export interface MoveAssetMetadata {

View File

@@ -1,5 +1,5 @@
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { StorageService } from 'src/domain/storage/storage.service';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { newStorageRepositoryMock } from 'test/repositories/storage.repository.mock';
describe(StorageService.name, () => {

View File

@@ -1,9 +1,9 @@
import { Inject, Injectable } from '@nestjs/common';
import { StorageCore, StorageFolder } from 'src/cores/storage.core';
import { IDeleteFilesJob } from 'src/domain/job/job.interface';
import { JobStatus } from 'src/domain/repositories/job.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { ImmichLogger } from 'src/infra/logger';
import { JobStatus } from 'src/interfaces/job.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
@Injectable()
export class StorageService {

View File

@@ -1,9 +1,6 @@
import { BadRequestException } from '@nestjs/common';
import { defaults } from 'src/cores/system-config.core';
import { QueueName } from 'src/domain/job/job.constants';
import { ICommunicationRepository, ServerEvent } from 'src/domain/repositories/communication.repository';
import { ISearchRepository } from 'src/domain/repositories/search.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { SystemConfigService } from 'src/domain/system-config/system-config.service';
import {
AudioCodec,
@@ -19,6 +16,9 @@ import {
VideoCodec,
} from 'src/infra/entities/system-config.entity';
import { ImmichLogger } from 'src/infra/logger';
import { ICommunicationRepository, ServerEvent } from 'src/interfaces/communication.repository';
import { ISearchRepository } from 'src/interfaces/search.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { newCommunicationRepositoryMock } from 'test/repositories/communication.repository.mock';
import { newSystemConfigRepositoryMock } from 'test/repositories/system-config.repository.mock';

View File

@@ -3,15 +3,6 @@ import { OnEvent } from '@nestjs/event-emitter';
import { instanceToPlain } from 'class-transformer';
import _ from 'lodash';
import { SystemConfigCore } from 'src/cores/system-config.core';
import {
ClientEvent,
ICommunicationRepository,
InternalEvent,
InternalEventMap,
ServerEvent,
} from 'src/domain/repositories/communication.repository';
import { ISearchRepository } from 'src/domain/repositories/search.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { SystemConfigDto, mapConfig } from 'src/domain/system-config/dto/system-config.dto';
import { SystemConfigTemplateStorageOptionDto } from 'src/domain/system-config/response-dto/system-config-template-storage-option.dto';
import {
@@ -26,6 +17,15 @@ import {
} from 'src/domain/system-config/system-config.constants';
import { LogLevel, SystemConfig } from 'src/infra/entities/system-config.entity';
import { ImmichLogger } from 'src/infra/logger';
import {
ClientEvent,
ICommunicationRepository,
InternalEvent,
InternalEventMap,
ServerEvent,
} from 'src/interfaces/communication.repository';
import { ISearchRepository } from 'src/interfaces/search.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
@Injectable()
export class SystemConfigService {

View File

@@ -1,9 +1,9 @@
import { BadRequestException } from '@nestjs/common';
import { when } from 'jest-when';
import { AssetIdErrorReason } from 'src/domain/asset/response-dto/asset-ids-response.dto';
import { ITagRepository } from 'src/domain/repositories/tag.repository';
import { TagService } from 'src/domain/tag/tag.service';
import { TagType } from 'src/infra/entities/tag.entity';
import { ITagRepository } from 'src/interfaces/tag.repository';
import { assetStub } from 'test/fixtures/asset.stub';
import { authStub } from 'test/fixtures/auth.stub';
import { tagResponseStub, tagStub } from 'test/fixtures/tag.stub';

View File

@@ -3,9 +3,9 @@ import { AssetIdsDto } from 'src/domain/asset/dto/asset-ids.dto';
import { AssetIdErrorReason, AssetIdsResponseDto } from 'src/domain/asset/response-dto/asset-ids-response.dto';
import { AssetResponseDto, mapAsset } from 'src/domain/asset/response-dto/asset-response.dto';
import { AuthDto } from 'src/domain/auth/auth.dto';
import { ITagRepository } from 'src/domain/repositories/tag.repository';
import { TagResponseDto, mapTag } from 'src/domain/tag/tag-response.dto';
import { CreateTagDto, UpdateTagDto } from 'src/domain/tag/tag.dto';
import { ITagRepository } from 'src/interfaces/tag.repository';
@Injectable()
export class TagService {

View File

@@ -1,9 +1,9 @@
import { BadRequestException } from '@nestjs/common';
import { JobName } from 'src/domain/job/job.constants';
import { IAssetRepository } from 'src/domain/repositories/asset.repository';
import { ClientEvent, ICommunicationRepository } from 'src/domain/repositories/communication.repository';
import { IJobRepository } from 'src/domain/repositories/job.repository';
import { TrashService } from 'src/domain/trash/trash.service';
import { IAssetRepository } from 'src/interfaces/asset.repository';
import { ClientEvent, ICommunicationRepository } from 'src/interfaces/communication.repository';
import { IJobRepository } from 'src/interfaces/job.repository';
import { assetStub } from 'test/fixtures/asset.stub';
import { authStub } from 'test/fixtures/auth.stub';
import { IAccessRepositoryMock, newAccessRepositoryMock } from 'test/repositories/access.repository.mock';

View File

@@ -4,10 +4,10 @@ import { AccessCore, Permission } from 'src/cores/access.core';
import { BulkIdsDto } from 'src/domain/asset/response-dto/asset-ids-response.dto';
import { AuthDto } from 'src/domain/auth/auth.dto';
import { JOBS_ASSET_PAGINATION_SIZE, JobName } from 'src/domain/job/job.constants';
import { IAccessRepository } from 'src/domain/repositories/access.repository';
import { IAssetRepository } from 'src/domain/repositories/asset.repository';
import { ClientEvent, ICommunicationRepository } from 'src/domain/repositories/communication.repository';
import { IJobRepository } from 'src/domain/repositories/job.repository';
import { IAccessRepository } from 'src/interfaces/access.repository';
import { IAssetRepository } from 'src/interfaces/asset.repository';
import { ClientEvent, ICommunicationRepository } from 'src/interfaces/communication.repository';
import { IJobRepository } from 'src/interfaces/job.repository';
import { usePagination } from 'src/utils';
export class TrashService {

View File

@@ -6,17 +6,17 @@ import {
} from '@nestjs/common';
import { when } from 'jest-when';
import { JobName } from 'src/domain/job/job.constants';
import { IAlbumRepository } from 'src/domain/repositories/album.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { IJobRepository } from 'src/domain/repositories/job.repository';
import { ILibraryRepository } from 'src/domain/repositories/library.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { IUserRepository } from 'src/domain/repositories/user.repository';
import { UpdateUserDto } from 'src/domain/user/dto/update-user.dto';
import { mapUser } from 'src/domain/user/response-dto/user-response.dto';
import { UserService } from 'src/domain/user/user.service';
import { UserEntity, UserStatus } from 'src/infra/entities/user.entity';
import { IAlbumRepository } from 'src/interfaces/album.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { IJobRepository } from 'src/interfaces/job.repository';
import { ILibraryRepository } from 'src/interfaces/library.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { IUserRepository } from 'src/interfaces/user.repository';
import { CacheControl, ImmichFileResponse } from 'src/utils';
import { authStub } from 'test/fixtures/auth.stub';
import { systemConfigStub } from 'test/fixtures/system-config.stub';

View File

@@ -7,13 +7,6 @@ import { UserCore } from 'src/cores/user.core';
import { AuthDto } from 'src/domain/auth/auth.dto';
import { JobName } from 'src/domain/job/job.constants';
import { IEntityJob } from 'src/domain/job/job.interface';
import { IAlbumRepository } from 'src/domain/repositories/album.repository';
import { ICryptoRepository } from 'src/domain/repositories/crypto.repository';
import { IJobRepository, JobStatus } from 'src/domain/repositories/job.repository';
import { ILibraryRepository } from 'src/domain/repositories/library.repository';
import { IStorageRepository } from 'src/domain/repositories/storage.repository';
import { ISystemConfigRepository } from 'src/domain/repositories/system-config.repository';
import { IUserRepository, UserFindOptions } from 'src/domain/repositories/user.repository';
import { CreateUserDto } from 'src/domain/user/dto/create-user.dto';
import { DeleteUserDto } from 'src/domain/user/dto/delete-user.dto';
import { UpdateUserDto } from 'src/domain/user/dto/update-user.dto';
@@ -24,6 +17,13 @@ import {
import { UserResponseDto, mapUser } from 'src/domain/user/response-dto/user-response.dto';
import { UserEntity, UserStatus } from 'src/infra/entities/user.entity';
import { ImmichLogger } from 'src/infra/logger';
import { IAlbumRepository } from 'src/interfaces/album.repository';
import { ICryptoRepository } from 'src/interfaces/crypto.repository';
import { IJobRepository, JobStatus } from 'src/interfaces/job.repository';
import { ILibraryRepository } from 'src/interfaces/library.repository';
import { IStorageRepository } from 'src/interfaces/storage.repository';
import { ISystemConfigRepository } from 'src/interfaces/system-config.repository';
import { IUserRepository, UserFindOptions } from 'src/interfaces/user.repository';
import { CacheControl, ImmichFileResponse } from 'src/utils';
@Injectable()