1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2024-12-28 22:51:59 +00:00

fix(server): allow library id to be null in metadata search (#10512)

* fix: allow library id to be null in metadata search

* chore: open api
This commit is contained in:
Daniel Dietzler 2024-06-21 01:02:05 +02:00 committed by GitHub
parent 0fda67543d
commit 5e9a7b17d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 22 additions and 8 deletions

View file

@ -339,6 +339,13 @@ describe('/search', () => {
should: 'should search by model',
deferred: () => ({ dto: { model: 'Canon EOS 7D' }, assets: [assetDenali] }),
},
{
should: 'should allow searching the upload library (libraryId: null)',
deferred: () => ({
dto: { libraryId: null, size: 1 },
assets: [assetLast],
}),
},
];
for (const { should, deferred } of searchTests) {

Binary file not shown.

Binary file not shown.

View file

@ -9026,6 +9026,7 @@
},
"libraryId": {
"format": "uuid",
"nullable": true,
"type": "string"
},
"make": {
@ -10140,6 +10141,7 @@
},
"libraryId": {
"format": "uuid",
"nullable": true,
"type": "string"
},
"make": {

View file

@ -697,7 +697,7 @@ export type MetadataSearchDto = {
isOffline?: boolean;
isVisible?: boolean;
lensModel?: string;
libraryId?: string;
libraryId?: string | null;
make?: string;
model?: string;
order?: AssetOrder;
@ -768,7 +768,7 @@ export type SmartSearchDto = {
isOffline?: boolean;
isVisible?: boolean;
lensModel?: string;
libraryId?: string;
libraryId?: string | null;
make?: string;
model?: string;
page?: number;

View file

@ -9,8 +9,8 @@ import { GeodataPlacesEntity } from 'src/entities/geodata-places.entity';
import { Optional, ValidateBoolean, ValidateDate, ValidateUUID } from 'src/validation';
class BaseSearchDto {
@ValidateUUID({ optional: true })
libraryId?: string;
@ValidateUUID({ optional: true, nullable: true })
libraryId?: string | null;
@IsString()
@IsNotEmpty()

View file

@ -45,7 +45,7 @@ export interface SearchAssetIDOptions {
export interface SearchUserIdOptions {
deviceId?: string;
libraryId?: string;
libraryId?: string | null;
userIds?: string[];
}

View file

@ -52,6 +52,11 @@ export function searchAssetBuilder(
}
const id = _.pick(options, ['checksum', 'deviceAssetId', 'deviceId', 'id', 'libraryId']);
if (id.libraryId === null) {
id.libraryId = IsNull() as unknown as string;
}
builder.andWhere(_.omitBy(id, _.isUndefined));
if (options.userIds) {

View file

@ -80,13 +80,13 @@ export function Optional({ nullable, ...validationOptions }: OptionalOptions = {
return ValidateIf((object: any, v: any) => v !== undefined, validationOptions);
}
type UUIDOptions = { optional?: boolean; each?: boolean };
type UUIDOptions = { optional?: boolean; each?: boolean; nullable?: boolean };
export const ValidateUUID = (options?: UUIDOptions) => {
const { optional, each } = { optional: false, each: false, ...options };
const { optional, each, nullable } = { optional: false, each: false, nullable: false, ...options };
return applyDecorators(
IsUUID('4', { each }),
ApiProperty({ format: 'uuid' }),
optional ? Optional() : IsNotEmpty(),
optional ? Optional({ nullable }) : IsNotEmpty(),
each ? IsArray() : IsString(),
);
};