Skip to content

Commit

Permalink
fix(server): allow library id to be null in metadata search (#10512)
Browse files Browse the repository at this point in the history
* fix: allow library id to be null in metadata search

* chore: open api
  • Loading branch information
danieldietzler authored Jun 20, 2024
1 parent 0fda675 commit 5e9a7b1
Show file tree
Hide file tree
Showing 9 changed files with 22 additions and 20 deletions.
7 changes: 7 additions & 0 deletions e2e/src/api/specs/search.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
6 changes: 0 additions & 6 deletions mobile/openapi/lib/model/metadata_search_dto.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 0 additions & 6 deletions mobile/openapi/lib/model/smart_search_dto.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions open-api/immich-openapi-specs.json
Original file line number Diff line number Diff line change
Expand Up @@ -9026,6 +9026,7 @@
},
"libraryId": {
"format": "uuid",
"nullable": true,
"type": "string"
},
"make": {
Expand Down Expand Up @@ -10140,6 +10141,7 @@
},
"libraryId": {
"format": "uuid",
"nullable": true,
"type": "string"
},
"make": {
Expand Down
4 changes: 2 additions & 2 deletions open-api/typescript-sdk/src/fetch-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ export type MetadataSearchDto = {
isOffline?: boolean;
isVisible?: boolean;
lensModel?: string;
libraryId?: string;
libraryId?: string | null;
make?: string;
model?: string;
order?: AssetOrder;
Expand Down Expand Up @@ -768,7 +768,7 @@ export type SmartSearchDto = {
isOffline?: boolean;
isVisible?: boolean;
lensModel?: string;
libraryId?: string;
libraryId?: string | null;
make?: string;
model?: string;
page?: number;
Expand Down
4 changes: 2 additions & 2 deletions server/src/dtos/search.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion server/src/interfaces/search.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export interface SearchAssetIDOptions {

export interface SearchUserIdOptions {
deviceId?: string;
libraryId?: string;
libraryId?: string | null;
userIds?: string[];
}

Expand Down
5 changes: 5 additions & 0 deletions server/src/utils/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
6 changes: 3 additions & 3 deletions server/src/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
);
};
Expand Down

0 comments on commit 5e9a7b1

Please sign in to comment.