Formatted code
This commit is contained in:
parent
a73c024e0a
commit
b6255cacc0
16 changed files with 181 additions and 160 deletions
30
.eslintrc.js
30
.eslintrc.js
|
|
@ -1,33 +1,27 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
parser: '@typescript-eslint/parser',
|
parser: "@typescript-eslint/parser",
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
project: 'tsconfig.json',
|
project: "tsconfig.json",
|
||||||
tsconfigRootDir: __dirname,
|
tsconfigRootDir: __dirname,
|
||||||
sourceType: 'module',
|
sourceType: "module",
|
||||||
},
|
},
|
||||||
plugins: ['@typescript-eslint/eslint-plugin'],
|
plugins: ["@typescript-eslint/eslint-plugin"],
|
||||||
extends: [
|
extends: ["plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"],
|
||||||
'plugin:@typescript-eslint/recommended',
|
|
||||||
'plugin:prettier/recommended',
|
|
||||||
],
|
|
||||||
root: true,
|
root: true,
|
||||||
env: {
|
env: {
|
||||||
node: true,
|
node: true,
|
||||||
jest: true,
|
jest: true,
|
||||||
},
|
},
|
||||||
ignorePatterns: ['.eslintrc.js'],
|
ignorePatterns: [".eslintrc.js"],
|
||||||
rules: {
|
rules: {
|
||||||
'@typescript-eslint/interface-name-prefix': 'off',
|
"@typescript-eslint/interface-name-prefix": "off",
|
||||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
"@typescript-eslint/explicit-function-return-type": "off",
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
strict: true,
|
strict: 2,
|
||||||
curly: ["error", "all"],
|
curly: ["error", "all"],
|
||||||
|
|
||||||
|
|
||||||
"@typescript-eslint/no-unused-vars": ["error"],
|
"@typescript-eslint/no-unused-vars": ["error"],
|
||||||
"@typescript-eslint/array-type": ["error", { default: "array-simple", "read-only": "array-simple" }],
|
"@typescript-eslint/array-type": ["error", { default: "array-simple" }],
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { AppService } from "@/app.service";
|
||||||
import { SkillsService } from "@/skills/skills.service";
|
import { SkillsService } from "@/skills/skills.service";
|
||||||
import { ExperiencesService } from "@/experiences/experiences.service";
|
import { ExperiencesService } from "@/experiences/experiences.service";
|
||||||
import { SkillDto } from "@/skills/skills.types";
|
import { SkillDto } from "@/skills/skills.types";
|
||||||
import { ExperienceDto, ExperienceType } from "@/experiences/experiences.types";
|
import { ExperienceDto } from "@/experiences/experiences.types";
|
||||||
|
|
||||||
describe("AppController", () => {
|
describe("AppController", () => {
|
||||||
let appController: AppController;
|
let appController: AppController;
|
||||||
|
|
@ -12,7 +12,6 @@ describe("AppController", () => {
|
||||||
let skillsService: SkillsService;
|
let skillsService: SkillsService;
|
||||||
let experiencesService: ExperiencesService;
|
let experiencesService: ExperiencesService;
|
||||||
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const app: TestingModule = await Test.createTestingModule({
|
const app: TestingModule = await Test.createTestingModule({
|
||||||
controllers: [AppController],
|
controllers: [AppController],
|
||||||
|
|
@ -27,25 +26,27 @@ describe("AppController", () => {
|
||||||
|
|
||||||
describe("root", () => {
|
describe("root", () => {
|
||||||
it("Should call AppService", () => {
|
it("Should call AppService", () => {
|
||||||
jest.spyOn(appService, "sayHello").mockImplementation(() => "Hello World!")
|
jest.spyOn(appService, "sayHello").mockImplementation(() => "Hello World!");
|
||||||
appController.sayHello();
|
appController.sayHello();
|
||||||
expect(appService.sayHello).toBeCalled();
|
expect(appService.sayHello).toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return \"Hello World!\"", () => {
|
it('should return "Hello World!"', () => {
|
||||||
expect(appController.sayHello()).toBe("Hello World!");
|
expect(appController.sayHello()).toBe("Hello World!");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getSkills", () => {
|
describe("getSkills", () => {
|
||||||
it("Should return an Array of SkillDtos", () => {
|
it("Should return an Array of SkillDtos", () => {
|
||||||
const result: SkillDto[] = SkillDto.asDto([{
|
const result: SkillDto[] = SkillDto.asDto([
|
||||||
|
{
|
||||||
name: "skillName",
|
name: "skillName",
|
||||||
category: "skillCategory",
|
category: "skillCategory",
|
||||||
description: "skillDescription"
|
description: "skillDescription",
|
||||||
}]);
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
jest.spyOn(skillsService, "getMany").mockImplementation(() => result)
|
jest.spyOn(skillsService, "getMany").mockImplementation(() => result);
|
||||||
expect(appController.getSkills()).toBe(result);
|
expect(appController.getSkills()).toBe(result);
|
||||||
expect(skillsService.getMany).toBeCalled();
|
expect(skillsService.getMany).toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
@ -53,17 +54,19 @@ describe("AppController", () => {
|
||||||
|
|
||||||
describe("getExperience", () => {
|
describe("getExperience", () => {
|
||||||
it("Should return an Array of ExperienceDtos", () => {
|
it("Should return an Array of ExperienceDtos", () => {
|
||||||
const result: ExperienceDto[] = ExperienceDto.asDto([{
|
const result: ExperienceDto[] = ExperienceDto.asDto([
|
||||||
|
{
|
||||||
name: "experienceName",
|
name: "experienceName",
|
||||||
city: "experienceCity",
|
city: "experienceCity",
|
||||||
jobTitle: "experienceJobTitle",
|
jobTitle: "experienceJobTitle",
|
||||||
startDate: new Date(),
|
startDate: new Date(),
|
||||||
endDate: new Date(),
|
endDate: new Date(),
|
||||||
description: "experienceDescription",
|
description: "experienceDescription",
|
||||||
skills: []
|
skills: [],
|
||||||
}]);
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
jest.spyOn(experiencesService, "getMany").mockImplementation(() => result)
|
jest.spyOn(experiencesService, "getMany").mockImplementation(() => result);
|
||||||
expect(appController.getExperiences()).toBe(result);
|
expect(appController.getExperiences()).toBe(result);
|
||||||
expect(experiencesService.getMany).toBeCalled();
|
expect(experiencesService.getMany).toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,11 @@ import { ExperienceDto } from "@/experiences/experiences.types";
|
||||||
@Controller()
|
@Controller()
|
||||||
@ApiExtraModels(SkillDto, ExperienceDto)
|
@ApiExtraModels(SkillDto, ExperienceDto)
|
||||||
export class AppController {
|
export class AppController {
|
||||||
constructor(private readonly appService: AppService, private readonly skillsService: SkillsService, private readonly experiencesService: ExperiencesService) {
|
constructor(
|
||||||
}
|
private readonly appService: AppService,
|
||||||
|
private readonly skillsService: SkillsService,
|
||||||
|
private readonly experiencesService: ExperiencesService
|
||||||
|
) {}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@ApiExcludeEndpoint()
|
@ApiExcludeEndpoint()
|
||||||
|
|
@ -28,7 +31,7 @@ export class AppController {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
getSkills(): ReadonlyArray<SkillDto> {
|
getSkills(): readonly SkillDto[] {
|
||||||
return this.skillsService.getMany();
|
return this.skillsService.getMany();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,7 +45,7 @@ export class AppController {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
getExperiences(): ReadonlyArray<ExperienceDto> {
|
getExperiences(): readonly ExperienceDto[] {
|
||||||
return this.experiencesService.getMany();
|
return this.experiencesService.getMany();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from "@nestjs/common";
|
||||||
import { AppController } from '@/app.controller';
|
import { AppController } from "@/app.controller";
|
||||||
import { AppService } from '@/app.service';
|
import { AppService } from "@/app.service";
|
||||||
import { SkillsService } from '@/skills/skills.service';
|
import { SkillsService } from "@/skills/skills.service";
|
||||||
import { ExperiencesService } from '@/experiences/experiences.service';
|
import { ExperiencesService } from "@/experiences/experiences.service";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [],
|
imports: [],
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from "@nestjs/common";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AppService {
|
export class AppService {
|
||||||
sayHello(): string {
|
sayHello(): string {
|
||||||
return 'Hello World!';
|
return "Hello World!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
export function DtoClass<Type extends Record<string, unknown>, DTO>() {
|
export function DtoClass<Type extends Record<string, unknown>, DTO>() {
|
||||||
return class BaseDto {
|
return class BaseDto {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
constructor(type: unknown) {}
|
constructor(type: unknown) {}
|
||||||
|
|
||||||
public static asDto<T extends Type[]>(bases: T): DTO[]
|
public static asDto<T extends Type[]>(bases: T): DTO[];
|
||||||
public static asDto<T extends Type>(types: T): T
|
public static asDto<T extends Type>(types: T): T;
|
||||||
public static asDto<T extends Type | Type[]>(types: T): DTO | DTO[] {
|
public static asDto<T extends Type | Type[]>(types: T): DTO | DTO[] {
|
||||||
if (!Array.isArray(types)) {
|
if (!Array.isArray(types)) {
|
||||||
return new this(types) as DTO;
|
return new this(types) as DTO;
|
||||||
|
|
@ -11,5 +12,5 @@ export function DtoClass<Type extends Record<string, unknown>, DTO>() {
|
||||||
|
|
||||||
return types.map((base) => new this(base) as DTO);
|
return types.map((base) => new this(base) as DTO);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from "@nestjs/testing";
|
||||||
import { ExperiencesService } from './experiences.service';
|
import { ExperiencesService } from "./experiences.service";
|
||||||
import { SkillsService } from "@/skills/skills.service";
|
import { SkillsService } from "@/skills/skills.service";
|
||||||
|
|
||||||
describe('ExperiencesService', () => {
|
describe("ExperiencesService", () => {
|
||||||
let service: ExperiencesService;
|
let service: ExperiencesService;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
|
@ -13,7 +13,7 @@ describe('ExperiencesService', () => {
|
||||||
service = module.get<ExperiencesService>(ExperiencesService);
|
service = module.get<ExperiencesService>(ExperiencesService);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be defined', () => {
|
it("should be defined", () => {
|
||||||
expect(service).toBeDefined();
|
expect(service).toBeDefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,30 +6,34 @@ import { SkillDto } from "@/skills/skills.types";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ExperiencesService {
|
export class ExperiencesService {
|
||||||
private readonly experiences: ReadonlyArray<ExperienceDto>;
|
private readonly experiences: readonly ExperienceDto[];
|
||||||
|
|
||||||
constructor(
|
constructor(private readonly skillsService: SkillsService) {
|
||||||
private readonly skillsService: SkillsService
|
this.experiences = ExperienceDto.asDto(this.linkSkills(experiences)).sort((experienceA, experienceB) =>
|
||||||
) {
|
experienceA.startDate > experienceB.startDate ? 1 : -1
|
||||||
this.experiences = ExperienceDto.asDto(this.linkSkills(experiences))
|
);
|
||||||
.sort((experienceA, experienceB) => experienceA.startDate > experienceB.startDate ? 1 : -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getMany(filter?: Partial<Omit<ExperienceType, "startDate" | "endDate" | "skills">>) {
|
getMany(filter?: Partial<Omit<ExperienceType, "startDate" | "endDate" | "skills">>) {
|
||||||
const filtersValues = Object.entries(filter ?? {}).map(([key, filterValue]) => ([key, new RegExp(filterValue, "i")])) as [keyof Omit<ExperienceType, "startDate" | "endDate" | "skills">, RegExp][];
|
const filtersValues = Object.entries(filter ?? {}).map(([key, filterValue]) => [
|
||||||
|
key,
|
||||||
|
new RegExp(filterValue, "i"),
|
||||||
|
]) as Array<[keyof Omit<ExperienceType, "startDate" | "endDate" | "skills">, RegExp]>;
|
||||||
if (!filter || filtersValues.length === 0) {
|
if (!filter || filtersValues.length === 0) {
|
||||||
return this.experiences;
|
return this.experiences;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.experiences.filter((experience) => filtersValues.every(([key, filterValue]) => filterValue.test(experience[key])));
|
return this.experiences.filter((experience) =>
|
||||||
|
filtersValues.every(([key, filterValue]) => filterValue.test(experience[key]))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private linkSkills(experiences: ExperienceType[]): Array<ExperienceType & { skills: ReadonlyArray<SkillDto> }> {
|
private linkSkills(experiences: ExperienceType[]): Array<ExperienceType & { skills: readonly SkillDto[] }> {
|
||||||
return experiences.map((experience) => {
|
return experiences.map((experience) => {
|
||||||
return {
|
return {
|
||||||
...experience,
|
...experience,
|
||||||
skills: experience.skills.map(partialSkill => this.skillsService.getMany(partialSkill)).flat()
|
skills: experience.skills.map((partialSkill) => this.skillsService.getMany(partialSkill)).flat(),
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,10 @@ During my time
|
||||||
`,
|
`,
|
||||||
skills: [
|
skills: [
|
||||||
{
|
{
|
||||||
category: "AWS|Containerization|DevOps|Business Intelligence|Team Management"
|
category: "AWS|Containerization|DevOps|Business Intelligence|Team Management",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "NodeJs|Git"
|
name: "NodeJs|Git",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
@ -31,10 +31,10 @@ During my time
|
||||||
description: "",
|
description: "",
|
||||||
skills: [
|
skills: [
|
||||||
{
|
{
|
||||||
category: "AWS|Containerization|DevOps"
|
category: "AWS|Containerization|DevOps",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "NodeJs|Git|Server"
|
name: "NodeJs|Git|Server",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
@ -47,7 +47,7 @@ During my time
|
||||||
description: "",
|
description: "",
|
||||||
skills: [
|
skills: [
|
||||||
{
|
{
|
||||||
name: "PHP|Webhosting"
|
name: "PHP|Webhosting",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
@ -61,10 +61,10 @@ During my time
|
||||||
description: "",
|
description: "",
|
||||||
skills: [
|
skills: [
|
||||||
{
|
{
|
||||||
name: "Finances"
|
name: "Finances",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
category: "Organization"
|
category: "Organization",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ export type ExperienceType = {
|
||||||
description: string;
|
description: string;
|
||||||
startDate: Date;
|
startDate: Date;
|
||||||
endDate: Date | null;
|
endDate: Date | null;
|
||||||
skills: Partial<SkillDto>[];
|
skills: Array<Partial<SkillDto>>;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class ExperienceDto extends DtoClass<ExperienceType, ExperienceDto>() implements ExperienceType {
|
export class ExperienceDto extends DtoClass<ExperienceType, ExperienceDto>() implements ExperienceType {
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
|
|
@ -19,7 +19,7 @@ export class ExperienceDto extends DtoClass<ExperienceType, ExperienceDto>() imp
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
readonly city: string;
|
readonly city: string;
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
readonly url?: string
|
readonly url?: string;
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
readonly jobTitle: string;
|
readonly jobTitle: string;
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
|
|
@ -31,8 +31,8 @@ export class ExperienceDto extends DtoClass<ExperienceType, ExperienceDto>() imp
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
type: [SkillDto],
|
type: [SkillDto],
|
||||||
items: {
|
items: {
|
||||||
$ref: getSchemaPath(SkillDto)
|
$ref: getSchemaPath(SkillDto),
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
readonly skills: SkillDto[];
|
readonly skills: SkillDto[];
|
||||||
|
|
||||||
|
|
|
||||||
46
src/main.ts
46
src/main.ts
|
|
@ -16,12 +16,16 @@ async function bootstrap() {
|
||||||
// }, "Credentials")
|
// }, "Credentials")
|
||||||
.setVersion("1.0.0a")
|
.setVersion("1.0.0a")
|
||||||
.setContact("Thom Werring", null, "cv@t-werring.nl")
|
.setContact("Thom Werring", null, "cv@t-werring.nl")
|
||||||
.addTag("Skills",
|
.addTag(
|
||||||
|
"Skills",
|
||||||
`<p>I'm a software lead with 5+ years of experience in cloud-native development and Agile/Scrum methodologies. I'm passionate about building and leading high-performing teams to deliver scalable and reliable cloud-based applications. I have a proven track record of success in using Node.js, TypeScript, JavaScript, Docker, Kubernetes, AWS, DevOps, Git, microservices, and HAProxy to create and deploy innovative solutions.<br/>
|
`<p>I'm a software lead with 5+ years of experience in cloud-native development and Agile/Scrum methodologies. I'm passionate about building and leading high-performing teams to deliver scalable and reliable cloud-based applications. I have a proven track record of success in using Node.js, TypeScript, JavaScript, Docker, Kubernetes, AWS, DevOps, Git, microservices, and HAProxy to create and deploy innovative solutions.<br/>
|
||||||
I'm also a strong communicator and collaborator, and I'm always looking for ways to improve my skills and knowledge. I'm excited about the future of cloud computing, and I'm eager to use my skills and experience to help others achieve their goals.
|
I'm also a strong communicator and collaborator, and I'm always looking for ways to improve my skills and knowledge. I'm excited about the future of cloud computing, and I'm eager to use my skills and experience to help others achieve their goals.
|
||||||
</p>
|
</p>
|
||||||
`)
|
`
|
||||||
.addTag("Saysimple", `<p>Senior Developer - Haarlem<br/> October 2018 - PRESENT</p><p>
|
)
|
||||||
|
.addTag(
|
||||||
|
"Saysimple",
|
||||||
|
`<p>Senior Developer - Haarlem<br/> October 2018 - PRESENT</p><p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>NodeJs, TypeScript, Javascript</strong> Building scalable microservices</li>
|
<li><strong>NodeJs, TypeScript, Javascript</strong> Building scalable microservices</li>
|
||||||
<li><strong>Docker and Kubernetes</strong> Containerizing and deploying microservices to AWS EKS</li>
|
<li><strong>Docker and Kubernetes</strong> Containerizing and deploying microservices to AWS EKS</li>
|
||||||
|
|
@ -29,46 +33,54 @@ async function bootstrap() {
|
||||||
<li><strong>DevOps</strong> Automating deployments and CI/CD pipelines.</li>
|
<li><strong>DevOps</strong> Automating deployments and CI/CD pipelines.</li>
|
||||||
<li><strong>On call</strong> Handling outages and maintenance during nights & weekends</li>
|
<li><strong>On call</strong> Handling outages and maintenance during nights & weekends</li>
|
||||||
</ul>
|
</ul>
|
||||||
</p>`)
|
</p>`
|
||||||
.addTag("Blackorange", `<p>Junior Developer - Amsterdam<br/> October 2014 - September 2018</p><p>
|
)
|
||||||
|
.addTag(
|
||||||
|
"Blackorange",
|
||||||
|
`<p>Junior Developer - Amsterdam<br/> October 2014 - September 2018</p><p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>PHP, Laravel</strong> Building websites and -applications in PHP Laravel</li>
|
<li><strong>PHP, Laravel</strong> Building websites and -applications in PHP Laravel</li>
|
||||||
<li><strong>Linux System Administrator</strong> Setup & maintenance of our application hosting</li>
|
<li><strong>Linux System Administrator</strong> Setup & maintenance of our application hosting</li>
|
||||||
</ul>
|
</ul>
|
||||||
</p>`)
|
</p>`
|
||||||
.addTag("Werring webdevelopment", `<p>ZZP - Middenbeemster<br/> Januari 2012 - December 2016</p><p>
|
)
|
||||||
|
.addTag(
|
||||||
|
"Werring webdevelopment",
|
||||||
|
`<p>ZZP - Middenbeemster<br/> Januari 2012 - December 2016</p><p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>PHP, Wordpress</strong> Building websites in PHP & Wordpress</li>
|
<li><strong>PHP, Wordpress</strong> Building websites in PHP & Wordpress</li>
|
||||||
<li><strong>Webhosting & Email</strong> managing webhosting for companies. </li>
|
<li><strong>Webhosting & Email</strong> managing webhosting for companies. </li>
|
||||||
</ul>
|
</ul>
|
||||||
</p>`)
|
</p>`
|
||||||
|
)
|
||||||
.build();
|
.build();
|
||||||
const document = SwaggerModule.createDocument(app, config, {
|
const document = SwaggerModule.createDocument(app, config, {
|
||||||
operationIdFactory: (controllerKey: string, methodKey: string) => (`${methodKey[0].toUpperCase()}${methodKey.substring(1)}`)
|
operationIdFactory: (controllerKey: string, methodKey: string) =>
|
||||||
|
`${methodKey[0].toUpperCase()}${methodKey.substring(1)}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
const redocOptions: RedocOptions = {
|
const redocOptions: RedocOptions = {
|
||||||
title: 'CV - Thom Werring',
|
title: "CV - Thom Werring",
|
||||||
logo: {
|
logo: {
|
||||||
url: 'https://picsum.photos/256/128',
|
url: "https://picsum.photos/256/128",
|
||||||
altText: 'Thom Werring'
|
altText: "Thom Werring",
|
||||||
},
|
},
|
||||||
sortPropsAlphabetically: true,
|
sortPropsAlphabetically: true,
|
||||||
hideDownloadButton: false,
|
hideDownloadButton: false,
|
||||||
|
|
||||||
tagGroups: [
|
tagGroups: [
|
||||||
{
|
{
|
||||||
name: 'Skills',
|
name: "Skills",
|
||||||
tags: ['Skills', ],
|
tags: ["Skills"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Experience',
|
name: "Experience",
|
||||||
tags: ['Experience', 'Saysimple', 'Blackorange', 'Werring webdevelopment'],
|
tags: ["Experience", "Saysimple", "Blackorange", "Werring webdevelopment"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
await RedocModule.setup('/docs', app, document, redocOptions);
|
await RedocModule.setup("/docs", app, document, redocOptions);
|
||||||
SwaggerModule.setup("/api", app, document);
|
SwaggerModule.setup("/api", app, document);
|
||||||
|
|
||||||
await app.listen(3000);
|
await app.listen(3000);
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,17 @@ describe("SkillsService", () => {
|
||||||
expect(service).toBeDefined();
|
expect(service).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe("getMany method", () => {
|
describe("getMany method", () => {
|
||||||
it("should be defined", () => { expect(service.getMany).toBeDefined(); });
|
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);
|
||||||
it("should return an array", () => { expect(Array.isArray(service.getMany())).toBe(true); });
|
});
|
||||||
})
|
|
||||||
|
|
||||||
|
it("should return an array", () => {
|
||||||
|
expect(Array.isArray(service.getMany())).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,20 @@
|
||||||
import { Injectable } from "@nestjs/common";
|
import { Injectable } from "@nestjs/common";
|
||||||
import { SkillDto, SkillType } from "@/skills/skills.types";
|
import { SkillDto, SkillType } from "@/skills/skills.types";
|
||||||
import {skills} from "@/skills/skills";
|
import { skills } from "@/skills/skills";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SkillsService {
|
export class SkillsService {
|
||||||
private readonly skills: ReadonlyArray<SkillDto>;
|
private readonly skills: readonly SkillDto[];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.skills = SkillDto.asDto(skills)
|
this.skills = SkillDto.asDto(skills).sort((skillA, skillB) => (skillA.category > skillB.category ? 1 : -1));
|
||||||
.sort((skillA, skillB) => skillA.category > skillB.category ? 1 : -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getMany(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 Array<[keyof SkillType, RegExp]>;
|
||||||
if (!filter || filtersValues.length === 0) {
|
if (!filter || filtersValues.length === 0) {
|
||||||
return this.skills;
|
return this.skills;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,22 +68,23 @@ export const skills: SkillType[] = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "One-on-ones",
|
name: "One-on-ones",
|
||||||
description: "Periodic meetings with junior developers and interns in my team to discuss their personal growth progress.",
|
description:
|
||||||
|
"Periodic meetings with junior developers and interns in my team to discuss their personal growth progress.",
|
||||||
category: "Team Management",
|
category: "Team Management",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Scrum Master",
|
name: "Scrum Master",
|
||||||
description: "Facilitate the meetings, keeping track of the sprint board and refine tickets with the PO." ,
|
description: "Facilitate the meetings, keeping track of the sprint board and refine tickets with the PO.",
|
||||||
category: "Team Management",
|
category: "Team Management",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Finances",
|
name: "Finances",
|
||||||
description: "Manage the financial aspect of a student organization" ,
|
description: "Manage the financial aspect of a student organization",
|
||||||
category: "Finance",
|
category: "Finance",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Event Organization",
|
name: "Event Organization",
|
||||||
description: "Organize educational events for students" ,
|
description: "Organize educational events for students",
|
||||||
category: "Organization",
|
category: "Organization",
|
||||||
}
|
},
|
||||||
] satisfies SkillType[];
|
] satisfies SkillType[];
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ export type SkillType = {
|
||||||
name: string;
|
name: string;
|
||||||
category: string;
|
category: string;
|
||||||
description: string;
|
description: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class SkillDto extends DtoClass<SkillType, SkillDto>() implements SkillType {
|
export class SkillDto extends DtoClass<SkillType, SkillDto>() implements SkillType {
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
|
|
@ -16,11 +16,11 @@ export class SkillDto extends DtoClass<SkillType, SkillDto>() implements SkillTy
|
||||||
readonly description: string;
|
readonly description: string;
|
||||||
|
|
||||||
constructor(skill: SkillType) {
|
constructor(skill: SkillType) {
|
||||||
super(skill)
|
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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from "@nestjs/testing";
|
||||||
import { INestApplication } from '@nestjs/common';
|
import { INestApplication } from "@nestjs/common";
|
||||||
import * as request from 'supertest';
|
import * as request from "supertest";
|
||||||
import { AppModule } from './../src/app.module';
|
import { AppModule } from "./../src/app.module";
|
||||||
|
|
||||||
describe('AppController (e2e)', () => {
|
describe("AppController (e2e)", () => {
|
||||||
let app: INestApplication;
|
let app: INestApplication;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
|
@ -15,10 +15,7 @@ describe('AppController (e2e)', () => {
|
||||||
await app.init();
|
await app.init();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('/ (GET)', () => {
|
it("/ (GET)", () => {
|
||||||
return request(app.getHttpServer())
|
return request(app.getHttpServer()).get("/").expect(200).expect("Hello World!");
|
||||||
.get('/')
|
|
||||||
.expect(200)
|
|
||||||
.expect('Hello World!');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue