refactor api dto's

This commit is contained in:
rubikscraft
2022-03-24 16:14:14 +01:00
parent 6417651419
commit 25b85c00e0
13 changed files with 90 additions and 86 deletions

View File

@@ -9,9 +9,11 @@ import {
} from '@nestjs/common';
import { plainToClass } from 'class-transformer';
import {
GetSyspreferenceResponse,
MultipleSysPreferencesResponse,
SysPreferenceResponse,
UpdateSysPreferenceRequest
SysPreferenceBaseResponse,
UpdateSysPreferenceRequest,
UpdateSysPreferenceResponse
} from 'picsur-shared/dist/dto/api/pref.dto';
import { Permission } from 'picsur-shared/dist/dto/permissions';
import { SysPreferences } from 'picsur-shared/dist/dto/syspreferences.dto';
@@ -36,28 +38,30 @@ export class PrefController {
const returned = new MultipleSysPreferencesResponse();
returned.preferences = prefs.map((pref) =>
plainToClass(SysPreferenceResponse, pref),
plainToClass(SysPreferenceBaseResponse, pref),
);
return returned;
}
@Get('sys/:key')
async getSysPref(@Param('key') key: string): Promise<SysPreferenceResponse> {
async getSysPref(
@Param('key') key: string,
): Promise<GetSyspreferenceResponse> {
const pref = await this.prefService.getPreference(key as SysPreferences);
if (HasFailed(pref)) {
this.logger.warn(pref.getReason());
throw new InternalServerErrorException('Could not get preference');
}
return plainToClass(SysPreferenceResponse, pref);
return plainToClass(GetSyspreferenceResponse, pref);
}
@Post('sys/:key')
async setSysPref(
@Param('key') key: string,
@Body() body: UpdateSysPreferenceRequest,
): Promise<SysPreferenceResponse> {
): Promise<UpdateSysPreferenceResponse> {
const value = body.value;
const pref = await this.prefService.setPreference(
@@ -69,7 +73,7 @@ export class PrefController {
throw new InternalServerErrorException('Could not set preference');
}
const returned = new SysPreferenceResponse();
const returned = new UpdateSysPreferenceResponse();
returned.key = key as SysPreferences;
returned.value = pref.value;
returned.type = pref.type;

View File

@@ -1,6 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import { SysPreferenceResponse } from 'picsur-shared/dist/dto/api/pref.dto';
import { SysPreferenceBaseResponse } from 'picsur-shared/dist/dto/api/pref.dto';
import { HasFailed } from 'picsur-shared/dist/types';
import { SnackBarType } from 'src/app/models/snack-bar-type';
import { SysprefService as SysPrefService } from 'src/app/services/api/syspref.service';
@@ -11,7 +11,7 @@ import { UtilService } from 'src/app/util/util.service';
})
export class SettingsSysprefComponent implements OnInit {
render = true;
preferences: SysPreferenceResponse[] = [];
preferences: SysPreferenceBaseResponse[] = [];
constructor(
private sysprefService: SysPrefService,

View File

@@ -1,6 +1,6 @@
import { Component, Input, OnInit } from '@angular/core';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import { SysPreferenceResponse } from 'picsur-shared/dist/dto/api/pref.dto';
import { SysPreferenceBaseResponse } from 'picsur-shared/dist/dto/api/pref.dto';
import {
SysPreferenceFriendlyNames,
SysPrefValueType
@@ -17,7 +17,7 @@ import { UtilService } from 'src/app/util/util.service';
styleUrls: ['./settings-syspref-option.component.scss'],
})
export class SettingsSysprefOptionComponent implements OnInit {
@Input() pref: SysPreferenceResponse;
@Input() pref: SysPreferenceBaseResponse;
private updateSubject = new Subject<SysPrefValueType>();

View File

@@ -1,9 +1,11 @@
import { Injectable } from '@angular/core';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import {
GetSyspreferenceResponse,
MultipleSysPreferencesResponse,
SysPreferenceResponse,
UpdateSysPreferenceRequest
SysPreferenceBaseResponse,
UpdateSysPreferenceRequest,
UpdateSysPreferenceResponse
} from 'picsur-shared/dist/dto/api/pref.dto';
import { Permission } from 'picsur-shared/dist/dto/permissions';
import {
@@ -29,7 +31,7 @@ export class SysprefService {
return this.sysprefObservable;
}
private sysprefObservable = new BehaviorSubject<SysPreferenceResponse[]>([]);
private sysprefObservable = new BehaviorSubject<SysPreferenceBaseResponse[]>([]);
constructor(
private api: ApiService,
@@ -38,7 +40,7 @@ export class SysprefService {
this.onPermissions();
}
public async getPreferences(): AsyncFailable<SysPreferenceResponse[]> {
public async getPreferences(): AsyncFailable<SysPreferenceBaseResponse[]> {
if (!this.hasPermission)
return Fail('You do not have permission to edit system preferences');
@@ -57,12 +59,12 @@ export class SysprefService {
public async getPreference(
key: SysPreferences
): AsyncFailable<SysPreferenceResponse> {
): AsyncFailable<GetSyspreferenceResponse> {
if (!this.hasPermission)
return Fail('You do not have permission to edit system preferences');
const response = await this.api.get(
SysPreferenceResponse,
GetSyspreferenceResponse,
`/api/pref/sys/${key}`
);
if (HasFailed(response)) {
@@ -77,13 +79,13 @@ export class SysprefService {
public async setPreference(
key: SysPreferences,
value: SysPrefValueType
): AsyncFailable<SysPreferenceResponse> {
): AsyncFailable<UpdateSysPreferenceResponse> {
if (!this.hasPermission)
return Fail('You do not have permission to edit system preferences');
const response = await this.api.post(
UpdateSysPreferenceRequest,
SysPreferenceResponse,
UpdateSysPreferenceResponse,
`/api/pref/sys/${key}`,
{ value }
);
@@ -96,7 +98,7 @@ export class SysprefService {
return response;
}
private updatePrefArray(pref: SysPreferenceResponse) {
private updatePrefArray(pref: SysPreferenceBaseResponse) {
const prefArray = this.snapshot;
// Replace the old pref with the new one
const index = prefArray.findIndex((i) => pref.key === i.key);
@@ -112,7 +114,7 @@ export class SysprefService {
private sync() {
this.sysprefObservable.next(
([] as SysPreferenceResponse[]).concat(this.snapshot)
([] as SysPreferenceBaseResponse[]).concat(this.snapshot)
);
}

View File

@@ -1 +0,0 @@
export * from './api.dto';

View File

@@ -1,24 +1,17 @@
import { Type } from 'class-transformer';
import {
IsArray,
IsEnum,
IsNotEmpty, ValidateNested
IsArray, IsEnum, IsNotEmpty, ValidateNested
} from 'class-validator';
import { IsPosInt } from '../../validators/positive-int.validator';
import { IsSysPrefValue } from '../../validators/syspref.validator';
import {
IsSysPrefValue,
SysPreferences,
SysPrefValueType,
SysPrefValueTypes,
SysPrefValueTypeStrings
} from '../syspreferences.dto';
export class UpdateSysPreferenceRequest {
@IsNotEmpty()
@IsSysPrefValue()
value: SysPrefValueType;
}
export class SysPreferenceResponse {
export class SysPreferenceBaseResponse {
@IsNotEmpty()
@IsEnum(SysPreferences)
key: SysPreferences;
@@ -32,10 +25,28 @@ export class SysPreferenceResponse {
type: SysPrefValueTypeStrings;
}
// Get Syspreference
// Request is done via url parameters
export class GetSyspreferenceResponse extends SysPreferenceBaseResponse {}
// Get syspreferences
export class MultipleSysPreferencesResponse {
@IsArray()
@IsNotEmpty()
@ValidateNested({ each: true })
@Type(() => SysPreferenceResponse)
preferences: SysPreferenceResponse[];
@Type(() => SysPreferenceBaseResponse)
preferences: SysPreferenceBaseResponse[];
@IsPosInt()
total: number;
}
// Update Syspreference
export class UpdateSysPreferenceRequest {
@IsNotEmpty()
@IsSysPrefValue()
value: SysPrefValueType;
}
export class UpdateSysPreferenceResponse extends SysPreferenceBaseResponse {}

View File

@@ -1,15 +1,14 @@
import { Type } from 'class-transformer';
import {
IsArray,
IsDefined,
IsInt, IsPositive,
ValidateNested
IsDefined, ValidateNested
} from 'class-validator';
import {
ERole,
RoleNameObject,
RoleNamePermsObject
} from '../../entities/role.entity';
import { IsPosInt } from '../../validators/positive-int.validator';
// RoleInfo
export class RoleInfoRequest extends RoleNameObject {}
@@ -23,9 +22,7 @@ export class RoleListResponse {
@Type(() => ERole)
roles: ERole[];
@IsInt()
@IsPositive()
@IsDefined()
@IsPosInt()
total: number;
}

View File

@@ -1,7 +1,7 @@
import { Type } from 'class-transformer';
import {
IsArray, IsDefined,
IsEnum, IsString,
IsEnum, IsJWT, IsString,
ValidateNested
} from 'class-validator';
import { EUser, NamePassUser } from '../../entities/user.entity';
@@ -15,6 +15,7 @@ export class UserLoginRequest extends NamePassUser {}
export class UserLoginResponse {
@IsString()
@IsDefined()
@IsJWT()
jwt_token: string;
}
@@ -32,6 +33,7 @@ export class UserMeResponse {
@IsString()
@IsDefined()
@IsJWT()
token: string;
}

View File

@@ -1,27 +1,20 @@
import { Type } from 'class-transformer';
import {
IsArray,
IsDefined,
IsInt,
IsOptional,
IsString,
Min,
ValidateNested
IsDefined, IsOptional,
IsString, ValidateNested
} from 'class-validator';
import { EUser, NamePassUser, UsernameUser } from '../../entities/user.entity';
import { IsPosInt } from '../../validators/positive-int.validator';
import { IsPlainTextPwd } from '../../validators/user.validators';
import { Roles } from '../roles.dto';
// UserList
export class UserListRequest {
@IsDefined()
@IsInt()
@Min(0)
@IsPosInt()
count: number;
@IsDefined()
@IsInt()
@Min(0)
@IsPosInt()
page: number;
}
@@ -32,14 +25,10 @@ export class UserListResponse {
@Type(() => EUser)
users: EUser[];
@IsDefined()
@IsInt()
@Min(0)
@IsPosInt()
count: number;
@IsDefined()
@IsInt()
@Min(0)
@IsPosInt()
page: number;
}

View File

@@ -1,8 +1,3 @@
import {
registerDecorator,
ValidationArguments,
ValidationOptions
} from 'class-validator';
import tuple from '../types/tuple';
// Syspref keys
@@ -46,24 +41,6 @@ export const SysPreferenceValueTypes: {
// Validators
export function isSysPrefValue(value: any, args: ValidationArguments) {
const type = typeof value;
return SysPrefValueTypes.includes(type);
}
export function IsSysPrefValue(validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
registerDecorator({
name: 'isSysPrefValue',
target: object.constructor,
propertyName: propertyName,
options: validationOptions,
validator: {
validate: isSysPrefValue,
},
});
};
}
// interfaces

View File

@@ -1,4 +1,2 @@
// Nothing
const a = 'hello';
export { };
export default a;

View File

@@ -0,0 +1,4 @@
import { IsDefined, IsInt, Min } from 'class-validator';
import { ComposeValidators } from './compose.validator';
export const IsPosInt = ComposeValidators(IsInt(), Min(0), IsDefined());

View File

@@ -0,0 +1,21 @@
import { registerDecorator, ValidationArguments, ValidationOptions } from 'class-validator';
import { SysPrefValueTypes } from '../dto/syspreferences.dto';
export function isSysPrefValue(value: any, args: ValidationArguments) {
const type = typeof value;
return SysPrefValueTypes.includes(type);
}
export function IsSysPrefValue(validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
registerDecorator({
name: 'isSysPrefValue',
target: object.constructor,
propertyName: propertyName,
options: validationOptions,
validator: {
validate: isSysPrefValue,
},
});
};
}