mirror of
https://github.com/immich-app/immich.git
synced 2024-12-29 15:11:58 +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:
parent
0fda67543d
commit
5e9a7b17d9
9 changed files with 22 additions and 8 deletions
|
@ -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) {
|
||||
|
|
BIN
mobile/openapi/lib/model/metadata_search_dto.dart
generated
BIN
mobile/openapi/lib/model/metadata_search_dto.dart
generated
Binary file not shown.
BIN
mobile/openapi/lib/model/smart_search_dto.dart
generated
BIN
mobile/openapi/lib/model/smart_search_dto.dart
generated
Binary file not shown.
|
@ -9026,6 +9026,7 @@
|
|||
},
|
||||
"libraryId": {
|
||||
"format": "uuid",
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
},
|
||||
"make": {
|
||||
|
@ -10140,6 +10141,7 @@
|
|||
},
|
||||
"libraryId": {
|
||||
"format": "uuid",
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
},
|
||||
"make": {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -45,7 +45,7 @@ export interface SearchAssetIDOptions {
|
|||
|
||||
export interface SearchUserIdOptions {
|
||||
deviceId?: string;
|
||||
libraryId?: string;
|
||||
libraryId?: string | null;
|
||||
userIds?: string[];
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(),
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue