diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d196d1c7e7..66b0a94da1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,8 +18,8 @@ jobs: - name: Run Immich Server 2E2 Test run: docker-compose -f ./docker/docker-compose.test.yml --env-file ./docker/.env.test up --abort-on-container-exit --exit-code-from immich-server-test - unit-tests: - name: Run unit test suites + server-unit-tests: + name: Run server unit test suites and checks runs-on: ubuntu-latest steps: @@ -27,4 +27,4 @@ jobs: uses: actions/checkout@v3 - name: Run tests - run: cd server && npm install && npm run test + run: cd server && npm ci && npm run check:all diff --git a/server/apps/immich/src/api-v1/album/album-repository.ts b/server/apps/immich/src/api-v1/album/album-repository.ts index 42f2cf5702..5b8aaad0c1 100644 --- a/server/apps/immich/src/api-v1/album/album-repository.ts +++ b/server/apps/immich/src/api-v1/album/album-repository.ts @@ -11,7 +11,6 @@ import { GetAlbumsDto } from './dto/get-albums.dto'; import { RemoveAssetsDto } from './dto/remove-assets.dto'; import { UpdateAlbumDto } from './dto/update-album.dto'; import { AlbumCountResponseDto } from './response-dto/album-count-response.dto'; -import { AlbumResponseDto } from './response-dto/album-response.dto'; export interface IAlbumRepository { create(ownerId: string, createAlbumDto: CreateAlbumDto): Promise; @@ -165,7 +164,7 @@ export class AlbumRepository implements IAlbumRepository { } async getListByAssetId(userId: string, assetId: string): Promise { - let query = this.albumRepository.createQueryBuilder('album'); + const query = this.albumRepository.createQueryBuilder('album'); const albums = await query .where('album.ownerId = :ownerId', { ownerId: userId }) @@ -190,7 +189,7 @@ export class AlbumRepository implements IAlbumRepository { } async get(albumId: string): Promise { - let query = this.albumRepository.createQueryBuilder('album'); + const query = this.albumRepository.createQueryBuilder('album'); const album = await query .where('album.id = :albumId', { albumId }) diff --git a/server/apps/immich/src/api-v1/album/album.controller.ts b/server/apps/immich/src/api-v1/album/album.controller.ts index 0b923fa62d..c58fa97f11 100644 --- a/server/apps/immich/src/api-v1/album/album.controller.ts +++ b/server/apps/immich/src/api-v1/album/album.controller.ts @@ -11,7 +11,6 @@ import { ParseUUIDPipe, Put, Query, - Header, } from '@nestjs/common'; import { ParseMeUUIDPipe } from '../validation/parse-me-uuid-pipe'; import { AlbumService } from './album.service'; diff --git a/server/apps/immich/src/api-v1/album/album.service.spec.ts b/server/apps/immich/src/api-v1/album/album.service.spec.ts index 34e9bd4f08..46c7d20ef9 100644 --- a/server/apps/immich/src/api-v1/album/album.service.spec.ts +++ b/server/apps/immich/src/api-v1/album/album.service.spec.ts @@ -4,7 +4,6 @@ import { AuthUserDto } from '../../decorators/auth-user.decorator'; import { BadRequestException, NotFoundException, ForbiddenException } from '@nestjs/common'; import { AlbumEntity } from '@app/database/entities/album.entity'; import { AlbumResponseDto } from './response-dto/album-response.dto'; -import { AssetAlbumEntity } from '@app/database/entities/asset-album.entity'; describe('Album service', () => { let sut: AlbumService; diff --git a/server/apps/immich/src/api-v1/album/dto/update-album.dto.ts b/server/apps/immich/src/api-v1/album/dto/update-album.dto.ts index d71438a51d..44b0764d51 100644 --- a/server/apps/immich/src/api-v1/album/dto/update-album.dto.ts +++ b/server/apps/immich/src/api-v1/album/dto/update-album.dto.ts @@ -1,4 +1,4 @@ -import { IsNotEmpty, IsOptional } from 'class-validator'; +import { IsOptional } from 'class-validator'; export class UpdateAlbumDto { @IsOptional() diff --git a/server/apps/immich/src/api-v1/asset/asset.controller.ts b/server/apps/immich/src/api-v1/asset/asset.controller.ts index 7707e73aaa..7e7a4d1853 100644 --- a/server/apps/immich/src/api-v1/asset/asset.controller.ts +++ b/server/apps/immich/src/api-v1/asset/asset.controller.ts @@ -15,7 +15,6 @@ import { HttpCode, BadRequestException, UploadedFile, - Header, } from '@nestjs/common'; import { JwtAuthGuard } from '../../modules/immich-jwt/guards/jwt-auth.guard'; import { AssetService } from './asset.service'; @@ -34,7 +33,7 @@ import { IAssetUploadedJob } from '@app/job/index'; import { assetUploadedQueueName } from '@app/job/constants/queue-name.constant'; import { assetUploadedProcessorName } from '@app/job/constants/job-name.constant'; import { CheckDuplicateAssetDto } from './dto/check-duplicate-asset.dto'; -import { ApiBearerAuth, ApiBody, ApiConsumes, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { ApiBearerAuth, ApiBody, ApiConsumes, ApiTags } from '@nestjs/swagger'; import { CuratedObjectsResponseDto } from './response-dto/curated-objects-response.dto'; import { CuratedLocationsResponseDto } from './response-dto/curated-locations-response.dto'; import { AssetResponseDto } from './response-dto/asset-response.dto'; diff --git a/server/apps/immich/src/api-v1/asset/asset.service.spec.ts b/server/apps/immich/src/api-v1/asset/asset.service.spec.ts index 2fccf7f5ab..487b6e6369 100644 --- a/server/apps/immich/src/api-v1/asset/asset.service.spec.ts +++ b/server/apps/immich/src/api-v1/asset/asset.service.spec.ts @@ -1,9 +1,8 @@ -import { AssetRepository, IAssetRepository } from './asset-repository'; +import { IAssetRepository } from './asset-repository'; import { AuthUserDto } from '../../decorators/auth-user.decorator'; import { AssetService } from './asset.service'; import { Repository } from 'typeorm'; -import { AssetEntity, AssetType } from '@app/database/entities/asset.entity'; -import { CreateAssetDto } from './dto/create-asset.dto'; +import { AssetEntity } from '@app/database/entities/asset.entity'; describe('AssetService', () => { let sui: AssetService; @@ -15,39 +14,39 @@ describe('AssetService', () => { email: 'auth@test.com', }); - const _getCreateAssetDto = (): CreateAssetDto => { - const createAssetDto = new CreateAssetDto(); - createAssetDto.deviceAssetId = 'deviceAssetId'; - createAssetDto.deviceId = 'deviceId'; - createAssetDto.assetType = AssetType.OTHER; - createAssetDto.createdAt = '2022-06-19T23:41:36.910Z'; - createAssetDto.modifiedAt = '2022-06-19T23:41:36.910Z'; - createAssetDto.isFavorite = false; - createAssetDto.duration = '0:00:00.000000'; + // const _getCreateAssetDto = (): CreateAssetDto => { + // const createAssetDto = new CreateAssetDto(); + // createAssetDto.deviceAssetId = 'deviceAssetId'; + // createAssetDto.deviceId = 'deviceId'; + // createAssetDto.assetType = AssetType.OTHER; + // createAssetDto.createdAt = '2022-06-19T23:41:36.910Z'; + // createAssetDto.modifiedAt = '2022-06-19T23:41:36.910Z'; + // createAssetDto.isFavorite = false; + // createAssetDto.duration = '0:00:00.000000'; - return createAssetDto; - }; - const _getAsset = () => { - const assetEntity = new AssetEntity(); + // return createAssetDto; + // }; + // const _getAsset = () => { + // const assetEntity = new AssetEntity(); - assetEntity.id = 'e8edabfd-7d8a-45d0-9d61-7c7ca60f2c67'; - assetEntity.userId = '3ea54709-e168-42b7-90b0-a0dfe8a7ecbd'; - assetEntity.deviceAssetId = '4967046344801'; - assetEntity.deviceId = '116766fd-2ef2-52dc-a3ef-149988997291'; - assetEntity.type = AssetType.VIDEO; - assetEntity.originalPath = - 'upload/3ea54709-e168-42b7-90b0-a0dfe8a7ecbd/original/116766fd-2ef2-52dc-a3ef-149988997291/51c97f95-244f-462d-bdf0-e1dc19913516.jpg'; - assetEntity.resizePath = ''; - assetEntity.createdAt = '2022-06-19T23:41:36.910Z'; - assetEntity.modifiedAt = '2022-06-19T23:41:36.910Z'; - assetEntity.isFavorite = false; - assetEntity.mimeType = 'image/jpeg'; - assetEntity.webpPath = ''; - assetEntity.encodedVideoPath = ''; - assetEntity.duration = '0:00:00.000000'; + // assetEntity.id = 'e8edabfd-7d8a-45d0-9d61-7c7ca60f2c67'; + // assetEntity.userId = '3ea54709-e168-42b7-90b0-a0dfe8a7ecbd'; + // assetEntity.deviceAssetId = '4967046344801'; + // assetEntity.deviceId = '116766fd-2ef2-52dc-a3ef-149988997291'; + // assetEntity.type = AssetType.VIDEO; + // assetEntity.originalPath = + // 'upload/3ea54709-e168-42b7-90b0-a0dfe8a7ecbd/original/116766fd-2ef2-52dc-a3ef-149988997291/51c97f95-244f-462d-bdf0-e1dc19913516.jpg'; + // assetEntity.resizePath = ''; + // assetEntity.createdAt = '2022-06-19T23:41:36.910Z'; + // assetEntity.modifiedAt = '2022-06-19T23:41:36.910Z'; + // assetEntity.isFavorite = false; + // assetEntity.mimeType = 'image/jpeg'; + // assetEntity.webpPath = ''; + // assetEntity.encodedVideoPath = ''; + // assetEntity.duration = '0:00:00.000000'; - return assetEntity; - }; + // return assetEntity; + // }; beforeAll(() => { assetRepositoryMock = { diff --git a/server/apps/immich/src/api-v1/asset/dto/get-asset-thumbnail.dto.ts b/server/apps/immich/src/api-v1/asset/dto/get-asset-thumbnail.dto.ts index 9f75369d7d..a0df22d238 100644 --- a/server/apps/immich/src/api-v1/asset/dto/get-asset-thumbnail.dto.ts +++ b/server/apps/immich/src/api-v1/asset/dto/get-asset-thumbnail.dto.ts @@ -1,6 +1,5 @@ import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { IsBoolean, IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator'; +import { IsOptional } from 'class-validator'; export enum GetAssetThumbnailFormatEnum { JPEG = 'JPEG', diff --git a/server/apps/immich/src/api-v1/asset/dto/serve-file.dto.ts b/server/apps/immich/src/api-v1/asset/dto/serve-file.dto.ts index e22732005a..d544e5c845 100644 --- a/server/apps/immich/src/api-v1/asset/dto/serve-file.dto.ts +++ b/server/apps/immich/src/api-v1/asset/dto/serve-file.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; -import { Transform, Type } from 'class-transformer'; -import { IsBoolean, IsBooleanString, IsNotEmpty, IsOptional } from 'class-validator'; +import { Transform } from 'class-transformer'; +import { IsBoolean, IsNotEmpty, IsOptional } from 'class-validator'; export class ServeFileDto { @IsNotEmpty() diff --git a/server/apps/immich/src/api-v1/auth/auth.controller.ts b/server/apps/immich/src/api-v1/auth/auth.controller.ts index 031c39610d..1f53a3c776 100644 --- a/server/apps/immich/src/api-v1/auth/auth.controller.ts +++ b/server/apps/immich/src/api-v1/auth/auth.controller.ts @@ -1,12 +1,5 @@ import { Body, Controller, Post, Res, UseGuards, ValidationPipe } from '@nestjs/common'; -import { - ApiBadRequestResponse, - ApiBearerAuth, - ApiBody, - ApiCreatedResponse, - ApiResponse, - ApiTags, -} from '@nestjs/swagger'; +import { ApiBadRequestResponse, ApiBearerAuth, ApiTags } from '@nestjs/swagger'; import { AuthUserDto, GetAuthUser } from '../../decorators/auth-user.decorator'; import { JwtAuthGuard } from '../../modules/immich-jwt/guards/jwt-auth.guard'; import { AuthService } from './auth.service'; diff --git a/server/apps/immich/src/api-v1/auth/response-dto/login-response.dto.ts b/server/apps/immich/src/api-v1/auth/response-dto/login-response.dto.ts index f6870158aa..915a83793e 100644 --- a/server/apps/immich/src/api-v1/auth/response-dto/login-response.dto.ts +++ b/server/apps/immich/src/api-v1/auth/response-dto/login-response.dto.ts @@ -1,5 +1,5 @@ import { UserEntity } from '@app/database/entities/user.entity'; -import { ApiProperty, ApiResponseProperty } from '@nestjs/swagger'; +import { ApiResponseProperty } from '@nestjs/swagger'; export class LoginResponseDto { @ApiResponseProperty() diff --git a/server/apps/immich/src/api-v1/device-info/dto/update-device-info.dto.ts b/server/apps/immich/src/api-v1/device-info/dto/update-device-info.dto.ts index a047e852b5..f267d90362 100644 --- a/server/apps/immich/src/api-v1/device-info/dto/update-device-info.dto.ts +++ b/server/apps/immich/src/api-v1/device-info/dto/update-device-info.dto.ts @@ -1,8 +1,6 @@ import { DeviceType } from '@app/database/entities/device-info.entity'; -import { PartialType } from '@nestjs/mapped-types'; import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsOptional } from 'class-validator'; -import { CreateDeviceInfoDto } from './create-device-info.dto'; export class UpdateDeviceInfoDto { @IsNotEmpty() diff --git a/server/apps/immich/src/api-v1/server-info/server-info.controller.ts b/server/apps/immich/src/api-v1/server-info/server-info.controller.ts index 9c863d7e21..51b3d0a336 100644 --- a/server/apps/immich/src/api-v1/server-info/server-info.controller.ts +++ b/server/apps/immich/src/api-v1/server-info/server-info.controller.ts @@ -1,13 +1,10 @@ -import { Controller, Get, UseGuards } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import { JwtAuthGuard } from '../../modules/immich-jwt/guards/jwt-auth.guard'; +import { Controller, Get } from '@nestjs/common'; import { ServerInfoService } from './server-info.service'; import { serverVersion } from '../../constants/server_version.constant'; import { ApiTags } from '@nestjs/swagger'; import { ServerPingResponse } from './response-dto/server-ping-response.dto'; import { ServerVersionReponseDto } from './response-dto/server-version-response.dto'; import { ServerInfoResponseDto } from './response-dto/server-info-response.dto'; -import { DataSource } from 'typeorm'; @ApiTags('Server Info') @Controller('server-info') diff --git a/server/apps/immich/src/api-v1/user/user.controller.ts b/server/apps/immich/src/api-v1/user/user.controller.ts index e2eff4418c..6dc42a1276 100644 --- a/server/apps/immich/src/api-v1/user/user.controller.ts +++ b/server/apps/immich/src/api-v1/user/user.controller.ts @@ -12,7 +12,6 @@ import { UploadedFile, Response, Request, - StreamableFile, ParseBoolPipe, } from '@nestjs/common'; import { UserService } from './user.service'; diff --git a/server/apps/immich/src/app.module.ts b/server/apps/immich/src/app.module.ts index 9814fd54f0..16f644c030 100644 --- a/server/apps/immich/src/app.module.ts +++ b/server/apps/immich/src/app.module.ts @@ -15,7 +15,6 @@ import { AppController } from './app.controller'; import { ScheduleModule } from '@nestjs/schedule'; import { ScheduleTasksModule } from './modules/schedule-tasks/schedule-tasks.module'; import { DatabaseModule } from '@app/database'; -import { AppLoggerMiddleware } from './middlewares/app-logger.middleware'; @Module({ imports: [ diff --git a/server/apps/immich/src/main.ts b/server/apps/immich/src/main.ts index a977e446fd..7b03466ce9 100644 --- a/server/apps/immich/src/main.ts +++ b/server/apps/immich/src/main.ts @@ -1,4 +1,3 @@ -import { dataSource } from '@app/database/config/database.config'; import { Logger } from '@nestjs/common'; import { NestFactory } from '@nestjs/core'; import { NestExpressApplication } from '@nestjs/platform-express'; diff --git a/server/apps/immich/src/modules/background-task/background-task.service.ts b/server/apps/immich/src/modules/background-task/background-task.service.ts index f73091ffb9..0fb26b66a4 100644 --- a/server/apps/immich/src/modules/background-task/background-task.service.ts +++ b/server/apps/immich/src/modules/background-task/background-task.service.ts @@ -2,7 +2,6 @@ import { InjectQueue } from '@nestjs/bull/dist/decorators'; import { Injectable } from '@nestjs/common'; import { Queue } from 'bull'; import { randomUUID } from 'node:crypto'; -import { AssetEntity } from '@app/database/entities/asset.entity'; import { AssetResponseDto } from '../../api-v1/asset/response-dto/asset-response.dto'; @Injectable() diff --git a/server/apps/microservices/src/processors/generate-checksum.processor.ts b/server/apps/microservices/src/processors/generate-checksum.processor.ts index cebadc98cf..1057bf9202 100644 --- a/server/apps/microservices/src/processors/generate-checksum.processor.ts +++ b/server/apps/microservices/src/processors/generate-checksum.processor.ts @@ -18,7 +18,7 @@ export class GenerateChecksumProcessor { @Process() async generateChecksum() { let hasNext = true; - let pageSize = 200; + const pageSize = 200; while (hasNext) { const assets = await this.assetRepository.find({ diff --git a/server/apps/microservices/src/processors/metadata-extraction.processor.ts b/server/apps/microservices/src/processors/metadata-extraction.processor.ts index dc9e518396..195ffdbca3 100644 --- a/server/apps/microservices/src/processors/metadata-extraction.processor.ts +++ b/server/apps/microservices/src/processors/metadata-extraction.processor.ts @@ -21,7 +21,6 @@ import axios from 'axios'; import { Job } from 'bull'; import exifr from 'exifr'; import ffmpeg from 'fluent-ffmpeg'; -import { readFile } from 'fs/promises'; import path from 'path'; import sharp from 'sharp'; import { Repository } from 'typeorm/repository/Repository'; @@ -330,7 +329,7 @@ export class MetadataExtractionProcessor { } if (stream.r_frame_rate) { - let fpsParts = stream.r_frame_rate.split('/'); + const fpsParts = stream.r_frame_rate.split('/'); if (fpsParts.length === 2) { newExif.fps = Math.round(parseInt(fpsParts[0]) / parseInt(fpsParts[1]));