1
0
mirror of https://github.com/immich-app/immich.git synced 2024-11-24 08:52:28 +02: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', should: 'should search by model',
deferred: () => ({ dto: { model: 'Canon EOS 7D' }, assets: [assetDenali] }), 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) { for (const { should, deferred } of searchTests) {

Binary file not shown.

Binary file not shown.

View File

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

View File

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

View File

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

View File

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

View File

@ -52,6 +52,11 @@ export function searchAssetBuilder(
} }
const id = _.pick(options, ['checksum', 'deviceAssetId', 'deviceId', 'id', 'libraryId']); 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)); builder.andWhere(_.omitBy(id, _.isUndefined));
if (options.userIds) { if (options.userIds) {

View File

@ -80,13 +80,13 @@ export function Optional({ nullable, ...validationOptions }: OptionalOptions = {
return ValidateIf((object: any, v: any) => v !== undefined, validationOptions); 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) => { 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( return applyDecorators(
IsUUID('4', { each }), IsUUID('4', { each }),
ApiProperty({ format: 'uuid' }), ApiProperty({ format: 'uuid' }),
optional ? Optional() : IsNotEmpty(), optional ? Optional({ nullable }) : IsNotEmpty(),
each ? IsArray() : IsString(), each ? IsArray() : IsString(),
); );
}; };