mirror of
https://github.com/immich-app/immich.git
synced 2024-12-28 22:51:59 +00:00
refactor: api validators (boolean and date) (#7709)
* refactor: api validators (boolean and date) * chore: open api * revert: time bucket change
This commit is contained in:
parent
753842745d
commit
a50f125dd1
41 changed files with 243 additions and 355 deletions
|
@ -66,8 +66,8 @@ class Asset {
|
|||
assetData: new File([await fs.openAsBlob(this.path)], basename(this.path)),
|
||||
deviceAssetId: this.deviceAssetId,
|
||||
deviceId: 'CLI',
|
||||
fileCreatedAt: this.fileCreatedAt,
|
||||
fileModifiedAt: this.fileModifiedAt,
|
||||
fileCreatedAt: this.fileCreatedAt.toISOString(),
|
||||
fileModifiedAt: this.fileModifiedAt.toISOString(),
|
||||
isFavorite: String(false),
|
||||
};
|
||||
const formData = new FormData();
|
||||
|
|
|
@ -6,10 +6,9 @@ import request from 'supertest';
|
|||
import { beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
const invalidBirthday = [
|
||||
// TODO: enable after replacing `@Type(() => Date)`
|
||||
// { birthDate: 'false', response: 'Invalid date' },
|
||||
// { birthDate: '123567', response: 'Invalid date },
|
||||
// { birthDate: 123_567, response: ['Birth date cannot be in the future'] },
|
||||
{ birthDate: 'false', response: 'birthDate must be a date string' },
|
||||
{ birthDate: '123567', response: 'birthDate must be a date string' },
|
||||
{ birthDate: 123_567, response: 'birthDate must be a date string' },
|
||||
{ birthDate: new Date(9999, 0, 0).toISOString(), response: ['Birth date cannot be in the future'] },
|
||||
];
|
||||
|
||||
|
@ -152,16 +151,16 @@ describe('/person', () => {
|
|||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should not accept invalid birth dates', async () => {
|
||||
for (const { birthDate, response } of invalidBirthday) {
|
||||
for (const { birthDate, response } of invalidBirthday) {
|
||||
it(`should not accept an invalid birth date [${birthDate}]`, async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post(`/person`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ birthDate });
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest(response));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
it('should create a person', async () => {
|
||||
const { status, body } = await request(app)
|
||||
|
@ -202,16 +201,16 @@ describe('/person', () => {
|
|||
});
|
||||
}
|
||||
|
||||
it('should not accept invalid birth dates', async () => {
|
||||
for (const { birthDate, response } of invalidBirthday) {
|
||||
for (const { birthDate, response } of invalidBirthday) {
|
||||
it(`should not accept an invalid birth date [${birthDate}]`, async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/person/${visiblePerson.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ birthDate });
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest(response));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
it('should update a date of birth', async () => {
|
||||
const { status, body } = await request(app)
|
||||
|
|
BIN
mobile/openapi/doc/PersonApi.md
generated
BIN
mobile/openapi/doc/PersonApi.md
generated
Binary file not shown.
BIN
mobile/openapi/doc/ScanLibraryDto.md
generated
BIN
mobile/openapi/doc/ScanLibraryDto.md
generated
Binary file not shown.
BIN
mobile/openapi/doc/SharedLinkCreateDto.md
generated
BIN
mobile/openapi/doc/SharedLinkCreateDto.md
generated
Binary file not shown.
BIN
mobile/openapi/lib/model/scan_library_dto.dart
generated
BIN
mobile/openapi/lib/model/scan_library_dto.dart
generated
Binary file not shown.
BIN
mobile/openapi/lib/model/shared_link_create_dto.dart
generated
BIN
mobile/openapi/lib/model/shared_link_create_dto.dart
generated
Binary file not shown.
BIN
mobile/openapi/test/scan_library_dto_test.dart
generated
BIN
mobile/openapi/test/scan_library_dto_test.dart
generated
Binary file not shown.
BIN
mobile/openapi/test/shared_link_create_dto_test.dart
generated
BIN
mobile/openapi/test/shared_link_create_dto_test.dart
generated
Binary file not shown.
|
@ -4012,7 +4012,6 @@
|
|||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
|
@ -8937,7 +8936,6 @@
|
|||
"ScanLibraryDto": {
|
||||
"properties": {
|
||||
"refreshAllFiles": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"refreshModifiedFiles": {
|
||||
|
@ -9346,7 +9344,6 @@
|
|||
"type": "boolean"
|
||||
},
|
||||
"allowUpload": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"assetIds": {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { IsBoolean, IsString } from 'class-validator';
|
||||
import { Optional, ValidateUUID } from '../../domain.util';
|
||||
import { IsString } from 'class-validator';
|
||||
import { Optional, ValidateBoolean, ValidateUUID } from '../../domain.util';
|
||||
|
||||
export class UpdateAlbumDto {
|
||||
@Optional()
|
||||
|
@ -13,7 +13,6 @@ export class UpdateAlbumDto {
|
|||
@ValidateUUID({ optional: true })
|
||||
albumThumbnailAssetId?: string;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
isActivityEnabled?: boolean;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
import { Transform } from 'class-transformer';
|
||||
import { IsBoolean } from 'class-validator';
|
||||
import { Optional, toBoolean } from '../../domain.util';
|
||||
import { ValidateBoolean } from '../../domain.util';
|
||||
|
||||
export class AlbumInfoDto {
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
withoutAssets?: boolean;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Transform } from 'class-transformer';
|
||||
import { IsBoolean } from 'class-validator';
|
||||
import { Optional, toBoolean, ValidateUUID } from '../../domain.util';
|
||||
import { ValidateBoolean, ValidateUUID } from '../../domain.util';
|
||||
|
||||
export class GetAlbumsDto {
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ApiProperty()
|
||||
@ValidateBoolean({ optional: true })
|
||||
/**
|
||||
* true: only shared albums
|
||||
* false: only non-shared own albums
|
||||
|
|
|
@ -1,24 +1,16 @@
|
|||
import { AssetType } from '@app/infra/entities';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Transform } from 'class-transformer';
|
||||
import { IsBoolean } from 'class-validator';
|
||||
import { Optional, toBoolean } from '../../domain.util';
|
||||
import { ValidateBoolean } from '../../domain.util';
|
||||
import { AssetStats } from '../../repositories';
|
||||
|
||||
export class AssetStatsDto {
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@Optional()
|
||||
@ValidateBoolean({ optional: true })
|
||||
isArchived?: boolean;
|
||||
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@Optional()
|
||||
@ValidateBoolean({ optional: true })
|
||||
isFavorite?: boolean;
|
||||
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@Optional()
|
||||
@ValidateBoolean({ optional: true })
|
||||
isTrashed?: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { Type } from 'class-transformer';
|
||||
import {
|
||||
IsBoolean,
|
||||
IsDateString,
|
||||
IsInt,
|
||||
IsLatitude,
|
||||
|
@ -10,7 +9,7 @@ import {
|
|||
IsString,
|
||||
ValidateIf,
|
||||
} from 'class-validator';
|
||||
import { Optional, ValidateUUID } from '../../domain.util';
|
||||
import { Optional, ValidateBoolean, ValidateUUID } from '../../domain.util';
|
||||
import { BulkIdsDto } from '../response-dto';
|
||||
|
||||
export class DeviceIdDto {
|
||||
|
@ -28,23 +27,13 @@ const hasGPS = (o: { latitude: undefined; longitude: undefined }) =>
|
|||
o.latitude !== undefined || o.longitude !== undefined;
|
||||
const ValidateGPS = () => ValidateIf(hasGPS);
|
||||
|
||||
export class AssetBulkUpdateDto extends BulkIdsDto {
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
export class UpdateAssetBase {
|
||||
@ValidateBoolean({ optional: true })
|
||||
isFavorite?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
isArchived?: boolean;
|
||||
|
||||
@Optional()
|
||||
@ValidateUUID()
|
||||
stackParentId?: string;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
removeParent?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsDateString()
|
||||
dateTimeOriginal?: string;
|
||||
|
@ -60,32 +49,21 @@ export class AssetBulkUpdateDto extends BulkIdsDto {
|
|||
longitude?: number;
|
||||
}
|
||||
|
||||
export class UpdateAssetDto {
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
isFavorite?: boolean;
|
||||
export class AssetBulkUpdateDto extends UpdateAssetBase {
|
||||
@ValidateUUID({ each: true })
|
||||
ids!: string[];
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
isArchived?: boolean;
|
||||
@ValidateUUID({ optional: true })
|
||||
stackParentId?: string;
|
||||
|
||||
@ValidateBoolean({ optional: true })
|
||||
removeParent?: boolean;
|
||||
}
|
||||
|
||||
export class UpdateAssetDto extends UpdateAssetBase {
|
||||
@Optional()
|
||||
@IsString()
|
||||
description?: string;
|
||||
|
||||
@Optional()
|
||||
@IsDateString()
|
||||
dateTimeOriginal?: string;
|
||||
|
||||
@ValidateGPS()
|
||||
@IsLatitude()
|
||||
@IsNotEmpty()
|
||||
latitude?: number;
|
||||
|
||||
@ValidateGPS()
|
||||
@IsLongitude()
|
||||
@IsNotEmpty()
|
||||
longitude?: number;
|
||||
}
|
||||
|
||||
export class RandomAssetsDto {
|
||||
|
@ -97,7 +75,6 @@ export class RandomAssetsDto {
|
|||
}
|
||||
|
||||
export class AssetBulkDeleteDto extends BulkIdsDto {
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
force?: boolean;
|
||||
}
|
||||
|
|
|
@ -1,34 +1,18 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Transform, Type } from 'class-transformer';
|
||||
import { IsBoolean, IsDate } from 'class-validator';
|
||||
import { Optional, toBoolean } from '../../domain.util';
|
||||
import { ValidateBoolean, ValidateDate } from '../../domain.util';
|
||||
|
||||
export class MapMarkerDto {
|
||||
@ApiProperty()
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
isArchived?: boolean;
|
||||
|
||||
@ApiProperty()
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
isFavorite?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsDate()
|
||||
@Type(() => Date)
|
||||
@ValidateDate({ optional: true })
|
||||
fileCreatedAfter?: Date;
|
||||
|
||||
@Optional()
|
||||
@IsDate()
|
||||
@Type(() => Date)
|
||||
@ValidateDate({ optional: true })
|
||||
fileCreatedBefore?: Date;
|
||||
|
||||
@ApiProperty()
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
withPartners?: boolean;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Transform } from 'class-transformer';
|
||||
import { IsBoolean, IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
||||
import { Optional, ValidateUUID, toBoolean } from '../../domain.util';
|
||||
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
||||
import { ValidateBoolean, ValidateUUID } from '../../domain.util';
|
||||
import { TimeBucketSize } from '../../repositories';
|
||||
|
||||
export class TimeBucketDto {
|
||||
|
@ -19,34 +18,23 @@ export class TimeBucketDto {
|
|||
@ValidateUUID({ optional: true })
|
||||
personId?: string;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
isArchived?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
isFavorite?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
isTrashed?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
withStacked?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
withPartners?: boolean;
|
||||
}
|
||||
|
||||
export class TimeBucketAssetDto extends TimeBucketDto {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
timeBucket!: string;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import { AssetPathType, EntityType, PathType, PersonPathType, UserPathType } from '@app/infra/entities';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsArray, IsDate, IsEnum, IsString, IsUUID, ValidateNested } from 'class-validator';
|
||||
import { Optional, ValidateUUID } from '../domain.util';
|
||||
import { IsArray, IsEnum, IsString, IsUUID, ValidateNested } from 'class-validator';
|
||||
import { Optional, ValidateDate, ValidateUUID } from '../domain.util';
|
||||
|
||||
const PathEnum = Object.values({ ...AssetPathType, ...PersonPathType, ...UserPathType });
|
||||
|
||||
export class AuditDeletesDto {
|
||||
@IsDate()
|
||||
@Type(() => Date)
|
||||
@ValidateDate()
|
||||
after!: Date;
|
||||
|
||||
@ApiProperty({ enum: EntityType, enumName: 'EntityType' })
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { ImmichLogger } from '@app/infra/logger';
|
||||
import { applyDecorators } from '@nestjs/common';
|
||||
import { BadRequestException, applyDecorators } from '@nestjs/common';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Transform, Type } from 'class-transformer';
|
||||
import { Transform } from 'class-transformer';
|
||||
import {
|
||||
IsArray,
|
||||
IsBoolean,
|
||||
|
@ -12,6 +12,7 @@ import {
|
|||
IsUUID,
|
||||
ValidateIf,
|
||||
ValidationOptions,
|
||||
isDateString,
|
||||
} from 'class-validator';
|
||||
import { CronJob } from 'cron';
|
||||
import _ from 'lodash';
|
||||
|
@ -40,14 +41,10 @@ export interface OpenGraphTags {
|
|||
imageUrl?: string;
|
||||
}
|
||||
|
||||
export type Options = {
|
||||
optional?: boolean;
|
||||
each?: boolean;
|
||||
};
|
||||
|
||||
export const isConnectionAborted = (error: Error | any) => error.code === 'ECONNABORTED';
|
||||
|
||||
export function ValidateUUID(options?: Options) {
|
||||
type UUIDOptions = { optional?: boolean; each?: boolean };
|
||||
export const ValidateUUID = (options?: UUIDOptions) => {
|
||||
const { optional, each } = { optional: false, each: false, ...options };
|
||||
return applyDecorators(
|
||||
IsUUID('4', { each }),
|
||||
|
@ -55,7 +52,58 @@ export function ValidateUUID(options?: Options) {
|
|||
optional ? Optional() : IsNotEmpty(),
|
||||
each ? IsArray() : IsString(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
type DateOptions = { optional?: boolean; nullable?: boolean; format?: 'date' | 'date-time' };
|
||||
export const ValidateDate = (options?: DateOptions) => {
|
||||
const { optional, nullable, format } = { optional: false, nullable: false, format: 'date-time', ...options };
|
||||
|
||||
const decorators = [
|
||||
ApiProperty({ format }),
|
||||
IsDate(),
|
||||
optional ? Optional({ nullable: true }) : IsNotEmpty(),
|
||||
Transform(({ key, value }) => {
|
||||
if (value === null || value === undefined) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (!isDateString(value)) {
|
||||
throw new BadRequestException(`${key} must be a date string`);
|
||||
}
|
||||
|
||||
return new Date(value as string);
|
||||
}),
|
||||
];
|
||||
|
||||
if (optional) {
|
||||
decorators.push(Optional({ nullable }));
|
||||
}
|
||||
|
||||
return applyDecorators(...decorators);
|
||||
};
|
||||
|
||||
type BooleanOptions = { optional?: boolean };
|
||||
export const ValidateBoolean = (options?: BooleanOptions) => {
|
||||
const { optional } = { optional: false, ...options };
|
||||
const decorators = [
|
||||
// ApiProperty(),
|
||||
IsBoolean(),
|
||||
Transform(({ value }) => {
|
||||
if (value == 'true') {
|
||||
return true;
|
||||
} else if (value == 'false') {
|
||||
return false;
|
||||
}
|
||||
return value;
|
||||
}),
|
||||
];
|
||||
|
||||
if (optional) {
|
||||
decorators.push(Optional());
|
||||
}
|
||||
|
||||
return applyDecorators(...decorators);
|
||||
};
|
||||
|
||||
export function validateCronExpression(expression: string) {
|
||||
try {
|
||||
|
@ -67,34 +115,7 @@ export function validateCronExpression(expression: string) {
|
|||
return true;
|
||||
}
|
||||
|
||||
interface IValue {
|
||||
value?: string;
|
||||
}
|
||||
|
||||
export const QueryBoolean = ({ optional }: { optional?: boolean }) => {
|
||||
const decorators = [IsBoolean(), Transform(toBoolean)];
|
||||
if (optional) {
|
||||
decorators.push(Optional());
|
||||
}
|
||||
return applyDecorators(...decorators);
|
||||
};
|
||||
|
||||
export const QueryDate = ({ optional }: { optional?: boolean }) => {
|
||||
const decorators = [IsDate(), Type(() => Date)];
|
||||
if (optional) {
|
||||
decorators.push(Optional());
|
||||
}
|
||||
return applyDecorators(...decorators);
|
||||
};
|
||||
|
||||
export const toBoolean = ({ value }: IValue) => {
|
||||
if (value == 'true') {
|
||||
return true;
|
||||
} else if (value == 'false') {
|
||||
return false;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
type IValue = { value: string };
|
||||
|
||||
export const toEmail = ({ value }: IValue) => value?.toLowerCase();
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsBoolean, IsEnum, IsNotEmpty } from 'class-validator';
|
||||
import { Optional } from '../domain.util';
|
||||
import { IsEnum, IsNotEmpty } from 'class-validator';
|
||||
import { ValidateBoolean } from '../domain.util';
|
||||
import { JobCommand, QueueName } from './job.constants';
|
||||
|
||||
export class JobIdParamDto {
|
||||
|
@ -16,8 +16,7 @@ export class JobCommandDto {
|
|||
@ApiProperty({ type: 'string', enum: JobCommand, enumName: 'JobCommand' })
|
||||
command!: JobCommand;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
force!: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { LibraryEntity, LibraryType } from '@app/infra/entities';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { ArrayMaxSize, ArrayUnique, IsBoolean, IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
||||
import { Optional, ValidateUUID } from '../domain.util';
|
||||
import { ArrayMaxSize, ArrayUnique, IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
||||
import { Optional, ValidateBoolean, ValidateUUID } from '../domain.util';
|
||||
|
||||
export class CreateLibraryDto {
|
||||
@IsEnum(LibraryType)
|
||||
|
@ -16,8 +16,7 @@ export class CreateLibraryDto {
|
|||
@IsNotEmpty()
|
||||
name?: string;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
isVisible?: boolean;
|
||||
|
||||
@Optional()
|
||||
|
@ -34,8 +33,7 @@ export class CreateLibraryDto {
|
|||
@ArrayMaxSize(128)
|
||||
exclusionPatterns?: string[];
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
isWatched?: boolean;
|
||||
}
|
||||
|
||||
|
@ -45,8 +43,7 @@ export class UpdateLibraryDto {
|
|||
@IsNotEmpty()
|
||||
name?: string;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
isVisible?: boolean;
|
||||
|
||||
@Optional()
|
||||
|
@ -102,13 +99,11 @@ export class LibrarySearchDto {
|
|||
}
|
||||
|
||||
export class ScanLibraryDto {
|
||||
@IsBoolean()
|
||||
@Optional()
|
||||
@ValidateBoolean({ optional: true })
|
||||
refreshModifiedFiles?: boolean;
|
||||
|
||||
@IsBoolean()
|
||||
@Optional()
|
||||
refreshAllFiles?: boolean = false;
|
||||
@ValidateBoolean({ optional: true })
|
||||
refreshAllFiles?: boolean;
|
||||
}
|
||||
|
||||
export class SearchLibraryDto {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { AssetFaceEntity, PersonEntity } from '@app/infra/entities';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Transform, Type } from 'class-transformer';
|
||||
import { IsArray, IsBoolean, IsDate, IsNotEmpty, IsString, MaxDate, ValidateNested } from 'class-validator';
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsArray, IsNotEmpty, IsString, MaxDate, ValidateNested } from 'class-validator';
|
||||
import { AuthDto } from '../auth';
|
||||
import { Optional, ValidateUUID, toBoolean } from '../domain.util';
|
||||
import { Optional, ValidateBoolean, ValidateDate, ValidateUUID } from '../domain.util';
|
||||
|
||||
export class PersonCreateDto {
|
||||
/**
|
||||
|
@ -17,18 +17,14 @@ export class PersonCreateDto {
|
|||
* Person date of birth.
|
||||
* Note: the mobile app cannot currently set the birth date to null.
|
||||
*/
|
||||
@Optional({ nullable: true })
|
||||
@IsDate()
|
||||
@Type(() => Date)
|
||||
@MaxDate(() => new Date(), { message: 'Birth date cannot be in the future' })
|
||||
@ApiProperty({ format: 'date' })
|
||||
@ValidateDate({ optional: true, nullable: true, format: 'date' })
|
||||
birthDate?: Date | null;
|
||||
|
||||
/**
|
||||
* Person visibility
|
||||
*/
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
isHidden?: boolean;
|
||||
}
|
||||
|
||||
|
@ -63,9 +59,8 @@ export class MergePersonDto {
|
|||
}
|
||||
|
||||
export class PersonSearchDto {
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
withHidden?: boolean = false;
|
||||
@ValidateBoolean({ optional: true })
|
||||
withHidden?: boolean;
|
||||
}
|
||||
|
||||
export class PersonResponseDto {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { AssetOrder } from '@app/domain/asset/dto/asset.dto';
|
||||
import { AssetType, GeodataPlacesEntity } from '@app/infra/entities';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Transform, Type } from 'class-transformer';
|
||||
import { IsBoolean, IsEnum, IsInt, IsNotEmpty, IsString, Max, Min } from 'class-validator';
|
||||
import { Optional, QueryBoolean, QueryDate, ValidateUUID, toBoolean } from '../../domain.util';
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsEnum, IsInt, IsNotEmpty, IsString, Max, Min } from 'class-validator';
|
||||
import { Optional, ValidateBoolean, ValidateDate, ValidateUUID } from '../../domain.util';
|
||||
|
||||
class BaseSearchDto {
|
||||
@ValidateUUID({ optional: true })
|
||||
|
@ -19,62 +19,62 @@ class BaseSearchDto {
|
|||
@ApiProperty({ enumName: 'AssetTypeEnum', enum: AssetType })
|
||||
type?: AssetType;
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
@ValidateBoolean({ optional: true })
|
||||
isArchived?: boolean;
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
@ValidateBoolean({ optional: true })
|
||||
@ApiProperty({ default: false })
|
||||
withArchived?: boolean;
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
@ValidateBoolean({ optional: true })
|
||||
isEncoded?: boolean;
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
@ValidateBoolean({ optional: true })
|
||||
isExternal?: boolean;
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
@ValidateBoolean({ optional: true })
|
||||
isFavorite?: boolean;
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
@ValidateBoolean({ optional: true })
|
||||
isMotion?: boolean;
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
@ValidateBoolean({ optional: true })
|
||||
isOffline?: boolean;
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
@ValidateBoolean({ optional: true })
|
||||
isReadOnly?: boolean;
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
@ValidateBoolean({ optional: true })
|
||||
isVisible?: boolean;
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
@ValidateBoolean({ optional: true })
|
||||
withDeleted?: boolean;
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
@ValidateBoolean({ optional: true })
|
||||
withExif?: boolean;
|
||||
|
||||
@QueryDate({ optional: true })
|
||||
@ValidateDate({ optional: true })
|
||||
createdBefore?: Date;
|
||||
|
||||
@QueryDate({ optional: true })
|
||||
@ValidateDate({ optional: true })
|
||||
createdAfter?: Date;
|
||||
|
||||
@QueryDate({ optional: true })
|
||||
@ValidateDate({ optional: true })
|
||||
updatedBefore?: Date;
|
||||
|
||||
@QueryDate({ optional: true })
|
||||
@ValidateDate({ optional: true })
|
||||
updatedAfter?: Date;
|
||||
|
||||
@QueryDate({ optional: true })
|
||||
@ValidateDate({ optional: true })
|
||||
trashedBefore?: Date;
|
||||
|
||||
@QueryDate({ optional: true })
|
||||
@ValidateDate({ optional: true })
|
||||
trashedAfter?: Date;
|
||||
|
||||
@QueryDate({ optional: true })
|
||||
@ValidateDate({ optional: true })
|
||||
takenBefore?: Date;
|
||||
|
||||
@QueryDate({ optional: true })
|
||||
@ValidateDate({ optional: true })
|
||||
takenAfter?: Date;
|
||||
|
||||
@IsString()
|
||||
|
@ -120,7 +120,7 @@ class BaseSearchDto {
|
|||
@Optional()
|
||||
size?: number;
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
@ValidateBoolean({ optional: true })
|
||||
isNotInAlbum?: boolean;
|
||||
|
||||
@Optional()
|
||||
|
@ -141,10 +141,10 @@ export class MetadataSearchDto extends BaseSearchDto {
|
|||
@Optional()
|
||||
checksum?: string;
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
@ValidateBoolean({ optional: true })
|
||||
withStacked?: boolean;
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
@ValidateBoolean({ optional: true })
|
||||
withPeople?: boolean;
|
||||
|
||||
@IsString()
|
||||
|
@ -197,34 +197,24 @@ export class SearchDto {
|
|||
@Optional()
|
||||
query?: string;
|
||||
|
||||
@IsBoolean()
|
||||
@Optional()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
smart?: boolean;
|
||||
|
||||
/** @deprecated */
|
||||
@IsBoolean()
|
||||
@Optional()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
clip?: boolean;
|
||||
|
||||
@IsEnum(AssetType)
|
||||
@Optional()
|
||||
type?: AssetType;
|
||||
|
||||
@IsBoolean()
|
||||
@Optional()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
recent?: boolean;
|
||||
|
||||
@IsBoolean()
|
||||
@Optional()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
motion?: boolean;
|
||||
|
||||
@IsBoolean()
|
||||
@Optional()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
withArchived?: boolean;
|
||||
|
||||
@IsInt()
|
||||
|
@ -252,9 +242,7 @@ export class SearchPeopleDto {
|
|||
@IsNotEmpty()
|
||||
name!: string;
|
||||
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@Optional()
|
||||
@ValidateBoolean({ optional: true })
|
||||
withHidden?: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { SharedLinkType } from '@app/infra/entities';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsBoolean, IsDate, IsEnum, IsString } from 'class-validator';
|
||||
import { Optional, ValidateUUID } from '../domain.util';
|
||||
import { IsEnum, IsString } from 'class-validator';
|
||||
import { Optional, ValidateBoolean, ValidateDate, ValidateUUID } from '../domain.util';
|
||||
|
||||
export class SharedLinkCreateDto {
|
||||
@IsEnum(SharedLinkType)
|
||||
|
@ -23,21 +22,16 @@ export class SharedLinkCreateDto {
|
|||
@Optional()
|
||||
password?: string;
|
||||
|
||||
@IsDate()
|
||||
@Type(() => Date)
|
||||
@Optional({ nullable: true })
|
||||
@ValidateDate({ optional: true, nullable: true })
|
||||
expiresAt?: Date | null = null;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
allowUpload?: boolean = false;
|
||||
@ValidateBoolean({ optional: true })
|
||||
allowUpload?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
allowDownload?: boolean = true;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
showMetadata?: boolean = true;
|
||||
}
|
||||
|
||||
|
@ -54,10 +48,10 @@ export class SharedLinkEditDto {
|
|||
@Optional()
|
||||
allowUpload?: boolean;
|
||||
|
||||
@Optional()
|
||||
@ValidateBoolean({ optional: true })
|
||||
allowDownload?: boolean;
|
||||
|
||||
@Optional()
|
||||
@ValidateBoolean({ optional: true })
|
||||
showMetadata?: boolean;
|
||||
|
||||
/**
|
||||
|
@ -65,8 +59,7 @@ export class SharedLinkEditDto {
|
|||
* Setting this flag and not sending expiryAt is considered as null instead.
|
||||
* Clients that can send null values can ignore this.
|
||||
*/
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
changeExpiryTime?: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsBoolean, IsEnum, IsNotEmpty, IsNumber, IsString, Max, Min } from 'class-validator';
|
||||
import { Optional } from '../../domain.util';
|
||||
import { IsEnum, IsNotEmpty, IsNumber, IsString, Max, Min } from 'class-validator';
|
||||
import { Optional, ValidateBoolean } from '../../domain.util';
|
||||
import { CLIPMode, ModelType } from '../../repositories';
|
||||
|
||||
export class ModelConfig {
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
enabled!: boolean;
|
||||
|
||||
@IsString()
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { AudioCodec, CQMode, ToneMapping, TranscodeHWAccel, TranscodePolicy, VideoCodec } from '@app/infra/entities';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsBoolean, IsEnum, IsInt, IsString, Max, Min } from 'class-validator';
|
||||
import { IsEnum, IsInt, IsString, Max, Min } from 'class-validator';
|
||||
import { ValidateBoolean } from '../../domain.util';
|
||||
|
||||
export class SystemConfigFFmpegDto {
|
||||
@IsInt()
|
||||
|
@ -68,14 +69,14 @@ export class SystemConfigFFmpegDto {
|
|||
@ApiProperty({ type: 'integer' })
|
||||
npl!: number;
|
||||
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
temporalAQ!: boolean;
|
||||
|
||||
@IsEnum(CQMode)
|
||||
@ApiProperty({ enumName: 'CQMode', enum: CQMode })
|
||||
cqMode!: CQMode;
|
||||
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
twoPass!: boolean;
|
||||
|
||||
@IsString()
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import { validateCronExpression } from '@app/domain';
|
||||
import { Type } from 'class-transformer';
|
||||
import {
|
||||
IsBoolean,
|
||||
IsNotEmpty,
|
||||
IsObject,
|
||||
IsString,
|
||||
|
@ -11,6 +9,7 @@ import {
|
|||
ValidatorConstraint,
|
||||
ValidatorConstraintInterface,
|
||||
} from 'class-validator';
|
||||
import { ValidateBoolean, validateCronExpression } from '../../domain.util';
|
||||
|
||||
const isEnabled = (config: SystemConfigLibraryScanDto) => config.enabled;
|
||||
|
||||
|
@ -22,7 +21,7 @@ class CronValidator implements ValidatorConstraintInterface {
|
|||
}
|
||||
|
||||
export class SystemConfigLibraryScanDto {
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
enabled!: boolean;
|
||||
|
||||
@ValidateIf(isEnabled)
|
||||
|
@ -33,7 +32,7 @@ export class SystemConfigLibraryScanDto {
|
|||
}
|
||||
|
||||
export class SystemConfigLibraryWatchDto {
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
enabled!: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { LogLevel } from '@app/infra/entities';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsBoolean, IsEnum } from 'class-validator';
|
||||
import { IsEnum } from 'class-validator';
|
||||
import { ValidateBoolean } from '../../domain.util';
|
||||
|
||||
export class SystemConfigLoggingDto {
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
enabled!: boolean;
|
||||
|
||||
@ApiProperty({ enum: LogLevel, enumName: 'LogLevel' })
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { CLIPConfig, RecognitionConfig } from '@app/domain';
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsBoolean, IsObject, IsUrl, ValidateIf, ValidateNested } from 'class-validator';
|
||||
import { IsObject, IsUrl, ValidateIf, ValidateNested } from 'class-validator';
|
||||
import { ValidateBoolean } from '../../domain.util';
|
||||
import { CLIPConfig, RecognitionConfig } from '../../smart-info/dto/model-config.dto';
|
||||
|
||||
export class SystemConfigMachineLearningDto {
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
enabled!: boolean;
|
||||
|
||||
@IsUrl({ require_tld: false, allow_underscores: true })
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { IsBoolean, IsString } from 'class-validator';
|
||||
import { IsString } from 'class-validator';
|
||||
import { ValidateBoolean } from '../../domain.util';
|
||||
|
||||
export class SystemConfigMapDto {
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
enabled!: boolean;
|
||||
|
||||
@IsString()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { IsBoolean } from 'class-validator';
|
||||
import { ValidateBoolean } from '../../domain.util';
|
||||
|
||||
export class SystemConfigNewVersionCheckDto {
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
enabled!: boolean;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import { IsBoolean, IsNotEmpty, IsNumber, IsString, IsUrl, Min, ValidateIf } from 'class-validator';
|
||||
import { IsNotEmpty, IsNumber, IsString, IsUrl, Min, ValidateIf } from 'class-validator';
|
||||
import { ValidateBoolean } from '../../domain.util';
|
||||
|
||||
const isEnabled = (config: SystemConfigOAuthDto) => config.enabled;
|
||||
const isOverrideEnabled = (config: SystemConfigOAuthDto) => config.mobileOverrideEnabled;
|
||||
|
||||
export class SystemConfigOAuthDto {
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
autoLaunch!: boolean;
|
||||
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
autoRegister!: boolean;
|
||||
|
||||
@IsString()
|
||||
|
@ -27,7 +28,7 @@ export class SystemConfigOAuthDto {
|
|||
@Min(0)
|
||||
defaultStorageQuota!: number;
|
||||
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
enabled!: boolean;
|
||||
|
||||
@ValidateIf(isEnabled)
|
||||
|
@ -35,7 +36,7 @@ export class SystemConfigOAuthDto {
|
|||
@IsString()
|
||||
issuerUrl!: string;
|
||||
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
mobileOverrideEnabled!: boolean;
|
||||
|
||||
@ValidateIf(isOverrideEnabled)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { IsBoolean } from 'class-validator';
|
||||
import { ValidateBoolean } from '../../domain.util';
|
||||
|
||||
export class SystemConfigPasswordLoginDto {
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
enabled!: boolean;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { IsBoolean } from 'class-validator';
|
||||
import { ValidateBoolean } from '../../domain.util';
|
||||
|
||||
export class SystemConfigReverseGeocodingDto {
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
enabled!: boolean;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import { IsBoolean, IsNotEmpty, IsString } from 'class-validator';
|
||||
import { IsNotEmpty, IsString } from 'class-validator';
|
||||
import { ValidateBoolean } from '../../domain.util';
|
||||
|
||||
export class SystemConfigStorageTemplateDto {
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
enabled!: boolean;
|
||||
@IsBoolean()
|
||||
|
||||
@ValidateBoolean()
|
||||
hashVerificationEnabled!: boolean;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
template!: string;
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsBoolean, IsInt, Min } from 'class-validator';
|
||||
import { IsInt, Min } from 'class-validator';
|
||||
import { ValidateBoolean } from '../../domain.util';
|
||||
|
||||
export class SystemConfigTrashDto {
|
||||
@IsBoolean()
|
||||
@ValidateBoolean()
|
||||
enabled!: boolean;
|
||||
|
||||
@IsInt()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Transform } from 'class-transformer';
|
||||
import { IsBoolean, IsEmail, IsNotEmpty, IsNumber, IsPositive, IsString } from 'class-validator';
|
||||
import { Optional, toEmail, toSanitized } from '../../domain.util';
|
||||
import { IsEmail, IsNotEmpty, IsNumber, IsPositive, IsString } from 'class-validator';
|
||||
import { Optional, ValidateBoolean, toEmail, toSanitized } from '../../domain.util';
|
||||
|
||||
export class CreateUserDto {
|
||||
@IsEmail({ require_tld: false })
|
||||
|
@ -21,8 +21,7 @@ export class CreateUserDto {
|
|||
@Transform(toSanitized)
|
||||
storageLabel?: string | null;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
memoriesEnabled?: boolean;
|
||||
|
||||
@Optional({ nullable: true })
|
||||
|
@ -31,8 +30,7 @@ export class CreateUserDto {
|
|||
@ApiProperty({ type: 'integer', format: 'int64' })
|
||||
quotaSizeInBytes?: number | null;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
shouldChangePassword?: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { UserAvatarColor } from '@app/infra/entities';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Transform } from 'class-transformer';
|
||||
import { IsBoolean, IsEmail, IsEnum, IsNotEmpty, IsNumber, IsPositive, IsString, IsUUID } from 'class-validator';
|
||||
import { Optional, toEmail, toSanitized } from '../../domain.util';
|
||||
import { IsEmail, IsEnum, IsNotEmpty, IsNumber, IsPositive, IsString, IsUUID } from 'class-validator';
|
||||
import { Optional, ValidateBoolean, toEmail, toSanitized } from '../../domain.util';
|
||||
|
||||
export class UpdateUserDto {
|
||||
@Optional()
|
||||
|
@ -30,16 +30,13 @@ export class UpdateUserDto {
|
|||
@ApiProperty({ format: 'uuid' })
|
||||
id!: string;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
isAdmin?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
shouldChangePassword?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@ValidateBoolean({ optional: true })
|
||||
memoriesEnabled?: boolean;
|
||||
|
||||
@Optional()
|
||||
|
|
|
@ -1,19 +1,13 @@
|
|||
import { Optional, toBoolean } from '@app/domain';
|
||||
import { Optional, ValidateBoolean, ValidateDate } from '@app/domain';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Transform, Type } from 'class-transformer';
|
||||
import { IsBoolean, IsDate, IsInt, IsNotEmpty, IsUUID } from 'class-validator';
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsInt, IsUUID } from 'class-validator';
|
||||
|
||||
export class AssetSearchDto {
|
||||
@Optional()
|
||||
@IsNotEmpty()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
isFavorite?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsNotEmpty()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
isArchived?: boolean;
|
||||
|
||||
@Optional()
|
||||
|
@ -33,13 +27,9 @@ export class AssetSearchDto {
|
|||
@ApiProperty({ format: 'uuid' })
|
||||
userId?: string;
|
||||
|
||||
@Optional()
|
||||
@IsDate()
|
||||
@Type(() => Date)
|
||||
@ValidateDate({ optional: true })
|
||||
updatedAfter?: Date;
|
||||
|
||||
@Optional()
|
||||
@IsDate()
|
||||
@Type(() => Date)
|
||||
@ValidateDate({ optional: true })
|
||||
updatedBefore?: Date;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Optional, toBoolean, UploadFieldName, ValidateUUID } from '@app/domain';
|
||||
import { Optional, UploadFieldName, ValidateBoolean, ValidateDate, ValidateUUID } from '@app/domain';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Transform, Type } from 'class-transformer';
|
||||
import { IsBoolean, IsDate, IsNotEmpty, IsString } from 'class-validator';
|
||||
import { IsNotEmpty, IsString } from 'class-validator';
|
||||
|
||||
export class CreateAssetDto {
|
||||
@ValidateUUID({ optional: true })
|
||||
|
@ -15,43 +14,29 @@ export class CreateAssetDto {
|
|||
@IsString()
|
||||
deviceId!: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsDate()
|
||||
@Type(() => Date)
|
||||
@ValidateDate()
|
||||
fileCreatedAt!: Date;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsDate()
|
||||
@Type(() => Date)
|
||||
@ValidateDate()
|
||||
fileModifiedAt!: Date;
|
||||
|
||||
@Optional()
|
||||
@IsString()
|
||||
duration?: string;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
isFavorite?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
isArchived?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
isVisible?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
isOffline?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ValidateBoolean({ optional: true })
|
||||
isReadOnly?: boolean;
|
||||
|
||||
// The properties below are added to correctly generate the API docs
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
import { Optional, toBoolean } from '@app/domain';
|
||||
import { ValidateBoolean } from '@app/domain';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Transform } from 'class-transformer';
|
||||
import { IsBoolean } from 'class-validator';
|
||||
|
||||
export class ServeFileDto {
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ApiProperty({ type: Boolean, title: 'Is serve thumbnail (resize) file' })
|
||||
@ValidateBoolean({ optional: true })
|
||||
@ApiProperty({ title: 'Is serve thumbnail (resize) file' })
|
||||
isThumb?: boolean;
|
||||
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@ApiProperty({ type: Boolean, title: 'Is request made from web' })
|
||||
@ValidateBoolean({ optional: true })
|
||||
@ApiProperty({ title: 'Is request made from web' })
|
||||
isWeb?: boolean;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue