From 7e9e15b5a6f3559d81b4bae7ccef24cbb251a265 Mon Sep 17 00:00:00 2001 From: Alex Hoisl <32290337+ahoisl@users.noreply.github.com> Date: Thu, 7 Apr 2022 14:29:36 +0200 Subject: [PATCH 1/2] feat: add option to use constraint messages in ValidationError.toString --- src/validation/ValidationError.ts | 22 ++++++++++++++++------ test/functional/validation-error.spec.ts | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/validation/ValidationError.ts b/src/validation/ValidationError.ts index aa0c501f3a..daa3ff923d 100644 --- a/src/validation/ValidationError.ts +++ b/src/validation/ValidationError.ts @@ -45,14 +45,20 @@ export class ValidationError { * @param shouldDecorate decorate the message with ANSI formatter escape codes for better readability * @param hasParent true when the error is a child of an another one * @param parentPath path as string to the parent of this property + * @param showConstraintMessages show constraint messages instead of constraint names */ - toString(shouldDecorate: boolean = false, hasParent: boolean = false, parentPath: string = ``): string { + toString( + shouldDecorate: boolean = false, + hasParent: boolean = false, + parentPath: string = ``, + showConstraintMessages: boolean = false + ): string { const boldStart = shouldDecorate ? `\x1b[1m` : ``; const boldEnd = shouldDecorate ? `\x1b[22m` : ``; + const constraintsToString = () => + (showConstraintMessages ? Object.values : Object.keys)(this.constraints ?? {}).join(`, `); const propConstraintFailed = (propertyName: string): string => - ` - property ${boldStart}${parentPath}${propertyName}${boldEnd} has failed the following constraints: ${boldStart}${Object.keys( - this.constraints - ).join(`, `)}${boldEnd} \n`; + ` - property ${boldStart}${parentPath}${propertyName}${boldEnd} has failed the following constraints: ${boldStart}${constraintsToString()}${boldEnd} \n`; if (!hasParent) { return ( @@ -61,7 +67,9 @@ export class ValidationError { }${boldEnd} has failed the validation:\n` + (this.constraints ? propConstraintFailed(this.property) : ``) + (this.children - ? this.children.map(childError => childError.toString(shouldDecorate, true, this.property)).join(``) + ? this.children + .map(childError => childError.toString(shouldDecorate, true, this.property, showConstraintMessages)) + .join(``) : ``) ); } else { @@ -75,7 +83,9 @@ export class ValidationError { } else { return this.children ? this.children - .map(childError => childError.toString(shouldDecorate, true, `${parentPath}${formattedProperty}`)) + .map(childError => + childError.toString(shouldDecorate, true, `${parentPath}${formattedProperty}`, showConstraintMessages) + ) .join(``) : ``; } diff --git a/test/functional/validation-error.spec.ts b/test/functional/validation-error.spec.ts index b68441ae03..d2a7f8db99 100644 --- a/test/functional/validation-error.spec.ts +++ b/test/functional/validation-error.spec.ts @@ -49,6 +49,7 @@ describe('ValidationError', () => { } const validationErrors = await validator.validate(new RootClass()); + expect(validationErrors).toHaveLength(3); expect(validationErrors[0].toString()).toEqual( 'An instance of RootClass has failed the validation:\n' + ' - property title has failed the following constraints: minLength, isString \n' @@ -67,5 +68,23 @@ describe('ValidationError', () => { ' - property nestedArr[1].name has failed the following constraints: isString \n' + ' - property nestedArr[1].url has failed the following constraints: isUrl \n' ); + expect(validationErrors[0].toString(undefined, undefined, undefined, true)).toEqual( + 'An instance of RootClass has failed the validation:\n' + + ' - property title has failed the following constraints: title must be longer than or equal to 15 characters, title must be a string \n' + ); + expect(validationErrors[1].toString(undefined, undefined, undefined, true)).toEqual( + 'An instance of RootClass has failed the validation:\n' + + ' - property nestedObj.name has failed the following constraints: name must be a string \n' + + ' - property nestedObj.url has failed the following constraints: url must be a URL address \n' + + ' - property nestedObj.insideNested.name has failed the following constraints: name must be a string \n' + + ' - property nestedObj.insideNested.url has failed the following constraints: url must be a URL address \n' + ); + expect(validationErrors[2].toString(undefined, undefined, undefined, true)).toEqual( + 'An instance of RootClass has failed the validation:\n' + + ' - property nestedArr[0].name has failed the following constraints: name must be a string \n' + + ' - property nestedArr[0].url has failed the following constraints: url must be a URL address \n' + + ' - property nestedArr[1].name has failed the following constraints: name must be a string \n' + + ' - property nestedArr[1].url has failed the following constraints: url must be a URL address \n' + ); }); }); From 285e846910731e953080105aa72599ab3e2bc9c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20Ol=C3=A1h?= Date: Fri, 2 Dec 2022 12:16:15 +0000 Subject: [PATCH 2/2] refactor: format code with Prettier --- src/validation/ValidationExecutor.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/validation/ValidationExecutor.ts b/src/validation/ValidationExecutor.ts index 958face11c..9d3d312f14 100644 --- a/src/validation/ValidationExecutor.ts +++ b/src/validation/ValidationExecutor.ts @@ -45,9 +45,9 @@ export class ValidationExecutor { */ if (!this.metadataStorage.hasValidationMetaData && this.validatorOptions?.enableDebugMessages === true) { console.warn( - `No validation metadata found. No validation will be performed. There are multiple possible reasons:\n` + - ` - There may be multiple class-validator versions installed. You will need to flatten your dependencies to fix the issue.\n` + - ` - This validation runs before any file with validation decorator was parsed by NodeJS.` + `No validation metadata found. No validation will be performed. There are multiple possible reasons:\n` + + ` - There may be multiple class-validator versions installed. You will need to flatten your dependencies to fix the issue.\n` + + ` - This validation runs before any file with validation decorator was parsed by NodeJS.` ); }