Created a DTO base class factory

This commit is contained in:
Thom Werring 2023-10-21 14:02:55 +02:00
parent 8782242b10
commit 92c3d833f9
6 changed files with 139 additions and 84 deletions

View file

@ -23,11 +23,11 @@ export class AppController {
description: "Returns a list of all skills", description: "Returns a list of all skills",
schema: { schema: {
items: { items: {
$ref: getSchemaPath(SkillDto) $ref: getSchemaPath(SkillDto),
} },
} },
}) })
getSkills(): ReadonlyArray<SkillDto> { getSkills(): ReadonlyArray<SkillDto> {
return this.skillsService.getSkills({ }) return this.skillsService.getMany();
} }
} }

15
cv/src/common/types.ts Normal file
View file

@ -0,0 +1,15 @@
export function DtoClass<Type extends Record<string, unknown>, DTO>() {
return class BaseDto {
constructor(type: unknown) {}
public static asDto<T extends Type[]>(bases: T): DTO[]
public static asDto<T extends Type>(types: T): T
public static asDto<T extends Type | Type[]>(types: T): DTO | DTO[] {
if (!Array.isArray(types)) {
return new this(types) as DTO;
}
return types.map((base) => new this(base) as DTO);
}
}
}

View file

@ -1,7 +1,7 @@
import { Test, TestingModule } from '@nestjs/testing'; import { Test, TestingModule } from "@nestjs/testing";
import { SkillsService } from './skills.service'; import { SkillsService } from "./skills.service";
describe('SkillsService', () => { describe("SkillsService", () => {
let service: SkillsService; let service: SkillsService;
beforeEach(async () => { beforeEach(async () => {
@ -12,7 +12,17 @@ describe('SkillsService', () => {
service = module.get<SkillsService>(SkillsService); service = module.get<SkillsService>(SkillsService);
}); });
it('should be defined', () => { it("should be defined", () => {
expect(service).toBeDefined(); expect(service).toBeDefined();
}); });
describe("getMany method", () => {
it("should be defined", () => { expect(service.getMany).toBeDefined(); });
it("should return an array", () => { expect(Array.isArray(service.getMany())).toBe(true); });
it("should return an array", () => { expect(Array.isArray(service.getMany())).toBe(true); });
})
}); });

View file

@ -1,68 +1,18 @@
import { Injectable } from "@nestjs/common"; import { Injectable } from "@nestjs/common";
import { SkillDto, SkillType } from "src/skills/skills.types"; import { SkillDto, SkillType } from "@/skills/skills.types";
import {skills} from "@/skills/skills";
@Injectable() @Injectable()
export class SkillsService { export class SkillsService {
private readonly skills: ReadonlyArray<SkillDto>; private readonly skills: ReadonlyArray<SkillDto>;
constructor() { constructor() {
this.skills = SkillDto.asDto([ this.skills = SkillDto.asDto(skills)
{
name: "Git",
description: "Working with git, maintaining repositories, managing pull/merge requests.",
category: "Version control systems",
},
{
name: "NodeJs, TypeScript, and Javascript",
description: "Building efficient and scalable microservices.",
category: "Programming languages",
},
{
name: "Docker",
description: "Containerizing and running microservices in a local development environment.",
category: "Containerization",
},
{
name: "Kubernetes",
description: "Deploying microservices to AWS (EKS).",
category: "Containerization",
},
{
name: "EKS",
description: "Managing Elastic Kubernetes Service on AWS.",
category: "AWS",
},
{
name: "API Gateway",
description: "Building and deploying cloud based applications.",
category: "AWS",
},
{
name: "Lambda",
description: "Building and deploying cloud based applications.",
category: "AWS",
},
{
name: "CloudWatch",
description: "Monitoring cloud based applications.",
category: "AWS",
},
{
name: "CI/CD pipelines",
description: "Automating testing, building and deployments.",
category: "DevOps",
},
{
name: "PHP",
description: "Building Websites and applications in PHP Laravel.",
category: "Programming languages",
},
])
.sort((skillA, skillB) => skillA.category > skillB.category ? 1 : -1); .sort((skillA, skillB) => skillA.category > skillB.category ? 1 : -1);
} }
getSkills(filter?: Partial<SkillType>) { getMany(filter?: Partial<SkillType>) {
const filtersValues = Object.entries(filter).map(([key, filterValue]) => ([key, new RegExp(filterValue, "i")])) as [keyof SkillType, RegExp][]; const filtersValues = Object.entries(filter ?? {}).map(([key, filterValue]) => ([key, new RegExp(filterValue, "i")])) as [keyof SkillType, RegExp][];
if (!filter || filtersValues.length === 0) { if (!filter || filtersValues.length === 0) {
return this.skills; return this.skills;
} }

89
cv/src/skills/skills.ts Normal file
View file

@ -0,0 +1,89 @@
import { SkillType } from "@/skills/skills.types";
export const skills: SkillType[] = [
{
name: "Git",
description: "Working with git, maintaining repositories, managing pull/merge requests.",
category: "Version control systems",
},
{
name: "NodeJs, TypeScript, and Javascript",
description: "Building efficient and scalable microservices.",
category: "Programming languages",
},
{
name: "Docker",
description: "Containerizing and running microservices in a local development environment.",
category: "Containerization",
},
{
name: "Kubernetes",
description: "Deploying microservices to AWS (EKS).",
category: "Containerization",
},
{
name: "EKS",
description: "Managing Elastic Kubernetes Service on AWS.",
category: "AWS",
},
{
name: "API Gateway",
description: "Building and deploying cloud based applications.",
category: "AWS",
},
{
name: "Lambda",
description: "Building and deploying cloud based applications.",
category: "AWS",
},
{
name: "CloudWatch",
description: "Monitoring cloud based applications.",
category: "AWS",
},
{
name: "ElasticSearch, Logstash and Kibana",
description: "Generate statistics from data of a SaaS platform.",
category: "Business Intelligence",
},
{
name: "CI/CD pipelines",
description: "Automating testing, building and deployments.",
category: "DevOps",
},
{
name: "Server Management",
description: "Setup and management of a hosting server.",
category: "DevOps",
},
{
name: "Webhosting",
description: "Setting up hosting for websites & email.",
category: "DevOps",
},
{
name: "PHP",
description: "Building Websites and applications in PHP Laravel.",
category: "Programming languages",
},
{
name: "One-on-ones",
description: "Periodic meetings with junior developers and interns in my team to discuss their personal growth progress.",
category: "Team Management",
},
{
name: "Scrum Master",
description: "Facilitate the meetings, keeping track of the sprint board and refine tickets with the PO." ,
category: "Team Management",
},
{
name: "Finances",
description: "Manage the financial aspect of a student organization" ,
category: "Finance",
},
{
name: "Event Organization",
description: "Organize educational events for students" ,
category: "Organization",
}
] satisfies SkillType[];

View file

@ -1,4 +1,5 @@
import { ApiProperty } from "@nestjs/swagger"; import { ApiProperty } from "@nestjs/swagger";
import { DtoClass } from "@/common/types";
export type SkillType = { export type SkillType = {
name: string; name: string;
@ -6,8 +7,7 @@ export type SkillType = {
description: string; description: string;
} }
type Test<T extends SkillType | SkillType[]> = T extends SkillType ? SkillDto : SkillDto[]; export class SkillDto extends DtoClass<SkillType, SkillDto>() implements SkillType {
export class SkillDto implements SkillType {
@ApiProperty() @ApiProperty()
readonly name: string; readonly name: string;
@ApiProperty() @ApiProperty()
@ -16,20 +16,11 @@ export class SkillDto implements SkillType {
readonly description: string; readonly description: string;
constructor(skill: SkillType) { constructor(skill: SkillType) {
super(skill)
Object.assign(this, { Object.assign(this, {
name: skill.name, name: skill.name,
category: skill.category, category: skill.category,
descriptions: skill.description descriptions: skill.description
}); });
} }
public static asDto<T extends SkillType>(skills: T): SkillDto
public static asDto<T extends SkillType[]>(skills: T): SkillDto[]
public static asDto<T extends SkillType | SkillType[]>(skills: T): SkillDto | SkillDto[] {
if (!Array.isArray(skills)) {
return new SkillDto(skills);
}
return skills.map((skill) => new SkillDto(skill));
}
} }