Skip to content

Commit

Permalink
Merge pull request #69 from exceptionless/main
Browse files Browse the repository at this point in the history
Fixed Class Validator using development debug messages
  • Loading branch information
decs authored Oct 13, 2024
2 parents c9e33d8 + 7905cb7 commit 0f28135
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 9 deletions.
59 changes: 55 additions & 4 deletions packages/class-validator/src/__tests__/class-validator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,24 @@ import {
IsEmail,
IsInt,
IsNotEmpty,
IsOptional,
IsString,
IsUUID,
Min,
ValidateNested,
} from 'class-validator';
import {expectTypeOf} from 'expect-type';
import {describe, expect, test} from 'vitest';

import {assert, validate, wrap} from '..';

describe('class-validator', () => {
class NestedSchema {
@IsString()
@IsNotEmpty()
value!: string;
}

class Schema {
@IsInt()
@Min(0)
Expand All @@ -34,6 +43,12 @@ describe('class-validator', () => {

@IsDateString()
updatedAt!: string;

@ValidateNested()
nested!: NestedSchema;
@IsOptional()
@ValidateNested()
nestedArray?: NestedSchema[];
}
const schema = Schema;

Expand All @@ -44,14 +59,26 @@ describe('class-validator', () => {
id: 'c4a760a8-dbcf-4e14-9f39-645a8e933d74',
name: 'John Doe',
updatedAt: '2021-01-01T00:00:00.000Z',
};
} as Schema;

const badData = {
age: '123',
createdAt: '2021-01-01T00:00:00.000Z',
email: '[email protected]',
id: 'c4a760a8-dbcf-4e14-9f39-645a8e933d74',
name: 'John Doe',
updatedAt: '2021-01-01T00:00:00.000Z'
};

const badNestedData = {
age: 123,
createdAt: '2021-01-01T00:00:00.000Z',
email: '[email protected]',
id: 'c4a760a8-dbcf-4e14-9f39-645a8e933d74',
name: 'John Doe',
updatedAt: '2021-01-01T00:00:00.000Z',
nested: new NestedSchema(),
nestedArray: [new NestedSchema()],
};

test('infer', () => {
Expand All @@ -67,11 +94,35 @@ describe('class-validator', () => {
expect(await validate(schema, badData)).toStrictEqual({
issues: [
{
message: `An instance of Schema has failed the validation:
- property age has failed the following constraints: min, isInt
`,
message: 'age must not be less than 0',
path: ['age'],
},
{
message: 'age must be an integer number',
path: ['age'],
}
],
success: false,
});

expect(await validate(schema, badNestedData)).toStrictEqual({
issues: [
{
message: 'value should not be empty',
path: ['nested.value'],
},
{
message: 'value must be a string',
path: ['nested.value'],
},
{
message: 'value should not be empty',
path: ['nestedArray[0].value'],
},
{
message: 'value must be a string',
path: ['nestedArray[0].value'],
}
],
success: false,
});
Expand Down
25 changes: 20 additions & 5 deletions packages/class-validator/src/validation.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/* eslint-disable prettier/prettier */
import type {AdapterResolver} from './resolver';
import type {ValidationAdapter} from '@typeschema/core';
import type {ValidationAdapter, ValidationIssue} from '@typeschema/core';

import {memoize} from '@typeschema/core';
import { ValidationError } from "class-validator";

const importValidationModule = memoize(async () => {
const {validate} = await import('class-validator');
Expand All @@ -13,6 +15,22 @@ export const validationAdapter: ValidationAdapter<
> = async schema => {
const {validate} = await importValidationModule();
return async data => {
function getIssues(error: ValidationError, parentPath = ""): ValidationIssue[] {
const currentPath = parentPath
? Number.isInteger(+error.property) ? `${parentPath}[${error.property}]` : `${parentPath}.${error.property}`
: error.property;
const constraints = error.constraints ? Object.values(error.constraints) : [];
const childIssues = error.children ? error.children.flatMap(childError => getIssues(childError, currentPath)) : [];

return [
...constraints.map((message) => ({
message: message,
path: [currentPath],
})),
...childIssues
];
}

const errors = await validate(Object.assign(new schema(), data));
if (errors.length === 0) {
return {
Expand All @@ -22,10 +40,7 @@ export const validationAdapter: ValidationAdapter<
};
}
return {
issues: errors.map(error => ({
message: error.toString(),
path: [error.property],
})),
issues: errors.flatMap(error => getIssues(error)),
success: false,
};
};
Expand Down

0 comments on commit 0f28135

Please sign in to comment.