mirror of
https://github.com/immich-app/immich
synced 2026-08-15 13:03:57 +00:00
chore(server): remove unnused code
This commit is contained in:
parent
66d010381e
commit
1e1e5cea68
23 changed files with 5 additions and 328 deletions
|
|
@ -1,9 +1,7 @@
|
||||||
export const uuidDto = {
|
export const uuidDto = {
|
||||||
invalid: 'invalid-uuid',
|
|
||||||
// valid uuid v4
|
// valid uuid v4
|
||||||
notFound: '00000000-0000-4000-a000-000000000000',
|
notFound: '00000000-0000-4000-a000-000000000000',
|
||||||
dummy: '00000000-0000-4000-a000-000000000001',
|
dummy: '00000000-0000-4000-a000-000000000001',
|
||||||
dummy2: '00000000-0000-4000-a000-000000000002',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const adminLoginDto = {
|
const adminLoginDto = {
|
||||||
|
|
@ -57,22 +55,6 @@ export const createUserDto = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const userDto = {
|
export const userDto = {
|
||||||
admin: {
|
|
||||||
name: signupDto.admin.name,
|
|
||||||
email: signupDto.admin.email,
|
|
||||||
password: signupDto.admin.password,
|
|
||||||
storageLabel: 'admin',
|
|
||||||
oauthId: '',
|
|
||||||
shouldChangePassword: false,
|
|
||||||
profileImagePath: '',
|
|
||||||
createdAt: new Date('2021-01-01'),
|
|
||||||
deletedAt: null,
|
|
||||||
updatedAt: new Date('2021-01-01'),
|
|
||||||
tags: [],
|
|
||||||
assets: [],
|
|
||||||
quotaSizeInBytes: null,
|
|
||||||
quotaUsageInBytes: 0,
|
|
||||||
},
|
|
||||||
user1: {
|
user1: {
|
||||||
name: createUserDto.user1.name,
|
name: createUserDto.user1.name,
|
||||||
email: createUserDto.user1.email,
|
email: createUserDto.user1.email,
|
||||||
|
|
|
||||||
|
|
@ -40,41 +40,6 @@ export const errorDto = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const signupResponseDto = {
|
|
||||||
admin: {
|
|
||||||
avatarColor: expect.any(String),
|
|
||||||
id: expect.any(String),
|
|
||||||
name: 'Immich Admin',
|
|
||||||
email: 'admin@immich.cloud',
|
|
||||||
storageLabel: 'admin',
|
|
||||||
profileImagePath: '',
|
|
||||||
// why? lol
|
|
||||||
shouldChangePassword: true,
|
|
||||||
isAdmin: true,
|
|
||||||
createdAt: expect.any(String),
|
|
||||||
updatedAt: expect.any(String),
|
|
||||||
deletedAt: null,
|
|
||||||
oauthId: '',
|
|
||||||
quotaUsageInBytes: 0,
|
|
||||||
quotaSizeInBytes: null,
|
|
||||||
status: 'active',
|
|
||||||
license: null,
|
|
||||||
profileChangedAt: expect.any(String),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const loginResponseDto = {
|
|
||||||
admin: {
|
|
||||||
accessToken: expect.any(String),
|
|
||||||
name: 'Immich Admin',
|
|
||||||
isAdmin: true,
|
|
||||||
isOnboarded: false,
|
|
||||||
profileImagePath: '',
|
|
||||||
shouldChangePassword: true,
|
|
||||||
userEmail: 'admin@immich.cloud',
|
|
||||||
userId: expect.any(String),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
export const deviceDto = {
|
export const deviceDto = {
|
||||||
current: {
|
current: {
|
||||||
id: expect.any(String),
|
id: expect.any(String),
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,6 @@ export const ASPECT_RATIO_WEIGHTS = {
|
||||||
'3:1': 0.01, // 1% 3:1 panorama
|
'3:1': 0.01, // 1% 3:1 panorama
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export type AspectRatio = {
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
ratio: number;
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Mock configuration for asset generation - will be transformed to API response formats
|
// Mock configuration for asset generation - will be transformed to API response formats
|
||||||
export type MockTimelineAsset = {
|
export type MockTimelineAsset = {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { BrowserContext, expect, Page } from '@playwright/test';
|
import { expect, Page } from '@playwright/test';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { TimelineAssetConfig } from 'src/ui/generators/timeline';
|
import { TimelineAssetConfig } from 'src/ui/generators/timeline';
|
||||||
|
|
||||||
|
|
@ -11,18 +11,6 @@ export const padYearMonth = (yearMonth: string) => {
|
||||||
return `${year}-${month.padStart(2, '0')}`;
|
return `${year}-${month.padStart(2, '0')}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function throttlePage(context: BrowserContext, page: Page) {
|
|
||||||
const session = await context.newCDPSession(page);
|
|
||||||
await session.send('Network.emulateNetworkConditions', {
|
|
||||||
offline: false,
|
|
||||||
downloadThroughput: (1.5 * 1024 * 1024) / 8,
|
|
||||||
uploadThroughput: (750 * 1024) / 8,
|
|
||||||
latency: 40,
|
|
||||||
connectionType: 'cellular3g',
|
|
||||||
});
|
|
||||||
await session.send('Emulation.setCPUThrottlingRate', { rate: 10 });
|
|
||||||
}
|
|
||||||
|
|
||||||
export const poll = async <T>(
|
export const poll = async <T>(
|
||||||
page: Page,
|
page: Page,
|
||||||
query: () => Promise<T>,
|
query: () => Promise<T>,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { randomUUID } from 'node:crypto';
|
|
||||||
import { dirname, join, resolve } from 'node:path';
|
import { dirname, join, resolve } from 'node:path';
|
||||||
import { StorageAsset } from 'src/database';
|
import { StorageAsset } from 'src/database';
|
||||||
import {
|
import {
|
||||||
|
|
@ -352,10 +351,6 @@ export class StorageCore {
|
||||||
return join(StorageCore.getNestedFolder(folder, ownerId, filename), filename);
|
return join(StorageCore.getNestedFolder(folder, ownerId, filename), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getTempPathInDir(dir: string): string {
|
|
||||||
return join(dir, `${randomUUID()}.tmp`);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async getDevices() {
|
private async getDevices() {
|
||||||
try {
|
try {
|
||||||
return await this.storageRepository.readdir('/dev/dri');
|
return await this.storageRepository.readdir('/dev/dri');
|
||||||
|
|
|
||||||
|
|
@ -1211,14 +1211,6 @@ export enum ApiTag {
|
||||||
Workflows = 'Workflows',
|
Workflows = 'Workflows',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum PluginContext {
|
|
||||||
Asset = 'asset',
|
|
||||||
Album = 'album',
|
|
||||||
Person = 'person',
|
|
||||||
}
|
|
||||||
|
|
||||||
export const PluginContextSchema = z.enum(PluginContext).describe('Plugin context').meta({ id: 'PluginContextType' });
|
|
||||||
|
|
||||||
export const WorkflowTriggerSchema = z
|
export const WorkflowTriggerSchema = z
|
||||||
.enum(WorkflowTrigger)
|
.enum(WorkflowTrigger)
|
||||||
.describe('Plugin trigger type')
|
.describe('Plugin trigger type')
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,4 @@
|
||||||
import {
|
import { CanActivate, ExecutionContext, Injectable, SetMetadata, applyDecorators } from '@nestjs/common';
|
||||||
CanActivate,
|
|
||||||
ExecutionContext,
|
|
||||||
Injectable,
|
|
||||||
SetMetadata,
|
|
||||||
applyDecorators,
|
|
||||||
createParamDecorator,
|
|
||||||
} from '@nestjs/common';
|
|
||||||
import { Reflector } from '@nestjs/core';
|
import { Reflector } from '@nestjs/core';
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
import { MaintenanceAuthDto } from 'src/dtos/maintenance.dto';
|
import { MaintenanceAuthDto } from 'src/dtos/maintenance.dto';
|
||||||
|
|
@ -22,14 +15,6 @@ export interface MaintenanceAuthRequest extends Request {
|
||||||
auth?: MaintenanceAuthDto;
|
auth?: MaintenanceAuthDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MaintenanceAuthenticatedRequest extends Request {
|
|
||||||
auth: MaintenanceAuthDto;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const MaintenanceAuth = createParamDecorator((data, context: ExecutionContext): MaintenanceAuthDto => {
|
|
||||||
return context.switchToHttp().getRequest<MaintenanceAuthenticatedRequest>().auth;
|
|
||||||
});
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MaintenanceAuthGuard implements CanActivate {
|
export class MaintenanceAuthGuard implements CanActivate {
|
||||||
constructor(
|
constructor(
|
||||||
|
|
|
||||||
|
|
@ -483,35 +483,6 @@ export class DatabaseRepository {
|
||||||
await sql`SELECT pg_advisory_unlock(${lock})`.execute(connection);
|
await sql`SELECT pg_advisory_unlock(${lock})`.execute(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
async revertLastMigration(): Promise<string | undefined> {
|
|
||||||
this.logger.debug('Reverting last migration');
|
|
||||||
|
|
||||||
const migrator = this.createMigrator();
|
|
||||||
const { error, results } = await migrator.migrateDown();
|
|
||||||
|
|
||||||
for (const result of results ?? []) {
|
|
||||||
if (result.status === 'Success') {
|
|
||||||
this.logger.log(`Reverted migration "${result.migrationName}"`);
|
|
||||||
} else if (result.status === 'Error') {
|
|
||||||
this.logger.warn(`Failed to revert migration "${result.migrationName}"`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
this.logger.error(`Failed to revert migrations: ${error}`);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
const reverted = results?.find((result) => result.direction === 'Down' && result.status === 'Success');
|
|
||||||
if (!reverted) {
|
|
||||||
this.logger.debug('No migrations to revert');
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.debug('Finished reverting migration');
|
|
||||||
return reverted.migrationName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private createMigrator(): Migrator {
|
private createMigrator(): Migrator {
|
||||||
return new Migrator({
|
return new Migrator({
|
||||||
db: this.db,
|
db: this.db,
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,6 @@ export interface Face {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FacialRecognitionResponse = { [ModelTask.FACIAL_RECOGNITION]: Face[] } & VisualResponse;
|
export type FacialRecognitionResponse = { [ModelTask.FACIAL_RECOGNITION]: Face[] } & VisualResponse;
|
||||||
export type DetectedFaces = { faces: Face[] } & VisualResponse;
|
|
||||||
export type MachineLearningRequest = ClipVisualRequest | ClipTextualRequest | FacialRecognitionRequest | OcrRequest;
|
export type MachineLearningRequest = ClipVisualRequest | ClipTextualRequest | FacialRecognitionRequest | OcrRequest;
|
||||||
export type TextEncodingOptions = ModelOptions & { language?: string };
|
export type TextEncodingOptions = ModelOptions & { language?: string };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { ExpressionBuilder, Insertable, Kysely, Selectable, sql, Updateable } from 'kysely';
|
import { ExpressionBuilder, Insertable, Kysely, sql, Updateable } from 'kysely';
|
||||||
import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { AssetFace } from 'src/database';
|
import { AssetFace } from 'src/database';
|
||||||
|
|
@ -60,8 +60,6 @@ export interface GetAllFacesOptions {
|
||||||
|
|
||||||
export type UnassignFacesOptions = DeleteFacesOptions;
|
export type UnassignFacesOptions = DeleteFacesOptions;
|
||||||
|
|
||||||
export type SelectFaceOptions = (keyof Selectable<AssetFaceTable>)[];
|
|
||||||
|
|
||||||
const withPerson = (eb: ExpressionBuilder<DB, 'asset_face'>) => {
|
const withPerson = (eb: ExpressionBuilder<DB, 'asset_face'>) => {
|
||||||
return jsonObjectFrom(
|
return jsonObjectFrom(
|
||||||
eb.selectFrom('person').selectAll('person').whereRef('person.id', '=', 'asset_face.personId'),
|
eb.selectFrom('person').selectAll('person').whereRef('person.id', '=', 'asset_face.personId'),
|
||||||
|
|
|
||||||
|
|
@ -158,8 +158,6 @@ export type SmartSearchOptions = SearchDateOptions &
|
||||||
SearchTagOptions &
|
SearchTagOptions &
|
||||||
SearchOcrOptions & { visibility?: AssetVisibility | 'not-locked' };
|
SearchOcrOptions & { visibility?: AssetVisibility | 'not-locked' };
|
||||||
|
|
||||||
export type OcrSearchOptions = SearchDateOptions & SearchOcrOptions;
|
|
||||||
|
|
||||||
export type LargeAssetSearchOptions = AssetSearchOptions & { minFileSize?: number };
|
export type LargeAssetSearchOptions = AssetSearchOptions & { minFileSize?: number };
|
||||||
|
|
||||||
export interface FaceEmbeddingSearch extends SearchEmbeddingOptions {
|
export interface FaceEmbeddingSearch extends SearchEmbeddingOptions {
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,6 @@ import { ReleaseChannel } from 'src/dtos/system-config.dto';
|
||||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
|
|
||||||
export interface GitHubRelease {
|
|
||||||
id: number;
|
|
||||||
url: string;
|
|
||||||
tag_name: string;
|
|
||||||
name: string;
|
|
||||||
created_at: string;
|
|
||||||
published_at: string;
|
|
||||||
body: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface VersionResponse {
|
export interface VersionResponse {
|
||||||
version: string;
|
version: string;
|
||||||
published_at: string;
|
published_at: string;
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@ import { DB } from 'src/schema';
|
||||||
import { SessionTable } from 'src/schema/tables/session.table';
|
import { SessionTable } from 'src/schema/tables/session.table';
|
||||||
import { asUuid } from 'src/utils/database';
|
import { asUuid } from 'src/utils/database';
|
||||||
|
|
||||||
export type SessionSearchOptions = { updatedBefore: Date };
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SessionRepository {
|
export class SessionRepository {
|
||||||
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
||||||
|
|
|
||||||
|
|
@ -444,10 +444,6 @@ export class LibraryService extends BaseService {
|
||||||
await this.jobRepository.queue({ name: JobName.LibrarySyncAssetsQueueAll, data: { id } });
|
await this.jobRepository.queue({ name: JobName.LibrarySyncAssetsQueueAll, data: { id } });
|
||||||
}
|
}
|
||||||
|
|
||||||
async queueScanAll() {
|
|
||||||
await this.jobRepository.queue({ name: JobName.LibraryScanQueueAll, data: {} });
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnJob({ name: JobName.LibraryScanQueueAll, queue: QueueName.Library })
|
@OnJob({ name: JobName.LibraryScanQueueAll, queue: QueueName.Library })
|
||||||
async handleQueueScanAll(): Promise<JobStatus> {
|
async handleQueueScanAll(): Promise<JobStatus> {
|
||||||
this.logger.log(`Initiating scan of all external libraries...`);
|
this.logger.log(`Initiating scan of all external libraries...`);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { WorkflowTrigger } from '@immich/plugin-sdk';
|
|
||||||
import { ShallowDehydrateObject } from 'kysely';
|
import { ShallowDehydrateObject } from 'kysely';
|
||||||
import { SystemConfig } from 'src/config';
|
import { SystemConfig } from 'src/config';
|
||||||
import { VECTOR_EXTENSIONS } from 'src/constants';
|
import { VECTOR_EXTENSIONS } from 'src/constants';
|
||||||
|
|
@ -30,7 +29,6 @@ import {
|
||||||
SystemMetadataKey,
|
SystemMetadataKey,
|
||||||
TranscodeTarget,
|
TranscodeTarget,
|
||||||
UserMetadataKey,
|
UserMetadataKey,
|
||||||
WorkflowType,
|
|
||||||
} from 'src/enum';
|
} from 'src/enum';
|
||||||
import { Mocked } from 'vitest';
|
import { Mocked } from 'vitest';
|
||||||
|
|
||||||
|
|
@ -79,14 +77,6 @@ export interface DecodeToBufferOptions extends DecodeImageOptions {
|
||||||
export type GenerateThumbnailOptions = Pick<ImageOptions, 'format' | 'quality' | 'progressive'> & DecodeToBufferOptions;
|
export type GenerateThumbnailOptions = Pick<ImageOptions, 'format' | 'quality' | 'progressive'> & DecodeToBufferOptions;
|
||||||
export type GenerateThumbhashOptions = DecodeImageOptions;
|
export type GenerateThumbhashOptions = DecodeImageOptions;
|
||||||
|
|
||||||
export interface GenerateThumbnailsOptions {
|
|
||||||
colorspace: string;
|
|
||||||
preview?: ImageOptions;
|
|
||||||
processInvalidImages: boolean;
|
|
||||||
thumbhash?: boolean;
|
|
||||||
thumbnail?: ImageOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface VideoStreamInfo {
|
export interface VideoStreamInfo {
|
||||||
index: number;
|
index: number;
|
||||||
height: number;
|
height: number;
|
||||||
|
|
@ -143,10 +133,6 @@ export interface ImageDimensions {
|
||||||
height: number;
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InputDimensions extends ImageDimensions {
|
|
||||||
inputPath: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface VideoInfo {
|
export interface VideoInfo {
|
||||||
format: VideoFormat;
|
format: VideoFormat;
|
||||||
videoStreams: VideoStreamInfo[];
|
videoStreams: VideoStreamInfo[];
|
||||||
|
|
@ -189,11 +175,6 @@ export interface BitrateDistribution {
|
||||||
unit: string;
|
unit: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ImageBuffer {
|
|
||||||
data: Buffer;
|
|
||||||
info: RawImageInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface VideoCodecSWConfig {
|
export interface VideoCodecSWConfig {
|
||||||
getCommand(
|
getCommand(
|
||||||
target: TranscodeTarget,
|
target: TranscodeTarget,
|
||||||
|
|
@ -260,18 +241,10 @@ export interface ILibraryBulkIdsJob {
|
||||||
totalAssets: number;
|
totalAssets: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IBulkEntityJob {
|
|
||||||
ids: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IDeleteFilesJob extends IBaseJob {
|
export interface IDeleteFilesJob extends IBaseJob {
|
||||||
files: Array<string | null | undefined>;
|
files: Array<string | null | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISidecarWriteJob extends IEntityJob {
|
|
||||||
tags?: true;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IDeferrableJob extends IEntityJob {
|
export interface IDeferrableJob extends IEntityJob {
|
||||||
deferred?: boolean;
|
deferred?: boolean;
|
||||||
}
|
}
|
||||||
|
|
@ -307,12 +280,6 @@ export interface INotifyAlbumUpdateJob extends IEntityJob, IDelayedJob {
|
||||||
recipientId: string;
|
recipientId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type IWorkflowJob<T extends WorkflowType = WorkflowType> = {
|
|
||||||
id: string;
|
|
||||||
trigger: WorkflowTrigger;
|
|
||||||
type: T;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface IIntegrityJob {
|
export interface IIntegrityJob {
|
||||||
refreshOnly?: boolean;
|
refreshOnly?: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,8 +81,6 @@ export const asUuid = (id: string | Expression<string>) => sql<string>`${id}::uu
|
||||||
|
|
||||||
export const anyUuid = (ids: string[]) => sql<string>`any(${`{${ids}}`}::uuid[])`;
|
export const anyUuid = (ids: string[]) => sql<string>`any(${`{${ids}}`}::uuid[])`;
|
||||||
|
|
||||||
export const asVector = (embedding: number[]) => sql<string>`${`[${embedding}]`}::vector`;
|
|
||||||
|
|
||||||
export const unnest = (array: string[]) => sql<Record<string, string>>`unnest(array[${sql.join(array)}]::text[])`;
|
export const unnest = (array: string[]) => sql<Record<string, string>>`unnest(array[${sql.join(array)}]::text[])`;
|
||||||
|
|
||||||
export const removeUndefinedKeys = <T extends object>(update: T, template: unknown) => {
|
export const removeUndefinedKeys = <T extends object>(update: T, template: unknown) => {
|
||||||
|
|
|
||||||
|
|
@ -712,10 +712,6 @@ export class NvencSwDecodeConfig extends BaseHWConfig {
|
||||||
: ['-cq:v', String(this.config.crf)];
|
: ['-cq:v', String(this.config.crf)];
|
||||||
}
|
}
|
||||||
|
|
||||||
getThreadOptions() {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
getEncoderOptions(): string[] {
|
getEncoderOptions(): string[] {
|
||||||
const out = this.getOutputThreadOptions();
|
const out = this.getOutputThreadOptions();
|
||||||
if (this.tune.strictGop) {
|
if (this.tune.strictGop) {
|
||||||
|
|
|
||||||
13
server/test/fixtures/auth.stub.ts
vendored
13
server/test/fixtures/auth.stub.ts
vendored
|
|
@ -28,19 +28,6 @@ export const authStub = {
|
||||||
id: 'token-id',
|
id: 'token-id',
|
||||||
} as AuthSession,
|
} as AuthSession,
|
||||||
}),
|
}),
|
||||||
user2: Object.freeze<AuthDto>({
|
|
||||||
user: {
|
|
||||||
id: 'user-2',
|
|
||||||
name: 'User 2',
|
|
||||||
email: 'user2@immich.cloud',
|
|
||||||
isAdmin: false,
|
|
||||||
quotaSizeInBytes: null,
|
|
||||||
quotaUsageInBytes: 0,
|
|
||||||
},
|
|
||||||
session: {
|
|
||||||
id: 'token-id',
|
|
||||||
} as AuthSession,
|
|
||||||
}),
|
|
||||||
adminWithElevatedPermission: Object.freeze<AuthDto>({
|
adminWithElevatedPermission: Object.freeze<AuthDto>({
|
||||||
user: authUser.admin,
|
user: authUser.admin,
|
||||||
session: {
|
session: {
|
||||||
|
|
|
||||||
7
server/test/fixtures/file.stub.ts
vendored
7
server/test/fixtures/file.stub.ts
vendored
|
|
@ -6,13 +6,6 @@ export const fileStub = {
|
||||||
originalName: 'asset_1.jpeg',
|
originalName: 'asset_1.jpeg',
|
||||||
size: 42,
|
size: 42,
|
||||||
}),
|
}),
|
||||||
livePhotoMotion: Object.freeze({
|
|
||||||
uuid: 'live-photo-motion-asset',
|
|
||||||
originalPath: 'fake_path/asset_1.mp4',
|
|
||||||
checksum: Buffer.from('live photo file hash', 'utf8'),
|
|
||||||
originalName: 'asset_1.mp4',
|
|
||||||
size: 69,
|
|
||||||
}),
|
|
||||||
photo: Object.freeze({
|
photo: Object.freeze({
|
||||||
uuid: 'photo',
|
uuid: 'photo',
|
||||||
originalPath: 'fake_path/photo1.jpeg',
|
originalPath: 'fake_path/photo1.jpeg',
|
||||||
|
|
|
||||||
22
server/test/fixtures/media.stub.ts
vendored
22
server/test/fixtures/media.stub.ts
vendored
|
|
@ -451,28 +451,6 @@ export const videoInfoStub = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
videoStreamWithProfileLevel: Object.freeze<VideoInfo>({
|
|
||||||
...probeStubDefault,
|
|
||||||
videoStreams: [
|
|
||||||
{
|
|
||||||
...probeStubDefaultVideoStream[0],
|
|
||||||
codecName: 'h264',
|
|
||||||
profile: 100,
|
|
||||||
level: 40,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
audioStreamAAC: Object.freeze<VideoInfo>({
|
|
||||||
...probeStubDefault,
|
|
||||||
audioStreams: [
|
|
||||||
{
|
|
||||||
index: 1,
|
|
||||||
codecName: 'aac',
|
|
||||||
profile: 2,
|
|
||||||
bitrate: 128_000,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
interface SelectedStreams {
|
interface SelectedStreams {
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,6 @@
|
||||||
import { expect } from 'vitest';
|
import { expect } from 'vitest';
|
||||||
|
|
||||||
export const errorDto = {
|
export const errorDto = {
|
||||||
unauthorized: {
|
|
||||||
message: 'Authentication required',
|
|
||||||
},
|
|
||||||
forbidden: {
|
|
||||||
message: expect.any(String),
|
|
||||||
},
|
|
||||||
missingPermission: (permission: string) => ({
|
|
||||||
message: `Missing required permission: ${permission}`,
|
|
||||||
}),
|
|
||||||
wrongPassword: {
|
|
||||||
message: 'Wrong password',
|
|
||||||
},
|
|
||||||
invalidToken: {
|
|
||||||
message: 'Invalid user token',
|
|
||||||
},
|
|
||||||
invalidShareKey: {
|
|
||||||
message: 'Invalid share key',
|
|
||||||
},
|
|
||||||
invalidSharePassword: {
|
|
||||||
message: 'Invalid password',
|
|
||||||
},
|
|
||||||
badRequest: (message: any = null) => ({
|
badRequest: (message: any = null) => ({
|
||||||
message: message ?? expect.anything(),
|
message: message ?? expect.anything(),
|
||||||
}),
|
}),
|
||||||
|
|
@ -29,10 +8,4 @@ export const errorDto = {
|
||||||
message: 'Validation failed',
|
message: 'Validation failed',
|
||||||
errors: errors ? expect.arrayContaining(errors.map((e) => expect.objectContaining(e))) : expect.any(Array),
|
errors: errors ? expect.arrayContaining(errors.map((e) => expect.objectContaining(e))) : expect.any(Array),
|
||||||
}),
|
}),
|
||||||
noPermission: {
|
|
||||||
message: expect.stringContaining('Not found or no'),
|
|
||||||
},
|
|
||||||
incorrectLogin: {
|
|
||||||
message: 'Incorrect email or password',
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { AuthApiKey, AuthSharedLink, AuthUser, Exif, Library, UserAdmin } from 'src/database';
|
import { AuthApiKey, AuthSharedLink, AuthUser, Library, UserAdmin } from 'src/database';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { QueueStatisticsDto } from 'src/dtos/queue.dto';
|
import { QueueStatisticsDto } from 'src/dtos/queue.dto';
|
||||||
import { AssetFileType, Permission, UserStatus } from 'src/enum';
|
import { Permission, UserStatus } from 'src/enum';
|
||||||
import { v4, v7 } from 'uuid';
|
import { v4, v7 } from 'uuid';
|
||||||
import { expect } from 'vitest';
|
import { expect } from 'vitest';
|
||||||
|
|
||||||
|
|
@ -168,31 +168,6 @@ const versionHistoryFactory = () => ({
|
||||||
version: '1.123.45',
|
version: '1.123.45',
|
||||||
});
|
});
|
||||||
|
|
||||||
const assetSidecarWriteFactory = () => {
|
|
||||||
const id = newUuid();
|
|
||||||
return {
|
|
||||||
id,
|
|
||||||
originalPath: '/path/to/original-path.jpg.xmp',
|
|
||||||
tags: [],
|
|
||||||
files: [
|
|
||||||
{
|
|
||||||
id: newUuid(),
|
|
||||||
path: '/path/to/original-path.jpg.xmp',
|
|
||||||
type: AssetFileType.Sidecar,
|
|
||||||
isEdited: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
exifInfo: {
|
|
||||||
assetId: id,
|
|
||||||
description: 'this is a description',
|
|
||||||
latitude: 12,
|
|
||||||
longitude: 12,
|
|
||||||
dateTimeOriginal: '2023-11-22T04:56:12.196Z',
|
|
||||||
timeZone: 'UTC-6',
|
|
||||||
} as unknown as Exif,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const assetOcrFactory = (
|
const assetOcrFactory = (
|
||||||
ocr: {
|
ocr: {
|
||||||
id?: string;
|
id?: string;
|
||||||
|
|
@ -236,9 +211,6 @@ export const factory = {
|
||||||
library: libraryFactory,
|
library: libraryFactory,
|
||||||
queueStatistics: queueStatisticsFactory,
|
queueStatistics: queueStatisticsFactory,
|
||||||
versionHistory: versionHistoryFactory,
|
versionHistory: versionHistoryFactory,
|
||||||
jobAssets: {
|
|
||||||
sidecarWrite: assetSidecarWriteFactory,
|
|
||||||
},
|
|
||||||
uuid: newUuid,
|
uuid: newUuid,
|
||||||
buffer: () => Buffer.from('this is a fake buffer'),
|
buffer: () => Buffer.from('this is a fake buffer'),
|
||||||
date: newDate,
|
date: newDate,
|
||||||
|
|
|
||||||
|
|
@ -553,43 +553,6 @@ export const mockDuplex =
|
||||||
return duplex;
|
return duplex;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mockFork = vitest.fn((exitCode: number, stdout: string, stderr: string, error?: unknown) => {
|
|
||||||
const stdoutStream = new Readable({
|
|
||||||
read() {
|
|
||||||
this.push(stdout); // write mock data to stdout
|
|
||||||
this.push(null); // end stream
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
stdout: stdoutStream,
|
|
||||||
stderr: new Readable({
|
|
||||||
read() {
|
|
||||||
this.push(stderr); // write mock data to stderr
|
|
||||||
this.push(null); // end stream
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
stdin: new Writable({
|
|
||||||
write(chunk, encoding, callback) {
|
|
||||||
callback();
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
exitCode,
|
|
||||||
on: vitest.fn((event, callback: any) => {
|
|
||||||
if (event === 'close') {
|
|
||||||
stdoutStream.once('end', () => callback(0));
|
|
||||||
}
|
|
||||||
if (event === 'error' && error) {
|
|
||||||
stdoutStream.once('end', () => callback(error));
|
|
||||||
}
|
|
||||||
if (event === 'exit') {
|
|
||||||
stdoutStream.once('end', () => callback(exitCode));
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
kill: vitest.fn(),
|
|
||||||
} as unknown as ChildProcessWithoutNullStreams;
|
|
||||||
});
|
|
||||||
|
|
||||||
export async function* makeStream<T>(items: T[] = []): AsyncGenerator<T> {
|
export async function* makeStream<T>(items: T[] = []): AsyncGenerator<T> {
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue