Skip to content

Commit 729794e

Browse files
committed
WIP hotfix
1 parent f9acd5f commit 729794e

22 files changed

+972
-1011
lines changed

app/src/composables/useApiFetch.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,20 @@ export function useApiFetch<P extends AllPaths<Paths>, M extends IgnoreCase<keyo
3535
body?: Paths[`/${P}`][Lowercase<M>]['requestBody']['content']['application/json'],
3636
): /* @ts-ignore */
3737
AsyncData<OpenApiResponse<Paths[`/${P}`][Lowercase<M>]> | undefined, FetchError<OpenApiError<Paths[`/${P}`][Lowercase<M>]>>> {
38+
if (!body) {
39+
return useApiData(path, {
40+
...opts,
41+
cache: false,
42+
client: true,
43+
} as any)
44+
}
3845
return useApiData(path, {
3946
...opts,
4047
cache: false,
4148
client: true,
4249
body: {
4350
...opts?.body,
4451
...body,
45-
}
52+
},
4653
} as any)
4754
}

app/src/pages/index.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@ div
99

1010
<script lang='ts' setup>
1111
const { signIn, signOut, session, status, cookies, getProviders, user, sessionToken } = useAuth()
12+
13+
const test = useApiFetch('tickets/sla')
1214
</script>

service/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"types-package-json": "^2.0.39"
4747
},
4848
"devDependencies": {
49+
"@jest-mock/express": "^2.0.2",
4950
"@kradihsoy/lt-schematics": "*",
5051
"@nestjs/cli": "^9.0.0",
5152
"@nestjs/schematics": "^9.0.0",

service/src/_common/dto/parts/entity.part.dto.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { IsEnum, IsString } from 'class-validator'
1+
import { IsEnum, IsNumber, IsString } from 'class-validator'
22
import { ApiProperty } from '@nestjs/swagger'
33
import { IdnamePartDto } from '~/_common/dto/parts/idname.part.dto'
44
import { EntityType, EntityTypeList } from '~/_common/enum/entity-type.enum'
55

66
export class EntityPartDto extends IdnamePartDto {
7-
@IsString()
7+
@IsNumber()
88
@IsEnum(EntityTypeList)
99
@ApiProperty({ enum: EntityTypeList })
1010
public type: EntityType

service/src/_common/filters/mongoose-validation.filter.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,29 @@
11
import { ArgumentsHost, Catch, ExceptionFilter, HttpException, HttpStatus, Logger } from '@nestjs/common'
2-
import { Response } from 'express'
2+
import { Request, Response } from 'express'
33
import { Error } from 'mongoose'
44
import { ValidationError } from 'class-validator'
55

66
@Catch(Error.ValidationError, Error.CastError, ValidationError)
77
export class MongooseValidationFilter implements ExceptionFilter {
88
public catch(exception: Error.ValidationError | Error.CastError | ValidationError, host: ArgumentsHost) {
99
const ctx = host.switchToHttp()
10+
const request = ctx.getRequest<Request>()
1011
const response = ctx.getResponse<Response>()
1112
Logger.debug(exception['message'], 'MongooseValidationFilter')
1213
let debug = {}
13-
if (process.env.NODE_ENV !== 'production') {
14+
if (process.env.NODE_ENV !== 'production' && request.query['debug']) {
1415
debug['_exception'] = exception
1516
}
16-
response.status(HttpStatus.BAD_REQUEST).json(
17+
response.status(HttpStatus.NOT_ACCEPTABLE).json(
1718
HttpException.createBody(
1819
{
19-
statusCode: HttpStatus.BAD_REQUEST,
20+
statusCode: HttpStatus.NOT_ACCEPTABLE,
2021
message: exception['message'],
2122
validations: this.getValidationErrors(exception),
2223
...debug,
2324
},
2425
exception.constructor.name,
25-
HttpStatus.BAD_REQUEST,
26+
HttpStatus.NOT_ACCEPTABLE,
2627
),
2728
)
2829
}
Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
import { Type } from '@nestjs/common'
2-
import { PickType } from '@nestjs/swagger'
32

3+
// noinspection JSUnusedLocalSymbols
44
export function PickProjectionHelper<T, K extends keyof T>(
55
classRef: Type<T>,
6-
// classRef: any,
7-
projection: {
6+
_projection: {
87
[key in keyof T]?: number | 1 | 0
98
},
10-
): Type<Pick<T, any>> {
11-
// ): Type<Pick<T, (readonly K[])[number]>> {
12-
const keys = Object.keys(projection)
13-
// .filter((key) => projection[key] === 1)
14-
return PickType(classRef, keys as K[])
9+
): Type<T> {
10+
//TODO: fix to use projection with pick or partial
11+
return classRef
1512
}
16-
17-
// console.log(PickProjectionHelper({ a: number, b: 2, c: 3 }, { a: 1, b: 1 }))
Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,63 @@
1-
import { BadRequestException, HttpStatus, ValidationPipe, ValidationError, Logger } from '@nestjs/common'
1+
import {
2+
BadRequestException,
3+
HttpStatus,
4+
ValidationPipe,
5+
ValidationError,
6+
Logger,
7+
Injectable,
8+
Scope, Inject,
9+
} from '@nestjs/common'
10+
import { REQUEST } from '@nestjs/core'
11+
import { Request } from 'express'
212

13+
interface ValidationRecursive {
14+
[key: string]: string
15+
}
16+
17+
@Injectable({ scope: Scope.REQUEST })
318
export class DtoValidationPipe extends ValidationPipe {
4-
public constructor() {
19+
public constructor(@Inject(REQUEST) protected readonly request: Request) {
520
super({
621
transform: true,
7-
exceptionFactory: (errors) => {
8-
const validations = {}
9-
const errorsMessage = []
10-
errors.forEach((error: ValidationError) => {
11-
if (error.constraints) {
12-
Object.values(error.constraints).forEach((value) => {
13-
validations[error.property] = value
14-
errorsMessage.push(`${error.property}: ${value}`)
15-
})
16-
}
17-
if (error.children.length > 0) {
18-
validations[error.property] = {}
19-
error.children.forEach((childError: ValidationError) => {
20-
if (childError.constraints) {
21-
Object.values(childError.constraints).forEach((value) => {
22-
validations[error.property][childError.property] = value
23-
errorsMessage.push(`${error.property}.${childError.property}: ${value}`)
24-
})
25-
}
26-
})
27-
}
28-
})
29-
const message = `Validation failed: ${errorsMessage.join(', ')}`
30-
Logger.debug(message, 'DtoValidationPipe')
22+
transformOptions: {
23+
enableImplicitConversion: true,
24+
},
25+
exceptionFactory: (errors: ValidationError[]) => {
26+
let validations: ValidationRecursive = {}
27+
for (const error of errors) {
28+
validations = { ...validations, ...this.validationRecursive(error)}
29+
}
30+
const debug = {}
31+
const message = `Erreur de validation : ${Object.keys(validations).join(', ')}`.trim()
32+
Logger.debug(`${message} (${JSON.stringify(validations)})`, 'DtoValidationPipe')
33+
if (process.env.NODE_ENV !== 'production' && request.query['debug']) {
34+
debug['_errors'] = errors
35+
}
3136
return new BadRequestException({
3237
statusCode: HttpStatus.BAD_REQUEST,
3338
message,
3439
validations,
40+
...debug,
3541
})
3642
},
3743
})
3844
}
45+
46+
public validationRecursive(error: ValidationError, prefix = ''): ValidationRecursive {
47+
let validations = {}
48+
if (error.constraints) {
49+
validations[`${prefix + error.property}`] = Object.values(error.constraints)[0]
50+
}
51+
if (error.children.length > 0) {
52+
for (const errorChild of error.children) {
53+
if (errorChild.constraints) {
54+
validations[`${prefix + errorChild.property}`] = Object.values(errorChild.constraints)[0]
55+
}
56+
if (errorChild.children.length > 0) {
57+
validations = { ...validations, ...this.validationRecursive(errorChild, `${prefix + error.property}.${errorChild.property}.`) }
58+
}
59+
}
60+
}
61+
return validations
62+
}
3963
}

0 commit comments

Comments
 (0)