class-validator-translator-middleware v1.0.5
class-validator-translator-middleware
How to use this package
- first install it
npm i class-validator-translator-middleware - Now create a directory wherever you want and name it what ever you like but I use class-validator-errors:
mkdir src/class-validator-errors - Then you should create
error-codes.jsonin that directory:touch src/class-validator-errors/error-codes.json - Now in it you have to define your error codes like this.
{ "title_should_be_sample": "title_should_be_sample" } Now you must define your error locale messages in separated files on that directory. E.X. you should
touch src/class-validator-errors/en.jsonand in that file you have:{ "title_should_be_sample": "sample is good" }And Also
touch src/class-validator-errors/fa.json:{ "title_should_be_sample": "تست خوبه" }Important note: You cannot define an error code in
error-codes.jsonbut it had no defined error message in your error locale messages. If you do this intentionally or accidentally you will get an error while creating a new instance ofClassValidatorTranslatorMiddleware, The thrown error is instance of this error custom error class:IncompatibleErrorCodeAndErrorMessage.Since I am reading the error messages using require, they will be cached in the memory and this will prevent unnecessary reads from file system. for more info please read
ClassValidatorTranslatorMiddlewarecodes :star_struck:Note if you are using tsc: because we will never ever use fa.json and other json files you have to include this unused json files in your
tsconfig.json/tsconfig.build.jsonfile like this (If you do not include your fa.json, en.json, ... files will not be in the compiled version. unless you import them implicitly):{ "include": ["src", "src/**/*.json"] // ... }I client side sends an locale that you do not defined its error-message file in the
class-validator-errorsdirectory you will get An error in the next error handler middleware. In this case you will get an error that it is instance ofSpecifiedErrorMessageFileNotFound.Your frontend have to specify the
accept-languageheader in their requests and it should be within theLocaleenum.Final examples:
Here is one example in ExpressJS:
// app.ts import { join } from 'path'; import { Equals, IsOptional } from 'class-validator'; import { ClassValidatorTranslatorMiddleware, IncompatibleErrorCodeAndErrorMessage } from 'class-validator-translator-middleware'; process.on('uncaughtException', (error) => { if (error instanceof IncompatibleErrorCodeAndErrorMessage) { // do what ever you like, like sending email/notification to your devops guy process.exit(1); } }) const messagesPath = join(__dirname, 'class-validator-errors'); const classValidatorTranslatorMiddleware = new ClassValidatorTranslatorMiddleware(messagesPath);
const classValidatorTranslatorMiddleware =
new ClassValidatorTranslatorMiddleware(messagesPath);
app.use(classValidatorTranslatorMiddleware.middleware);
// this can be your class validator
class TestClassValidator {
@IsOptional()
@Equals('sample', { message: 'title_should_be_sample' })
title: string = 'bad_value';
}
app.use((error, req, res, next) => {
for (const error of errors) {
console.log(error.constraints); // تست خوبه
}
});
```
````
```
```
```
```
- Here is one example in routing controller
```ts
// messages.ts
import { ClassValidatorTranslatorMiddleware } from 'class-validator-translator-middleware';
// city-filter.ts
import {
IsBoolean,
IsAlpha,
IsOptional,
} from 'class-validator';
export class CityFilterQuery {
@IsOptional()
@IsAlpha('en', {
message: 'serviced_should_be_boolean_not_empty',
})
@IsBoolean({ message: 'serviced_should_be_boolean' })
serviced?: boolean;
}
// class-validator-error-translator.middleware.ts
import { join } from 'path';
import { ValidationError } from 'class-validator';
import {
Middleware,
ExpressErrorMiddlewareInterface,
HttpError,
} from 'routing-controllers';
import { NextFunction, Request, Response } from 'express';
import { ClassValidatorTranslatorMiddleware } from 'class-validator-translator-middleware';
const messagesPath = join(
__dirname,
'class-validator-errors',
);
const classValidatorTranslatorMiddleware =
new ClassValidatorTranslatorMiddleware(messagesPath);
class CustomValidationError {
errors: ValidationError[];
status?: number;
statusCode?: number;
}
@Middleware({ type: 'after' })
export class ClassValidatorErrorTranslator
implements ExpressErrorMiddlewareInterface
{
error(
error: HttpError | CustomValidationError,
request: Request,
response: Response,
next: NextFunction,
): void {
classValidatorTranslatorMiddleware.middleware(
error,
request,
response,
next,
);
}
}
// another middleware
import { ValidationError } from 'class-validator';
import {
Middleware,
ExpressErrorMiddlewareInterface,
HttpError,
} from 'routing-controllers';
import { NextFunction, Request, Response } from 'express';
import { SpecifiedErrorMessageFileNotFound } from 'class-validator-translator-middleware';
@Middleware({ type: 'after' })
export class ClassValidatorErrorTranslator
implements ExpressErrorMiddlewareInterface
{
error(
error: HttpError | CustomValidationError,
request: Request,
response: Response,
next: NextFunction,
): void {
if (
error instanceof SpecifiedErrorMessageFileNotFound
) {
// do whatever you want.
response.status(400).json({
message: 'un-supported-language',
});
}
next(error);
}
}
// app.ts
import { ClassValidatorErrorTranslator } from './middlewares/class-validator-error-translator.middleware';
import express from 'express';
const app = express();
const routingControllersOptions: RoutingControllersOptions = {
controllers: [
/* controllers */
],
middlewares: [ClassValidatorErrorTranslator],
/* other configs */
validation: {
whitelist: true,
},
};
useExpressServer(app, routingControllersOptions);
```Supported languages in Locale enum
Notes
- I had no time to add all the languages in the Locale
- Please use it with Typescript to prevent any unexpected behaviours
- Feel free to create issue or pull request
Contribution
- Clone repository
npm i; npm i prepeare- Create a new branch from
developbranch (git checkout -b develop-your-name) - Write you code
- Write its tests in tests directory
- run
npm testand make sure it works perfectly