refactor: enum casing (#19946)

This commit is contained in:
Jason Rasmussen
2025-07-15 14:50:13 -04:00
committed by GitHub
parent 920d7de349
commit e73abe0762
174 changed files with 2675 additions and 2459 deletions

View File

@@ -91,7 +91,7 @@ class AlbumAccess {
}
const accessRole =
access === AlbumUserRole.EDITOR ? [AlbumUserRole.EDITOR] : [AlbumUserRole.EDITOR, AlbumUserRole.VIEWER];
access === AlbumUserRole.Editor ? [AlbumUserRole.Editor] : [AlbumUserRole.Editor, AlbumUserRole.Viewer];
return this.db
.selectFrom('album')
@@ -178,7 +178,7 @@ class AssetAccess {
.select('asset.id')
.where('asset.id', 'in', [...assetIds])
.where('asset.ownerId', '=', userId)
.$if(!hasElevatedPermission, (eb) => eb.where('asset.visibility', '!=', AssetVisibility.LOCKED))
.$if(!hasElevatedPermission, (eb) => eb.where('asset.visibility', '!=', AssetVisibility.Locked))
.execute()
.then((assets) => new Set(assets.map((asset) => asset.id)));
}
@@ -200,8 +200,8 @@ class AssetAccess {
.where('partner.sharedWithId', '=', userId)
.where((eb) =>
eb.or([
eb('asset.visibility', '=', sql.lit(AssetVisibility.TIMELINE)),
eb('asset.visibility', '=', sql.lit(AssetVisibility.HIDDEN)),
eb('asset.visibility', '=', sql.lit(AssetVisibility.Timeline)),
eb('asset.visibility', '=', sql.lit(AssetVisibility.Hidden)),
]),
)

View File

@@ -90,7 +90,7 @@ export class ActivityRepository {
.where('activity.albumId', '=', albumId)
.where(({ or, and, eb }) =>
or([
and([eb('asset.deletedAt', 'is', null), eb('asset.visibility', '!=', sql.lit(AssetVisibility.LOCKED))]),
and([eb('asset.deletedAt', 'is', null), eb('asset.visibility', '!=', sql.lit(AssetVisibility.Locked))]),
eb('asset.id', 'is', null),
]),
)

View File

@@ -24,7 +24,7 @@ export class AlbumUserRepository {
.executeTakeFirstOrThrow();
}
@GenerateSql({ params: [{ usersId: DummyValue.UUID, albumsId: DummyValue.UUID }, { role: AlbumUserRole.VIEWER }] })
@GenerateSql({ params: [{ usersId: DummyValue.UUID, albumsId: DummyValue.UUID }, { role: AlbumUserRole.Viewer }] })
update({ usersId, albumsId }: AlbumPermissionId, dto: Updateable<AlbumUserTable>) {
return this.db
.updateTable('album_user')

View File

@@ -62,7 +62,7 @@ export class AssetJobRepository {
.select(['asset.id', 'asset.thumbhash'])
.select(withFiles)
.where('asset.deletedAt', 'is', null)
.where('asset.visibility', '!=', AssetVisibility.HIDDEN)
.where('asset.visibility', '!=', AssetVisibility.Hidden)
.$if(!force, (qb) =>
qb
// If there aren't any entries, metadata extraction hasn't run yet which is required for thumbnails
@@ -117,7 +117,7 @@ export class AssetJobRepository {
.executeTakeFirst();
}
@GenerateSql({ params: [DummyValue.UUID, AssetFileType.THUMBNAIL] })
@GenerateSql({ params: [DummyValue.UUID, AssetFileType.Thumbnail] })
getAlbumThumbnailFiles(id: string, fileType?: AssetFileType) {
return this.db
.selectFrom('asset_file')
@@ -130,7 +130,7 @@ export class AssetJobRepository {
private assetsWithPreviews() {
return this.db
.selectFrom('asset')
.where('asset.visibility', '!=', AssetVisibility.HIDDEN)
.where('asset.visibility', '!=', AssetVisibility.Hidden)
.where('asset.deletedAt', 'is', null)
.innerJoin('asset_job_status as job_status', 'assetId', 'asset.id')
.where('job_status.previewAt', 'is not', null);
@@ -167,7 +167,7 @@ export class AssetJobRepository {
return this.db
.selectFrom('asset')
.select(['asset.id', 'asset.visibility'])
.select((eb) => withFiles(eb, AssetFileType.PREVIEW))
.select((eb) => withFiles(eb, AssetFileType.Preview))
.where('asset.id', '=', id)
.executeTakeFirst();
}
@@ -179,7 +179,7 @@ export class AssetJobRepository {
.select(['asset.id', 'asset.visibility'])
.$call(withExifInner)
.select((eb) => withFaces(eb, true))
.select((eb) => withFiles(eb, AssetFileType.PREVIEW))
.select((eb) => withFiles(eb, AssetFileType.Preview))
.where('asset.id', '=', id)
.executeTakeFirst();
}
@@ -225,7 +225,7 @@ export class AssetJobRepository {
.select(['stack.id', 'stack.primaryAssetId'])
.select((eb) => eb.fn<Asset[]>('array_agg', [eb.table('stacked')]).as('assets'))
.where('stacked.deletedAt', 'is not', null)
.where('stacked.visibility', '=', AssetVisibility.TIMELINE)
.where('stacked.visibility', '=', AssetVisibility.Timeline)
.whereRef('stacked.stackId', '=', 'stack.id')
.groupBy('stack.id')
.as('stacked_assets'),
@@ -241,11 +241,11 @@ export class AssetJobRepository {
return this.db
.selectFrom('asset')
.select(['asset.id'])
.where('asset.type', '=', AssetType.VIDEO)
.where('asset.type', '=', AssetType.Video)
.$if(!force, (qb) =>
qb
.where((eb) => eb.or([eb('asset.encodedVideoPath', 'is', null), eb('asset.encodedVideoPath', '=', '')]))
.where('asset.visibility', '!=', AssetVisibility.HIDDEN),
.where('asset.visibility', '!=', AssetVisibility.Hidden),
)
.where('asset.deletedAt', 'is', null)
.stream();
@@ -257,7 +257,7 @@ export class AssetJobRepository {
.selectFrom('asset')
.select(['asset.id', 'asset.ownerId', 'asset.originalPath', 'asset.encodedVideoPath'])
.where('asset.id', '=', id)
.where('asset.type', '=', AssetType.VIDEO)
.where('asset.type', '=', AssetType.Video)
.executeTakeFirst();
}
@@ -327,7 +327,7 @@ export class AssetJobRepository {
.$if(!force, (qb) =>
qb.where((eb) => eb.or([eb('asset.sidecarPath', '=', ''), eb('asset.sidecarPath', 'is', null)])),
)
.where('asset.visibility', '!=', AssetVisibility.HIDDEN)
.where('asset.visibility', '!=', AssetVisibility.Hidden)
.stream();
}

View File

@@ -230,13 +230,13 @@ export class AssetRepository {
.where('asset_job_status.previewAt', 'is not', null)
.where(sql`(asset."localDateTime" at time zone 'UTC')::date`, '=', sql`today.date`)
.where('asset.ownerId', '=', anyUuid(ownerIds))
.where('asset.visibility', '=', AssetVisibility.TIMELINE)
.where('asset.visibility', '=', AssetVisibility.Timeline)
.where((eb) =>
eb.exists((qb) =>
qb
.selectFrom('asset_file')
.whereRef('assetId', '=', 'asset.id')
.where('asset_file.type', '=', AssetFileType.PREVIEW),
.where('asset_file.type', '=', AssetFileType.Preview),
),
)
.where('asset.deletedAt', 'is', null)
@@ -318,7 +318,7 @@ export class AssetRepository {
.select(['deviceAssetId'])
.where('ownerId', '=', asUuid(ownerId))
.where('deviceId', '=', deviceId)
.where('visibility', '!=', AssetVisibility.HIDDEN)
.where('visibility', '!=', AssetVisibility.Hidden)
.where('deletedAt', 'is', null)
.execute();
@@ -363,7 +363,7 @@ export class AssetRepository {
.whereRef('stacked.stackId', '=', 'stack.id')
.whereRef('stacked.id', '!=', 'stack.primaryAssetId')
.where('stacked.deletedAt', 'is', null)
.where('stacked.visibility', '=', AssetVisibility.TIMELINE)
.where('stacked.visibility', '=', AssetVisibility.Timeline)
.groupBy('stack.id')
.as('stacked_assets'),
(join) => join.on('stack.id', 'is not', null),
@@ -463,15 +463,15 @@ export class AssetRepository {
getStatistics(ownerId: string, { visibility, isFavorite, isTrashed }: AssetStatsOptions): Promise<AssetStats> {
return this.db
.selectFrom('asset')
.select((eb) => eb.fn.countAll<number>().filterWhere('type', '=', AssetType.AUDIO).as(AssetType.AUDIO))
.select((eb) => eb.fn.countAll<number>().filterWhere('type', '=', AssetType.IMAGE).as(AssetType.IMAGE))
.select((eb) => eb.fn.countAll<number>().filterWhere('type', '=', AssetType.VIDEO).as(AssetType.VIDEO))
.select((eb) => eb.fn.countAll<number>().filterWhere('type', '=', AssetType.OTHER).as(AssetType.OTHER))
.select((eb) => eb.fn.countAll<number>().filterWhere('type', '=', AssetType.Audio).as(AssetType.Audio))
.select((eb) => eb.fn.countAll<number>().filterWhere('type', '=', AssetType.Image).as(AssetType.Image))
.select((eb) => eb.fn.countAll<number>().filterWhere('type', '=', AssetType.Video).as(AssetType.Video))
.select((eb) => eb.fn.countAll<number>().filterWhere('type', '=', AssetType.Other).as(AssetType.Other))
.where('ownerId', '=', asUuid(ownerId))
.$if(visibility === undefined, withDefaultVisibility)
.$if(!!visibility, (qb) => qb.where('asset.visibility', '=', visibility!))
.$if(isFavorite !== undefined, (qb) => qb.where('isFavorite', '=', isFavorite!))
.$if(!!isTrashed, (qb) => qb.where('asset.status', '!=', AssetStatus.DELETED))
.$if(!!isTrashed, (qb) => qb.where('asset.status', '!=', AssetStatus.Deleted))
.where('deletedAt', isTrashed ? 'is not' : 'is', null)
.executeTakeFirstOrThrow();
}
@@ -496,7 +496,7 @@ export class AssetRepository {
qb
.selectFrom('asset')
.select(truncatedDate<Date>().as('timeBucket'))
.$if(!!options.isTrashed, (qb) => qb.where('asset.status', '!=', AssetStatus.DELETED))
.$if(!!options.isTrashed, (qb) => qb.where('asset.status', '!=', AssetStatus.Deleted))
.where('asset.deletedAt', options.isTrashed ? 'is not' : 'is', null)
.$if(options.visibility === undefined, withDefaultVisibility)
.$if(!!options.visibility, (qb) => qb.where('asset.visibility', '=', options.visibility!))
@@ -606,7 +606,7 @@ export class AssetRepository {
.select(sql`array[stacked."stackId"::text, count('stacked')::text]`.as('stack'))
.whereRef('stacked.stackId', '=', 'asset.stackId')
.where('stacked.deletedAt', 'is', null)
.where('stacked.visibility', '=', AssetVisibility.TIMELINE)
.where('stacked.visibility', '=', AssetVisibility.Timeline)
.groupBy('stacked.stackId')
.as('stacked_assets'),
(join) => join.onTrue(),
@@ -617,7 +617,7 @@ export class AssetRepository {
.$if(options.isDuplicate !== undefined, (qb) =>
qb.where('asset.duplicateId', options.isDuplicate ? 'is not' : 'is', null),
)
.$if(!!options.isTrashed, (qb) => qb.where('asset.status', '!=', AssetStatus.DELETED))
.$if(!!options.isTrashed, (qb) => qb.where('asset.status', '!=', AssetStatus.Deleted))
.$if(!!options.tagId, (qb) => withTagId(qb, options.tagId!))
.orderBy('asset.fileCreatedAt', options.order ?? 'desc'),
)
@@ -671,8 +671,8 @@ export class AssetRepository {
.select(['assetId as data', 'asset_exif.city as value'])
.$narrowType<{ value: NotNull }>()
.where('ownerId', '=', asUuid(ownerId))
.where('visibility', '=', AssetVisibility.TIMELINE)
.where('type', '=', AssetType.IMAGE)
.where('visibility', '=', AssetVisibility.Timeline)
.where('type', '=', AssetType.Image)
.where('deletedAt', 'is', null)
.limit(maxFields)
.execute();
@@ -710,7 +710,7 @@ export class AssetRepository {
)
.select((eb) => eb.fn.toJson(eb.table('stacked_assets')).$castTo<Stack | null>().as('stack'))
.where('asset.ownerId', '=', asUuid(ownerId))
.where('asset.visibility', '!=', AssetVisibility.HIDDEN)
.where('asset.visibility', '!=', AssetVisibility.Hidden)
.where('asset.updatedAt', '<=', updatedUntil)
.$if(!!lastId, (qb) => qb.where('asset.id', '>', lastId!))
.orderBy('asset.id')
@@ -738,7 +738,7 @@ export class AssetRepository {
)
.select((eb) => eb.fn.toJson(eb.table('stacked_assets').$castTo<Stack | null>()).as('stack'))
.where('asset.ownerId', '=', anyUuid(options.userIds))
.where('asset.visibility', '!=', AssetVisibility.HIDDEN)
.where('asset.visibility', '!=', AssetVisibility.Hidden)
.where('asset.updatedAt', '>', options.updatedAfter)
.limit(options.limit)
.execute();

View File

@@ -18,7 +18,7 @@ export class AuditRepository {
@GenerateSql({
params: [
DummyValue.DATE,
{ action: DatabaseAction.CREATE, entityType: EntityType.ASSET, userIds: [DummyValue.UUID] },
{ action: DatabaseAction.Create, entityType: EntityType.Asset, userIds: [DummyValue.UUID] },
],
})
async getAfter(since: Date, options: AuditSearch): Promise<string[]> {

View File

@@ -275,14 +275,14 @@ describe('getEnv', () => {
process.env.IMMICH_TELEMETRY_EXCLUDE = 'job';
const { telemetry } = getEnv();
expect(telemetry.metrics).toEqual(
new Set([ImmichTelemetry.API, ImmichTelemetry.HOST, ImmichTelemetry.IO, ImmichTelemetry.REPO]),
new Set([ImmichTelemetry.Api, ImmichTelemetry.Host, ImmichTelemetry.Io, ImmichTelemetry.Repo]),
);
});
it('should run with specific telemetry metrics', () => {
process.env.IMMICH_TELEMETRY_INCLUDE = 'io, host, api';
const { telemetry } = getEnv();
expect(telemetry.metrics).toEqual(new Set([ImmichTelemetry.API, ImmichTelemetry.HOST, ImmichTelemetry.IO]));
expect(telemetry.metrics).toEqual(new Set([ImmichTelemetry.Api, ImmichTelemetry.Host, ImmichTelemetry.Io]));
});
});
});

View File

@@ -136,7 +136,7 @@ const getEnv = (): EnvData => {
);
}
const includedWorkers = asSet(dto.IMMICH_WORKERS_INCLUDE, [ImmichWorker.API, ImmichWorker.MICROSERVICES]);
const includedWorkers = asSet(dto.IMMICH_WORKERS_INCLUDE, [ImmichWorker.Api, ImmichWorker.Microservices]);
const excludedWorkers = asSet(dto.IMMICH_WORKERS_EXCLUDE, []);
const workers = [...setDifference(includedWorkers, excludedWorkers)];
for (const worker of workers) {
@@ -145,8 +145,8 @@ const getEnv = (): EnvData => {
}
}
const environment = dto.IMMICH_ENV || ImmichEnvironment.PRODUCTION;
const isProd = environment === ImmichEnvironment.PRODUCTION;
const environment = dto.IMMICH_ENV || ImmichEnvironment.Production;
const isProd = environment === ImmichEnvironment.Production;
const buildFolder = dto.IMMICH_BUILD_DATA || '/build';
const folders = {
geodata: join(buildFolder, 'geodata'),
@@ -199,15 +199,15 @@ const getEnv = (): EnvData => {
let vectorExtension: VectorExtension | undefined;
switch (dto.DB_VECTOR_EXTENSION) {
case 'pgvector': {
vectorExtension = DatabaseExtension.VECTOR;
vectorExtension = DatabaseExtension.Vector;
break;
}
case 'pgvecto.rs': {
vectorExtension = DatabaseExtension.VECTORS;
vectorExtension = DatabaseExtension.Vectors;
break;
}
case 'vectorchord': {
vectorExtension = DatabaseExtension.VECTORCHORD;
vectorExtension = DatabaseExtension.VectorChord;
break;
}
}
@@ -254,11 +254,11 @@ const getEnv = (): EnvData => {
mount: true,
generateId: true,
setup: (cls, req: Request, res: Response) => {
const headerValues = req.headers[ImmichHeader.CID];
const headerValues = req.headers[ImmichHeader.Cid];
const headerValue = Array.isArray(headerValues) ? headerValues[0] : headerValues;
const cid = headerValue || cls.get(CLS_ID);
cls.set(CLS_ID, cid);
res.header(ImmichHeader.CID, cid);
res.header(ImmichHeader.Cid, cid);
},
},
},
@@ -278,9 +278,9 @@ const getEnv = (): EnvData => {
otel: {
metrics: {
hostMetrics: telemetries.has(ImmichTelemetry.HOST),
hostMetrics: telemetries.has(ImmichTelemetry.Host),
apiMetrics: {
enable: telemetries.has(ImmichTelemetry.API),
enable: telemetries.has(ImmichTelemetry.Api),
ignoreRoutes: excludePaths,
},
},
@@ -335,7 +335,7 @@ export class ConfigRepository {
}
isDev() {
return this.getEnv().environment === ImmichEnvironment.DEVELOPMENT;
return this.getEnv().environment === ImmichEnvironment.Development;
}
getWorker() {

View File

@@ -53,8 +53,8 @@ export async function getVectorExtension(runner: Kysely<DB> | QueryRunner): Prom
}
export const probes: Record<VectorIndex, number> = {
[VectorIndex.CLIP]: 1,
[VectorIndex.FACE]: 1,
[VectorIndex.Clip]: 1,
[VectorIndex.Face]: 1,
};
@Injectable()
@@ -77,7 +77,7 @@ export class DatabaseRepository {
return getVectorExtension(this.db);
}
@GenerateSql({ params: [[DatabaseExtension.VECTORS]] })
@GenerateSql({ params: [[DatabaseExtension.Vectors]] })
async getExtensionVersions(extensions: readonly DatabaseExtension[]): Promise<ExtensionVersion[]> {
const { rows } = await sql<ExtensionVersion>`
SELECT name, default_version as "availableVersion", installed_version as "installedVersion"
@@ -89,13 +89,13 @@ export class DatabaseRepository {
getExtensionVersionRange(extension: VectorExtension): string {
switch (extension) {
case DatabaseExtension.VECTORCHORD: {
case DatabaseExtension.VectorChord: {
return VECTORCHORD_VERSION_RANGE;
}
case DatabaseExtension.VECTORS: {
case DatabaseExtension.Vectors: {
return VECTORS_VERSION_RANGE;
}
case DatabaseExtension.VECTOR: {
case DatabaseExtension.Vector: {
return VECTOR_VERSION_RANGE;
}
default: {
@@ -117,7 +117,7 @@ export class DatabaseRepository {
async createExtension(extension: DatabaseExtension): Promise<void> {
this.logger.log(`Creating ${EXTENSION_NAMES[extension]} extension`);
await sql`CREATE EXTENSION IF NOT EXISTS ${sql.raw(extension)} CASCADE`.execute(this.db);
if (extension === DatabaseExtension.VECTORCHORD) {
if (extension === DatabaseExtension.VectorChord) {
const dbName = sql.id(await this.getDatabaseName());
await sql`ALTER DATABASE ${dbName} SET vchordrq.probes = 1`.execute(this.db);
await sql`SET vchordrq.probes = 1`.execute(this.db);
@@ -147,8 +147,8 @@ export class DatabaseRepository {
}
await Promise.all([
this.db.schema.dropIndex(VectorIndex.CLIP).ifExists().execute(),
this.db.schema.dropIndex(VectorIndex.FACE).ifExists().execute(),
this.db.schema.dropIndex(VectorIndex.Clip).ifExists().execute(),
this.db.schema.dropIndex(VectorIndex.Face).ifExists().execute(),
]);
await this.db.transaction().execute(async (tx) => {
@@ -156,14 +156,14 @@ export class DatabaseRepository {
await sql`ALTER EXTENSION ${sql.raw(extension)} UPDATE TO ${sql.lit(targetVersion)}`.execute(tx);
if (extension === DatabaseExtension.VECTORS && (diff === 'major' || diff === 'minor')) {
if (extension === DatabaseExtension.Vectors && (diff === 'major' || diff === 'minor')) {
await sql`SELECT pgvectors_upgrade()`.execute(tx);
restartRequired = true;
}
});
if (!restartRequired) {
await Promise.all([this.reindexVectors(VectorIndex.CLIP), this.reindexVectors(VectorIndex.FACE)]);
await Promise.all([this.reindexVectors(VectorIndex.Clip), this.reindexVectors(VectorIndex.Face)]);
}
return { restartRequired };
@@ -171,7 +171,7 @@ export class DatabaseRepository {
async prewarm(index: VectorIndex): Promise<void> {
const vectorExtension = await getVectorExtension(this.db);
if (vectorExtension !== DatabaseExtension.VECTORCHORD) {
if (vectorExtension !== DatabaseExtension.VectorChord) {
return;
}
this.logger.debug(`Prewarming ${index}`);
@@ -196,19 +196,19 @@ export class DatabaseRepository {
}
switch (vectorExtension) {
case DatabaseExtension.VECTOR: {
case DatabaseExtension.Vector: {
if (!row.indexdef.toLowerCase().includes('using hnsw')) {
promises.push(this.reindexVectors(indexName));
}
break;
}
case DatabaseExtension.VECTORS: {
case DatabaseExtension.Vectors: {
if (!row.indexdef.toLowerCase().includes('using vectors')) {
promises.push(this.reindexVectors(indexName));
}
break;
}
case DatabaseExtension.VECTORCHORD: {
case DatabaseExtension.VectorChord: {
const matches = row.indexdef.match(/(?<=lists = \[)\d+/g);
const lists = matches && matches.length > 0 ? Number(matches[0]) : 1;
promises.push(
@@ -264,7 +264,7 @@ export class DatabaseRepository {
await sql`ALTER TABLE ${sql.raw(table)} ADD COLUMN embedding real[] NOT NULL`.execute(tx);
}
await sql`ALTER TABLE ${sql.raw(table)} ALTER COLUMN embedding SET DATA TYPE real[]`.execute(tx);
const schema = vectorExtension === DatabaseExtension.VECTORS ? 'vectors.' : '';
const schema = vectorExtension === DatabaseExtension.Vectors ? 'vectors.' : '';
await sql`
ALTER TABLE ${sql.raw(table)}
ALTER COLUMN embedding
@@ -329,11 +329,11 @@ export class DatabaseRepository {
.alterColumn('embedding', (col) => col.setDataType(sql.raw(`vector(${dimSize})`)))
.execute();
await sql
.raw(vectorIndexQuery({ vectorExtension, table: 'smart_search', indexName: VectorIndex.CLIP }))
.raw(vectorIndexQuery({ vectorExtension, table: 'smart_search', indexName: VectorIndex.Clip }))
.execute(trx);
await trx.schema.alterTable('smart_search').dropConstraint('dim_size_constraint').ifExists().execute();
});
probes[VectorIndex.CLIP] = 1;
probes[VectorIndex.Clip] = 1;
await sql`vacuum analyze ${sql.table('smart_search')}`.execute(this.db);
}

View File

@@ -34,7 +34,7 @@ export class DownloadRepository {
downloadUserId(userId: string) {
return builder(this.db)
.where('asset.ownerId', '=', userId)
.where('asset.visibility', '!=', AssetVisibility.HIDDEN)
.where('asset.visibility', '!=', AssetVisibility.Hidden)
.stream();
}
}

View File

@@ -109,14 +109,14 @@ export class DuplicateRepository {
assetId: DummyValue.UUID,
embedding: DummyValue.VECTOR,
maxDistance: 0.6,
type: AssetType.IMAGE,
type: AssetType.Image,
userIds: [DummyValue.UUID],
},
],
})
search({ assetId, embedding, maxDistance, type, userIds }: DuplicateSearch) {
return this.db.transaction().execute(async (trx) => {
await sql`set local vchordrq.probes = ${sql.lit(probes[VectorIndex.CLIP])}`.execute(trx);
await sql`set local vchordrq.probes = ${sql.lit(probes[VectorIndex.Clip])}`.execute(trx);
return await trx
.with('cte', (qb) =>
qb

View File

@@ -166,7 +166,7 @@ export class EventRepository implements OnGatewayConnection, OnGatewayDisconnect
continue;
}
const event = reflector.get<EventConfig>(MetadataKey.EVENT_CONFIG, handler);
const event = reflector.get<EventConfig>(MetadataKey.EventConfig, handler);
if (!event) {
continue;
}

View File

@@ -41,7 +41,7 @@ export class JobRepository {
const instance = this.moduleRef.get<any>(Service);
for (const methodName of getMethodNames(instance)) {
const handler = instance[methodName];
const config = reflector.get<JobConfig>(MetadataKey.JOB_CONFIG, handler);
const config = reflector.get<JobConfig>(MetadataKey.JobConfig, handler);
if (!config) {
continue;
}
@@ -99,7 +99,7 @@ export class JobRepository {
const item = this.handlers[name as JobName];
if (!item) {
this.logger.warn(`Skipping unknown job: "${name}"`);
return JobStatus.SKIPPED;
return JobStatus.Skipped;
}
return item.handler(data);
@@ -205,20 +205,20 @@ export class JobRepository {
private getJobOptions(item: JobItem): JobsOptions | null {
switch (item.name) {
case JobName.NOTIFY_ALBUM_UPDATE: {
case JobName.NotifyAlbumUpdate: {
return {
jobId: `${item.data.id}/${item.data.recipientId}`,
delay: item.data?.delay,
};
}
case JobName.STORAGE_TEMPLATE_MIGRATION_SINGLE: {
case JobName.StorageTemplateMigrationSingle: {
return { jobId: item.data.id };
}
case JobName.GENERATE_PERSON_THUMBNAIL: {
case JobName.GeneratePersonThumbnail: {
return { priority: 1 };
}
case JobName.QUEUE_FACIAL_RECOGNITION: {
return { jobId: JobName.QUEUE_FACIAL_RECOGNITION };
case JobName.QueueFacialRecognition: {
return { jobId: JobName.QueueFacialRecognition };
}
default: {
return null;

View File

@@ -79,7 +79,7 @@ export class LibraryRepository {
eb.fn
.countAll<number>()
.filterWhere((eb) =>
eb.and([eb('asset.type', '=', AssetType.IMAGE), eb('asset.visibility', '!=', AssetVisibility.HIDDEN)]),
eb.and([eb('asset.type', '=', AssetType.Image), eb('asset.visibility', '!=', AssetVisibility.Hidden)]),
)
.as('photos'),
)
@@ -87,7 +87,7 @@ export class LibraryRepository {
eb.fn
.countAll<number>()
.filterWhere((eb) =>
eb.and([eb('asset.type', '=', AssetType.VIDEO), eb('asset.visibility', '!=', AssetVisibility.HIDDEN)]),
eb.and([eb('asset.type', '=', AssetType.Video), eb('asset.visibility', '!=', AssetVisibility.Hidden)]),
)
.as('videos'),
)

View File

@@ -22,7 +22,7 @@ describe(LoggingRepository.name, () => {
describe('formatContext', () => {
it('should use colors', () => {
sut = new LoggingRepository(clsMock, configMock);
sut.setAppName(ImmichWorker.API);
sut.setAppName(ImmichWorker.Api);
const logger = new MyConsoleLogger(clsMock, { color: true });
@@ -31,7 +31,7 @@ describe(LoggingRepository.name, () => {
it('should not use colors when color is false', () => {
sut = new LoggingRepository(clsMock, configMock);
sut.setAppName(ImmichWorker.API);
sut.setAppName(ImmichWorker.Api);
const logger = new MyConsoleLogger(clsMock, { color: false });

View File

@@ -8,7 +8,7 @@ import { ConfigRepository } from 'src/repositories/config.repository';
type LogDetails = any;
type LogFunction = () => string;
const LOG_LEVELS = [LogLevel.VERBOSE, LogLevel.DEBUG, LogLevel.LOG, LogLevel.WARN, LogLevel.ERROR, LogLevel.FATAL];
const LOG_LEVELS = [LogLevel.Verbose, LogLevel.Debug, LogLevel.Log, LogLevel.Warn, LogLevel.Error, LogLevel.Fatal];
enum LogColor {
RED = 31,
@@ -20,7 +20,7 @@ enum LogColor {
}
let appName: string | undefined;
let logLevels: LogLevel[] = [LogLevel.LOG, LogLevel.WARN, LogLevel.ERROR, LogLevel.FATAL];
let logLevels: LogLevel[] = [LogLevel.Log, LogLevel.Warn, LogLevel.Error, LogLevel.Fatal];
export class MyConsoleLogger extends ConsoleLogger {
private isColorEnabled: boolean;
@@ -106,35 +106,35 @@ export class LoggingRepository {
}
verbose(message: string, ...details: LogDetails) {
this.handleMessage(LogLevel.VERBOSE, message, details);
this.handleMessage(LogLevel.Verbose, message, details);
}
verboseFn(message: LogFunction, ...details: LogDetails) {
this.handleFunction(LogLevel.VERBOSE, message, details);
this.handleFunction(LogLevel.Verbose, message, details);
}
debug(message: string, ...details: LogDetails) {
this.handleMessage(LogLevel.DEBUG, message, details);
this.handleMessage(LogLevel.Debug, message, details);
}
debugFn(message: LogFunction, ...details: LogDetails) {
this.handleFunction(LogLevel.DEBUG, message, details);
this.handleFunction(LogLevel.Debug, message, details);
}
log(message: string, ...details: LogDetails) {
this.handleMessage(LogLevel.LOG, message, details);
this.handleMessage(LogLevel.Log, message, details);
}
warn(message: string, ...details: LogDetails) {
this.handleMessage(LogLevel.WARN, message, details);
this.handleMessage(LogLevel.Warn, message, details);
}
error(message: string | Error, ...details: LogDetails) {
this.handleMessage(LogLevel.ERROR, message, details);
this.handleMessage(LogLevel.Error, message, details);
}
fatal(message: string, ...details: LogDetails) {
this.handleMessage(LogLevel.FATAL, message, details);
this.handleMessage(LogLevel.Fatal, message, details);
}
private handleFunction(level: LogLevel, message: LogFunction, details: LogDetails[]) {
@@ -145,32 +145,32 @@ export class LoggingRepository {
private handleMessage(level: LogLevel, message: string | Error, details: LogDetails[]) {
switch (level) {
case LogLevel.VERBOSE: {
case LogLevel.Verbose: {
this.logger.verbose(message, ...details);
break;
}
case LogLevel.DEBUG: {
case LogLevel.Debug: {
this.logger.debug(message, ...details);
break;
}
case LogLevel.LOG: {
case LogLevel.Log: {
this.logger.log(message, ...details);
break;
}
case LogLevel.WARN: {
case LogLevel.Warn: {
this.logger.warn(message, ...details);
break;
}
case LogLevel.ERROR: {
case LogLevel.Error: {
this.logger.error(message, ...details);
break;
}
case LogLevel.FATAL: {
case LogLevel.Fatal: {
this.logger.fatal(message, ...details);
break;
}

View File

@@ -61,14 +61,14 @@ export class MapRepository {
const geodataDate = await readFile(resourcePaths.geodata.dateFile, 'utf8');
// TODO move to service init
const geocodingMetadata = await this.metadataRepository.get(SystemMetadataKey.REVERSE_GEOCODING_STATE);
const geocodingMetadata = await this.metadataRepository.get(SystemMetadataKey.ReverseGeocodingState);
if (geocodingMetadata?.lastUpdate === geodataDate) {
return;
}
await Promise.all([this.importGeodata(), this.importNaturalEarthCountries()]);
await this.metadataRepository.set(SystemMetadataKey.REVERSE_GEOCODING_STATE, {
await this.metadataRepository.set(SystemMetadataKey.ReverseGeocodingState, {
lastUpdate: geodataDate,
lastImportFileName: citiesFile,
});
@@ -102,13 +102,13 @@ export class MapRepository {
.$if(isArchived === true, (qb) =>
qb.where((eb) =>
eb.or([
eb('asset.visibility', '=', AssetVisibility.TIMELINE),
eb('asset.visibility', '=', AssetVisibility.ARCHIVE),
eb('asset.visibility', '=', AssetVisibility.Timeline),
eb('asset.visibility', '=', AssetVisibility.Archive),
]),
),
)
.$if(isArchived === false || isArchived === undefined, (qb) =>
qb.where('asset.visibility', '=', AssetVisibility.TIMELINE),
qb.where('asset.visibility', '=', AssetVisibility.Timeline),
)
.$if(isFavorite !== undefined, (q) => q.where('isFavorite', '=', isFavorite!))
.$if(fileCreatedAfter !== undefined, (q) => q.where('fileCreatedAt', '>=', fileCreatedAfter!))

View File

@@ -55,28 +55,28 @@ export class MediaRepository {
async extract(input: string): Promise<ExtractResult | null> {
try {
const buffer = await exiftool.extractBinaryTagToBuffer('JpgFromRaw2', input);
return { buffer, format: RawExtractedFormat.JPEG };
return { buffer, format: RawExtractedFormat.Jpeg };
} catch (error: any) {
this.logger.debug('Could not extract JpgFromRaw2 buffer from image, trying JPEG from RAW next', error.message);
}
try {
const buffer = await exiftool.extractBinaryTagToBuffer('JpgFromRaw', input);
return { buffer, format: RawExtractedFormat.JPEG };
return { buffer, format: RawExtractedFormat.Jpeg };
} catch (error: any) {
this.logger.debug('Could not extract JPEG buffer from image, trying PreviewJXL next', error.message);
}
try {
const buffer = await exiftool.extractBinaryTagToBuffer('PreviewJXL', input);
return { buffer, format: RawExtractedFormat.JXL };
return { buffer, format: RawExtractedFormat.Jxl };
} catch (error: any) {
this.logger.debug('Could not extract PreviewJXL buffer from image, trying PreviewImage next', error.message);
}
try {
const buffer = await exiftool.extractBinaryTagToBuffer('PreviewImage', input);
return { buffer, format: RawExtractedFormat.JPEG };
return { buffer, format: RawExtractedFormat.Jpeg };
} catch (error: any) {
this.logger.debug('Could not extract preview buffer from image', error.message);
return null;
@@ -142,7 +142,7 @@ export class MediaRepository {
limitInputPixels: false,
raw: options.raw,
})
.pipelineColorspace(options.colorspace === Colorspace.SRGB ? 'srgb' : 'rgb16')
.pipelineColorspace(options.colorspace === Colorspace.Srgb ? 'srgb' : 'rgb16')
.withIccProfile(options.colorspace);
if (!options.raw) {
@@ -267,7 +267,7 @@ export class MediaRepository {
const { frameCount, percentInterval } = options.progress;
const frameInterval = Math.ceil(frameCount / (100 / percentInterval));
if (this.logger.isLevelEnabled(LogLevel.DEBUG) && frameCount && frameInterval) {
if (this.logger.isLevelEnabled(LogLevel.Debug) && frameCount && frameInterval) {
let lastProgressFrame: number = 0;
ffmpegCall.on('progress', (progress: ProgressEvent) => {
if (progress.frames - lastProgressFrame < frameInterval) {

View File

@@ -19,7 +19,7 @@ export class MemoryRepository implements IBulkAsset {
.deleteFrom('memory_asset')
.using('asset')
.whereRef('memory_asset.assetsId', '=', 'asset.id')
.where('asset.visibility', '!=', AssetVisibility.TIMELINE)
.where('asset.visibility', '!=', AssetVisibility.Timeline)
.execute();
return this.db
@@ -67,7 +67,7 @@ export class MemoryRepository implements IBulkAsset {
.innerJoin('memory_asset', 'asset.id', 'memory_asset.assetsId')
.whereRef('memory_asset.memoriesId', '=', 'memory.id')
.orderBy('asset.fileCreatedAt', 'asc')
.where('asset.visibility', '=', sql.lit(AssetVisibility.TIMELINE))
.where('asset.visibility', '=', sql.lit(AssetVisibility.Timeline))
.where('asset.deletedAt', 'is', null),
).as('assets'),
)
@@ -158,7 +158,7 @@ export class MemoryRepository implements IBulkAsset {
.innerJoin('memory_asset', 'asset.id', 'memory_asset.assetsId')
.whereRef('memory_asset.memoriesId', '=', 'memory.id')
.orderBy('asset.fileCreatedAt', 'asc')
.where('asset.visibility', '=', sql.lit(AssetVisibility.TIMELINE))
.where('asset.visibility', '=', sql.lit(AssetVisibility.Timeline))
.where('asset.deletedAt', 'is', null),
).as('assets'),
)

View File

@@ -48,7 +48,7 @@ export class MoveRepository {
eb.selectFrom('asset').select('id').whereRef('asset.id', '=', 'move_history.entityId'),
),
)
.where('move_history.pathType', '=', sql.lit(AssetPathType.ORIGINAL))
.where('move_history.pathType', '=', sql.lit(AssetPathType.Original))
.execute();
}
@@ -56,7 +56,7 @@ export class MoveRepository {
async cleanMoveHistorySingle(assetId: string): Promise<void> {
await this.db
.deleteFrom('move_history')
.where('move_history.pathType', '=', sql.lit(AssetPathType.ORIGINAL))
.where('move_history.pathType', '=', sql.lit(AssetPathType.Original))
.where('entityId', '=', assetId)
.execute();
}

View File

@@ -138,11 +138,11 @@ export class OAuthRepository {
}
switch (tokenEndpointAuthMethod) {
case OAuthTokenEndpointAuthMethod.CLIENT_SECRET_POST: {
case OAuthTokenEndpointAuthMethod.ClientSecretPost: {
return ClientSecretPost(clientSecret);
}
case OAuthTokenEndpointAuthMethod.CLIENT_SECRET_BASIC: {
case OAuthTokenEndpointAuthMethod.ClientSecretBasic: {
return ClientSecretBasic(clientSecret);
}

View File

@@ -151,7 +151,7 @@ export class PersonRepository {
.innerJoin('asset', (join) =>
join
.onRef('asset_face.assetId', '=', 'asset.id')
.on('asset.visibility', '=', sql.lit(AssetVisibility.TIMELINE))
.on('asset.visibility', '=', sql.lit(AssetVisibility.Timeline))
.on('asset.deletedAt', 'is', null),
)
.where('person.ownerId', '=', userId)
@@ -276,7 +276,7 @@ export class PersonRepository {
.selectFrom('asset_file')
.select('asset_file.path')
.whereRef('asset_file.assetId', '=', 'asset.id')
.where('asset_file.type', '=', sql.lit(AssetFileType.PREVIEW))
.where('asset_file.type', '=', sql.lit(AssetFileType.Preview))
.as('previewPath'),
)
.where('person.id', '=', id)
@@ -341,7 +341,7 @@ export class PersonRepository {
join
.onRef('asset.id', '=', 'asset_face.assetId')
.on('asset_face.personId', '=', personId)
.on('asset.visibility', '=', sql.lit(AssetVisibility.TIMELINE))
.on('asset.visibility', '=', sql.lit(AssetVisibility.Timeline))
.on('asset.deletedAt', 'is', null),
)
.select((eb) => eb.fn.count(eb.fn('distinct', ['asset.id'])).as('count'))
@@ -369,7 +369,7 @@ export class PersonRepository {
eb
.selectFrom('asset')
.whereRef('asset.id', '=', 'asset_face.assetId')
.where('asset.visibility', '=', sql.lit(AssetVisibility.TIMELINE))
.where('asset.visibility', '=', sql.lit(AssetVisibility.Timeline))
.where('asset.deletedAt', 'is', null),
),
),

View File

@@ -256,7 +256,7 @@ export class SearchRepository {
}
return this.db.transaction().execute(async (trx) => {
await sql`set local vchordrq.probes = ${sql.lit(probes[VectorIndex.CLIP])}`.execute(trx);
await sql`set local vchordrq.probes = ${sql.lit(probes[VectorIndex.Clip])}`.execute(trx);
const items = await searchAssetBuilder(trx, options)
.selectAll('asset')
.innerJoin('smart_search', 'asset.id', 'smart_search.assetId')
@@ -284,7 +284,7 @@ export class SearchRepository {
}
return this.db.transaction().execute(async (trx) => {
await sql`set local vchordrq.probes = ${sql.lit(probes[VectorIndex.FACE])}`.execute(trx);
await sql`set local vchordrq.probes = ${sql.lit(probes[VectorIndex.Face])}`.execute(trx);
return await trx
.with('cte', (qb) =>
qb
@@ -351,8 +351,8 @@ export class SearchRepository {
.select(['city', 'assetId'])
.innerJoin('asset', 'asset.id', 'asset_exif.assetId')
.where('asset.ownerId', '=', anyUuid(userIds))
.where('asset.visibility', '=', AssetVisibility.TIMELINE)
.where('asset.type', '=', AssetType.IMAGE)
.where('asset.visibility', '=', AssetVisibility.Timeline)
.where('asset.type', '=', AssetType.Image)
.where('asset.deletedAt', 'is', null)
.orderBy('city')
.limit(1);
@@ -367,8 +367,8 @@ export class SearchRepository {
.select(['city', 'assetId'])
.innerJoin('asset', 'asset.id', 'asset_exif.assetId')
.where('asset.ownerId', '=', anyUuid(userIds))
.where('asset.visibility', '=', AssetVisibility.TIMELINE)
.where('asset.type', '=', AssetType.IMAGE)
.where('asset.visibility', '=', AssetVisibility.Timeline)
.where('asset.type', '=', AssetType.Image)
.where('asset.deletedAt', 'is', null)
.whereRef('asset_exif.city', '>', 'cte.city')
.orderBy('city')
@@ -450,7 +450,7 @@ export class SearchRepository {
.distinctOn(field)
.innerJoin('asset', 'asset.id', 'asset_exif.assetId')
.where('ownerId', '=', anyUuid(userIds))
.where('visibility', '=', AssetVisibility.TIMELINE)
.where('visibility', '=', AssetVisibility.Timeline)
.where('deletedAt', 'is', null)
.where(field, 'is not', null);
}

View File

@@ -103,7 +103,7 @@ export class SharedLinkRepository {
.select((eb) => eb.fn.toJson('album').$castTo<Album | null>().as('album'))
.where('shared_link.id', '=', id)
.where('shared_link.userId', '=', userId)
.where((eb) => eb.or([eb('shared_link.type', '=', SharedLinkType.INDIVIDUAL), eb('album.id', 'is not', null)]))
.where((eb) => eb.or([eb('shared_link.type', '=', SharedLinkType.Individual), eb('album.id', 'is not', null)]))
.orderBy('shared_link.createdAt', 'desc')
.executeTakeFirst();
}
@@ -165,7 +165,7 @@ export class SharedLinkRepository {
(join) => join.onTrue(),
)
.select((eb) => eb.fn.toJson('album').$castTo<Album | null>().as('album'))
.where((eb) => eb.or([eb('shared_link.type', '=', SharedLinkType.INDIVIDUAL), eb('album.id', 'is not', null)]))
.where((eb) => eb.or([eb('shared_link.type', '=', SharedLinkType.Individual), eb('album.id', 'is not', null)]))
.$if(!!albumId, (eb) => eb.where('shared_link.albumId', '=', albumId!))
.orderBy('shared_link.createdAt', 'desc')
.distinctOn(['shared_link.createdAt'])
@@ -185,7 +185,7 @@ export class SharedLinkRepository {
eb.selectFrom('user').select(columns.authUser).whereRef('user.id', '=', 'shared_link.userId'),
).as('user'),
])
.where((eb) => eb.or([eb('shared_link.type', '=', SharedLinkType.INDIVIDUAL), eb('album.id', 'is not', null)]))
.where((eb) => eb.or([eb('shared_link.type', '=', SharedLinkType.Individual), eb('album.id', 'is not', null)]))
.executeTakeFirst();
}

View File

@@ -112,21 +112,21 @@ export class TelemetryRepository {
const { telemetry } = this.configRepository.getEnv();
const { metrics } = telemetry;
this.api = new MetricGroupRepository(metricService).configure({ enabled: metrics.has(ImmichTelemetry.API) });
this.host = new MetricGroupRepository(metricService).configure({ enabled: metrics.has(ImmichTelemetry.HOST) });
this.jobs = new MetricGroupRepository(metricService).configure({ enabled: metrics.has(ImmichTelemetry.JOB) });
this.repo = new MetricGroupRepository(metricService).configure({ enabled: metrics.has(ImmichTelemetry.REPO) });
this.api = new MetricGroupRepository(metricService).configure({ enabled: metrics.has(ImmichTelemetry.Api) });
this.host = new MetricGroupRepository(metricService).configure({ enabled: metrics.has(ImmichTelemetry.Host) });
this.jobs = new MetricGroupRepository(metricService).configure({ enabled: metrics.has(ImmichTelemetry.Job) });
this.repo = new MetricGroupRepository(metricService).configure({ enabled: metrics.has(ImmichTelemetry.Repo) });
}
setup({ repositories }: { repositories: ClassConstructor<unknown>[] }) {
const { telemetry } = this.configRepository.getEnv();
const { metrics } = telemetry;
if (!metrics.has(ImmichTelemetry.REPO)) {
if (!metrics.has(ImmichTelemetry.Repo)) {
return;
}
for (const Repository of repositories) {
const isEnabled = this.reflect.get(MetadataKey.TELEMETRY_ENABLED, Repository) ?? true;
const isEnabled = this.reflect.get(MetadataKey.TelemetryEnabled, Repository) ?? true;
if (!isEnabled) {
this.logger.debug(`Telemetry disabled for ${Repository.name}`);
continue;

View File

@@ -8,7 +8,7 @@ export class TrashRepository {
constructor(@InjectKysely() private db: Kysely<DB>) {}
getDeletedIds(): AsyncIterableIterator<{ id: string }> {
return this.db.selectFrom('asset').select(['id']).where('status', '=', AssetStatus.DELETED).stream();
return this.db.selectFrom('asset').select(['id']).where('status', '=', AssetStatus.Deleted).stream();
}
@GenerateSql({ params: [DummyValue.UUID] })
@@ -16,8 +16,8 @@ export class TrashRepository {
const { numUpdatedRows } = await this.db
.updateTable('asset')
.where('ownerId', '=', userId)
.where('status', '=', AssetStatus.TRASHED)
.set({ status: AssetStatus.ACTIVE, deletedAt: null })
.where('status', '=', AssetStatus.Trashed)
.set({ status: AssetStatus.Active, deletedAt: null })
.executeTakeFirst();
return Number(numUpdatedRows);
@@ -28,8 +28,8 @@ export class TrashRepository {
const { numUpdatedRows } = await this.db
.updateTable('asset')
.where('ownerId', '=', userId)
.where('status', '=', AssetStatus.TRASHED)
.set({ status: AssetStatus.DELETED })
.where('status', '=', AssetStatus.Trashed)
.set({ status: AssetStatus.Deleted })
.executeTakeFirst();
return Number(numUpdatedRows);
@@ -43,9 +43,9 @@ export class TrashRepository {
const { numUpdatedRows } = await this.db
.updateTable('asset')
.where('status', '=', AssetStatus.TRASHED)
.where('status', '=', AssetStatus.Trashed)
.where('id', 'in', ids)
.set({ status: AssetStatus.ACTIVE, deletedAt: null })
.set({ status: AssetStatus.Active, deletedAt: null })
.executeTakeFirst();
return Number(numUpdatedRows);

View File

@@ -187,7 +187,7 @@ export class UserRepository {
restore(id: string) {
return this.db
.updateTable('user')
.set({ status: UserStatus.ACTIVE, deletedAt: null })
.set({ status: UserStatus.Active, deletedAt: null })
.where('user.id', '=', asUuid(id))
.returning(columns.userAdmin)
.returning(withMetadata)
@@ -229,8 +229,8 @@ export class UserRepository {
.countAll<number>()
.filterWhere((eb) =>
eb.and([
eb('asset.type', '=', sql.lit(AssetType.IMAGE)),
eb('asset.visibility', '!=', sql.lit(AssetVisibility.HIDDEN)),
eb('asset.type', '=', sql.lit(AssetType.Image)),
eb('asset.visibility', '!=', sql.lit(AssetVisibility.Hidden)),
]),
)
.as('photos'),
@@ -238,8 +238,8 @@ export class UserRepository {
.countAll<number>()
.filterWhere((eb) =>
eb.and([
eb('asset.type', '=', sql.lit(AssetType.VIDEO)),
eb('asset.visibility', '!=', sql.lit(AssetVisibility.HIDDEN)),
eb('asset.type', '=', sql.lit(AssetType.Video)),
eb('asset.visibility', '!=', sql.lit(AssetVisibility.Hidden)),
]),
)
.as('videos'),
@@ -254,7 +254,7 @@ export class UserRepository {
eb.fn
.sum<number>('asset_exif.fileSizeInByte')
.filterWhere((eb) =>
eb.and([eb('asset.libraryId', 'is', null), eb('asset.type', '=', sql.lit(AssetType.IMAGE))]),
eb.and([eb('asset.libraryId', 'is', null), eb('asset.type', '=', sql.lit(AssetType.Image))]),
),
eb.lit(0),
)
@@ -264,7 +264,7 @@ export class UserRepository {
eb.fn
.sum<number>('asset_exif.fileSizeInByte')
.filterWhere((eb) =>
eb.and([eb('asset.libraryId', 'is', null), eb('asset.type', '=', sql.lit(AssetType.VIDEO))]),
eb.and([eb('asset.libraryId', 'is', null), eb('asset.type', '=', sql.lit(AssetType.Video))]),
),
eb.lit(0),
)

View File

@@ -15,7 +15,7 @@ export class ViewRepository {
.select((eb) => eb.fn<string>('substring', ['asset.originalPath', eb.val('^(.*/)[^/]*$')]).as('directoryPath'))
.distinct()
.where('ownerId', '=', asUuid(userId))
.where('visibility', '=', AssetVisibility.TIMELINE)
.where('visibility', '=', AssetVisibility.Timeline)
.where('deletedAt', 'is', null)
.where('fileCreatedAt', 'is not', null)
.where('fileModifiedAt', 'is not', null)
@@ -34,7 +34,7 @@ export class ViewRepository {
.selectAll('asset')
.$call(withExif)
.where('ownerId', '=', asUuid(userId))
.where('visibility', '=', AssetVisibility.TIMELINE)
.where('visibility', '=', AssetVisibility.Timeline)
.where('deletedAt', 'is', null)
.where('fileCreatedAt', 'is not', null)
.where('fileModifiedAt', 'is not', null)