immich/server/src/dtos/sync.dto.ts
2025-05-21 14:35:32 -05:00

198 lines
4.8 KiB
TypeScript

import { ApiProperty } from '@nestjs/swagger';
import { IsEnum, IsInt, IsPositive, IsString } from 'class-validator';
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
import { AlbumUserRole, AssetOrder, AssetType, AssetVisibility, SyncEntityType, SyncRequestType } from 'src/enum';
import { Optional, ValidateDate, ValidateUUID } from 'src/validation';
export class AssetFullSyncDto {
@ValidateUUID({ optional: true })
lastId?: string;
@ValidateDate()
updatedUntil!: Date;
@IsInt()
@IsPositive()
@ApiProperty({ type: 'integer' })
limit!: number;
@ValidateUUID({ optional: true })
userId?: string;
}
export class AssetDeltaSyncDto {
@ValidateDate()
updatedAfter!: Date;
@ValidateUUID({ each: true })
userIds!: string[];
}
export class AssetDeltaSyncResponseDto {
needsFullSync!: boolean;
upserted!: AssetResponseDto[];
deleted!: string[];
}
export class SyncUserV1 {
id!: string;
name!: string;
email!: string;
deletedAt!: Date | null;
}
export class SyncUserDeleteV1 {
userId!: string;
}
export class SyncPartnerV1 {
sharedById!: string;
sharedWithId!: string;
inTimeline!: boolean;
}
export class SyncPartnerDeleteV1 {
sharedById!: string;
sharedWithId!: string;
}
export class SyncAssetV1 {
id!: string;
ownerId!: string;
thumbhash!: string | null;
checksum!: string;
fileCreatedAt!: Date | null;
fileModifiedAt!: Date | null;
localDateTime!: Date | null;
type!: AssetType;
deletedAt!: Date | null;
isFavorite!: boolean;
visibility!: AssetVisibility;
}
export class SyncAssetDeleteV1 {
assetId!: string;
}
export class SyncAssetExifV1 {
assetId!: string;
description!: string | null;
@ApiProperty({ type: 'integer' })
exifImageWidth!: number | null;
@ApiProperty({ type: 'integer' })
exifImageHeight!: number | null;
@ApiProperty({ type: 'integer' })
fileSizeInByte!: number | null;
orientation!: string | null;
dateTimeOriginal!: Date | null;
modifyDate!: Date | null;
timeZone!: string | null;
@ApiProperty({ type: 'integer' })
latitude!: number | null;
@ApiProperty({ type: 'integer' })
longitude!: number | null;
projectionType!: string | null;
city!: string | null;
state!: string | null;
country!: string | null;
make!: string | null;
model!: string | null;
lensModel!: string | null;
@ApiProperty({ type: 'integer' })
fNumber!: number | null;
@ApiProperty({ type: 'integer' })
focalLength!: number | null;
@ApiProperty({ type: 'integer' })
iso!: number | null;
exposureTime!: string | null;
profileDescription!: string | null;
@ApiProperty({ type: 'integer' })
rating!: number | null;
@ApiProperty({ type: 'integer' })
fps!: number | null;
}
export class SyncAlbumDeleteV1 {
albumId!: string;
}
export class SyncAlbumUserDeleteV1 {
albumId!: string;
userId!: string;
}
export class SyncAlbumUserV1 {
albumId!: string;
userId!: string;
role!: AlbumUserRole;
}
export class SyncAlbumV1 {
id!: string;
ownerId!: string;
name!: string;
description!: string;
createdAt!: Date;
updatedAt!: Date;
thumbnailAssetId!: string | null;
isActivityEnabled!: boolean;
@ApiProperty({ enumName: 'AssetOrder', enum: AssetOrder })
order!: AssetOrder;
}
export type SyncItem = {
[SyncEntityType.UserV1]: SyncUserV1;
[SyncEntityType.UserDeleteV1]: SyncUserDeleteV1;
[SyncEntityType.PartnerV1]: SyncPartnerV1;
[SyncEntityType.PartnerDeleteV1]: SyncPartnerDeleteV1;
[SyncEntityType.AssetV1]: SyncAssetV1;
[SyncEntityType.AssetDeleteV1]: SyncAssetDeleteV1;
[SyncEntityType.AssetExifV1]: SyncAssetExifV1;
[SyncEntityType.PartnerAssetV1]: SyncAssetV1;
[SyncEntityType.PartnerAssetDeleteV1]: SyncAssetDeleteV1;
[SyncEntityType.PartnerAssetExifV1]: SyncAssetExifV1;
[SyncEntityType.AlbumV1]: SyncAlbumV1;
[SyncEntityType.AlbumDeleteV1]: SyncAlbumDeleteV1;
[SyncEntityType.AlbumUserV1]: SyncAlbumUserV1;
[SyncEntityType.AlbumUserDeleteV1]: SyncAlbumUserDeleteV1;
};
const responseDtos = [
SyncUserV1,
SyncUserDeleteV1,
SyncPartnerV1,
SyncPartnerDeleteV1,
SyncAssetV1,
SyncAssetDeleteV1,
SyncAssetExifV1,
SyncAlbumV1,
SyncAlbumDeleteV1,
SyncAlbumUserV1,
SyncAlbumUserDeleteV1,
];
export const extraSyncModels = responseDtos;
export class SyncStreamDto {
@IsEnum(SyncRequestType, { each: true })
@ApiProperty({ enumName: 'SyncRequestType', enum: SyncRequestType, isArray: true })
types!: SyncRequestType[];
}
export class SyncAckDto {
@ApiProperty({ enumName: 'SyncEntityType', enum: SyncEntityType })
type!: SyncEntityType;
ack!: string;
}
export class SyncAckSetDto {
@IsString({ each: true })
acks!: string[];
}
export class SyncAckDeleteDto {
@IsEnum(SyncEntityType, { each: true })
@ApiProperty({ enumName: 'SyncEntityType', enum: SyncEntityType, isArray: true })
@Optional()
types?: SyncEntityType[];
}