Skip to content

Commit 5af2ffa

Browse files
committed
Created PipesModelParser
1 parent c9621c1 commit 5af2ffa

3 files changed

Lines changed: 71 additions & 0 deletions

File tree

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
"@nestjs/microservices": "^4.0.0",
2525
"@nestjs/testing": "^4.0.0",
2626
"@nestjs/websockets": "^4.0.0",
27+
"class-transformer": "^0.1.8",
28+
"class-validator": "^0.7.3",
2729
"cli-color": "^1.1.0",
2830
"engine.io-client": "^3.1.1",
2931
"express": "^4.16.2",
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { HttpException } from "@nestjs/core";
2+
import {
3+
PipeTransform,
4+
Pipe,
5+
ArgumentMetadata,
6+
HttpStatus
7+
} from "@nestjs/common";
8+
import { validate } from "class-validator";
9+
import { plainToClass } from "class-transformer";
10+
11+
@Pipe()
12+
export class PipesModelParser implements PipeTransform<any> {
13+
async transform(value, metadata: ArgumentMetadata) {
14+
const { metatype } = metadata;
15+
if (!metatype || !this.toValidate(metatype)) {
16+
return value;
17+
}
18+
const entity = plainToClass(metatype, value);
19+
const errors = await validate(entity);
20+
if (errors.length > 0) {
21+
throw new HttpException("Validation failed", HttpStatus.BAD_REQUEST);
22+
}
23+
return entity;
24+
}
25+
26+
private toValidate(metatype): boolean {
27+
const types = [String, Boolean, Number, Array, Object];
28+
return !types.find(type => metatype === type);
29+
}
30+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import * as sinon from "sinon";
2+
import { expect } from "chai";
3+
import { PipesModelParser } from "./../../pipes/pipes-model-parser";
4+
import { ArgumentMetadata } from "@nestjs/common";
5+
6+
class TestModel {
7+
constructor(public prop1: string, public prop2: number) {}
8+
}
9+
10+
describe("PipesModelParser", () => {
11+
let target: PipesModelParser;
12+
let testModel;
13+
beforeEach(() => {
14+
target = new PipesModelParser();
15+
});
16+
describe("transform", () => {
17+
describe("when metadata is empty or undefined", () => {
18+
it("should return the value unchanged", async () => {
19+
const testObj = { prop1: "value1", prop2: "value2" };
20+
expect(await target.transform(testObj, {} as any)).to.equal(testObj);
21+
expect(await target.transform(testObj, {} as any)).to.not.be.instanceOf(
22+
TestModel
23+
);
24+
});
25+
});
26+
describe("when metadata contains a class", () => {
27+
const metadata: ArgumentMetadata = {
28+
type: "body",
29+
metatype: TestModel,
30+
data: ""
31+
};
32+
it("should return an instance of the class", async () => {
33+
const testObj = { prop1: "value1", prop2: "value2" };
34+
const result = await target.transform(testObj, metadata);
35+
expect(result).to.be.instanceOf(TestModel);
36+
});
37+
});
38+
});
39+
});

0 commit comments

Comments
 (0)