Merge pull request 'Runner import' (#33) from feature/22-runner_import into dev
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #33 closes #22
This commit is contained in:
commit
ed53627bbe
@ -30,6 +30,7 @@
|
||||
"consola": "^2.15.0",
|
||||
"cookie-parser": "^1.4.5",
|
||||
"cors": "^2.8.5",
|
||||
"csvtojson": "^2.0.10",
|
||||
"dotenv": "^8.2.0",
|
||||
"express": "^4.17.1",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
@ -47,6 +48,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cors": "^2.8.8",
|
||||
"@types/csvtojson": "^1.1.5",
|
||||
"@types/express": "^4.17.9",
|
||||
"@types/jest": "^26.0.16",
|
||||
"@types/jsonwebtoken": "^8.5.0",
|
||||
|
101
src/controllers/ImportController.ts
Normal file
101
src/controllers/ImportController.ts
Normal file
@ -0,0 +1,101 @@
|
||||
import csv from 'csvtojson';
|
||||
import { Body, ContentType, Controller, Param, Post, QueryParam, Req, UseBefore } from 'routing-controllers';
|
||||
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
|
||||
import { RunnerGroupNeededError } from '../errors/RunnerErrors';
|
||||
import { RunnerGroupNotFoundError } from '../errors/RunnerGroupErrors';
|
||||
import RawBodyMiddleware from '../middlewares/RawBody';
|
||||
import { ImportRunner } from '../models/actions/ImportRunner';
|
||||
import { ResponseRunner } from '../models/responses/ResponseRunner';
|
||||
import { RunnerController } from './RunnerController';
|
||||
|
||||
@Controller()
|
||||
//@Authorized("IMPORT:read")
|
||||
export class ImportController {
|
||||
private runnerController: RunnerController;
|
||||
|
||||
/**
|
||||
* Gets the repository of this controller's model/entity.
|
||||
*/
|
||||
constructor() {
|
||||
this.runnerController = new RunnerController();
|
||||
}
|
||||
|
||||
@Post('/runners/import')
|
||||
@ContentType("application/json")
|
||||
@ResponseSchema(ResponseRunner, { isArray: true, statusCode: 200 })
|
||||
@ResponseSchema(RunnerGroupNotFoundError, { statusCode: 404 })
|
||||
@ResponseSchema(RunnerGroupNeededError, { statusCode: 406 })
|
||||
@OpenAPI({ description: "Create new runners from json and insert them (or their teams) into the provided group" })
|
||||
async postJSON(@Body({ validate: true, type: ImportRunner }) importRunners: ImportRunner[], @QueryParam("group") groupID: number) {
|
||||
if (!groupID) { throw new RunnerGroupNeededError(); }
|
||||
let responseRunners: ResponseRunner[] = new Array<ResponseRunner>();
|
||||
for await (let runner of importRunners) {
|
||||
responseRunners.push(await this.runnerController.post(await runner.toCreateRunner(groupID)));
|
||||
}
|
||||
return responseRunners;
|
||||
}
|
||||
|
||||
@Post('/organisations/:id/import')
|
||||
@ContentType("application/json")
|
||||
@ResponseSchema(ResponseRunner, { isArray: true, statusCode: 200 })
|
||||
@ResponseSchema(RunnerGroupNotFoundError, { statusCode: 404 })
|
||||
@ResponseSchema(RunnerGroupNeededError, { statusCode: 406 })
|
||||
@OpenAPI({ description: "Create new runners from json and insert them (or their teams) into the provided org" })
|
||||
async postOrgsJSON(@Body({ validate: true, type: ImportRunner }) importRunners: ImportRunner[], @Param('id') id: number) {
|
||||
return await this.postJSON(importRunners, id)
|
||||
}
|
||||
|
||||
@Post('/teams/:id/import')
|
||||
@ContentType("application/json")
|
||||
@ResponseSchema(ResponseRunner, { isArray: true, statusCode: 200 })
|
||||
@ResponseSchema(RunnerGroupNotFoundError, { statusCode: 404 })
|
||||
@ResponseSchema(RunnerGroupNeededError, { statusCode: 406 })
|
||||
@OpenAPI({ description: "Create new runners from json and insert them into the provided team" })
|
||||
async postTeamsJSON(@Body({ validate: true, type: ImportRunner }) importRunners: ImportRunner[], @Param('id') id: number) {
|
||||
return await this.postJSON(importRunners, id)
|
||||
}
|
||||
|
||||
@Post('/runners/import/csv')
|
||||
@ContentType("application/json")
|
||||
@UseBefore(RawBodyMiddleware)
|
||||
@ResponseSchema(ResponseRunner, { isArray: true, statusCode: 200 })
|
||||
@ResponseSchema(RunnerGroupNotFoundError, { statusCode: 404 })
|
||||
@ResponseSchema(RunnerGroupNeededError, { statusCode: 406 })
|
||||
@OpenAPI({ description: "Create new runners from csv and insert them (or their teams) into the provided group" })
|
||||
async postCSV(@Req() request: any, @QueryParam("group") groupID: number) {
|
||||
let csvParse = await csv({ delimiter: [",", ";"], trim: true }).fromString(request.rawBody.toString());
|
||||
let importRunners: ImportRunner[] = new Array<ImportRunner>();
|
||||
for await (let runner of csvParse) {
|
||||
let newImportRunner = new ImportRunner();
|
||||
newImportRunner.firstname = runner.firstname;
|
||||
newImportRunner.middlename = runner.middlename;
|
||||
newImportRunner.lastname = runner.lastname;
|
||||
if (runner.class === undefined) { newImportRunner.team = runner.team; }
|
||||
else { newImportRunner.class = runner.class; }
|
||||
importRunners.push(newImportRunner);
|
||||
}
|
||||
return await this.postJSON(importRunners, groupID);
|
||||
}
|
||||
|
||||
@Post('/organisations/:id/import/csv')
|
||||
@ContentType("application/json")
|
||||
@UseBefore(RawBodyMiddleware)
|
||||
@ResponseSchema(ResponseRunner, { isArray: true, statusCode: 200 })
|
||||
@ResponseSchema(RunnerGroupNotFoundError, { statusCode: 404 })
|
||||
@ResponseSchema(RunnerGroupNeededError, { statusCode: 406 })
|
||||
@OpenAPI({ description: "Create new runners from csv and insert them (or their teams) into the provided org" })
|
||||
async postOrgsCSV(@Req() request: any, @Param("id") id: number) {
|
||||
return await this.postCSV(request, id);
|
||||
}
|
||||
|
||||
@Post('/teams/:id/import/csv')
|
||||
@ContentType("application/json")
|
||||
@UseBefore(RawBodyMiddleware)
|
||||
@ResponseSchema(ResponseRunner, { isArray: true, statusCode: 200 })
|
||||
@ResponseSchema(RunnerGroupNotFoundError, { statusCode: 404 })
|
||||
@ResponseSchema(RunnerGroupNeededError, { statusCode: 406 })
|
||||
@OpenAPI({ description: "Create new runners from csv and insert them into the provided team" })
|
||||
async postTeamsCSV(@Req() request: any, @Param("id") id: number) {
|
||||
return await this.postCSV(request, id);
|
||||
}
|
||||
}
|
27
src/middlewares/RawBody.ts
Normal file
27
src/middlewares/RawBody.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
const RawBodyMiddleware = (req: Request, res: Response, next: () => void) => {
|
||||
const body = []
|
||||
req.on('data', chunk => {
|
||||
body.push(chunk)
|
||||
})
|
||||
req.on('end', () => {
|
||||
const rawBody = Buffer.concat(body)
|
||||
req['rawBody'] = rawBody
|
||||
/*
|
||||
switch (req.header('content-type')) {
|
||||
case 'application/json':
|
||||
req.body = JSON.parse(rawBody.toString())
|
||||
break
|
||||
// add more body parsing if needs be
|
||||
default:
|
||||
}
|
||||
*/
|
||||
next()
|
||||
})
|
||||
req.on('error', () => {
|
||||
res.sendStatus(400)
|
||||
})
|
||||
}
|
||||
|
||||
export default RawBodyMiddleware
|
82
src/models/actions/ImportRunner.ts
Normal file
82
src/models/actions/ImportRunner.ts
Normal file
@ -0,0 +1,82 @@
|
||||
import { IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
||||
import { getConnectionManager } from 'typeorm';
|
||||
import { RunnerGroupNeededError } from '../../errors/RunnerErrors';
|
||||
import { RunnerOrganisationNotFoundError } from '../../errors/RunnerOrganisationErrors';
|
||||
import { RunnerGroup } from '../entities/RunnerGroup';
|
||||
import { RunnerOrganisation } from '../entities/RunnerOrganisation';
|
||||
import { RunnerTeam } from '../entities/RunnerTeam';
|
||||
import { CreateRunner } from './CreateRunner';
|
||||
|
||||
export class ImportRunner {
|
||||
|
||||
/**
|
||||
* The new runner's first name.
|
||||
*/
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
firstname: string;
|
||||
|
||||
/**
|
||||
* The new runner's middle name.
|
||||
* Optional.
|
||||
*/
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
middlename?: string;
|
||||
|
||||
/**
|
||||
* The new runner's last name.
|
||||
*/
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
lastname: string;
|
||||
|
||||
/**
|
||||
* The new runner's class (if not provided otherwise).
|
||||
*/
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
team?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
public set class(value: string) {
|
||||
this.team = value;
|
||||
}
|
||||
|
||||
public async toCreateRunner(groupID: number): Promise<CreateRunner> {
|
||||
let newRunner: CreateRunner = new CreateRunner();
|
||||
|
||||
newRunner.firstname = this.firstname;
|
||||
newRunner.middlename = this.middlename;
|
||||
newRunner.lastname = this.lastname;
|
||||
newRunner.group = (await this.getGroup(groupID)).id;
|
||||
|
||||
return newRunner;
|
||||
}
|
||||
|
||||
public async getGroup(groupID: number): Promise<RunnerGroup> {
|
||||
if (this.team === undefined && groupID === undefined) {
|
||||
throw new RunnerGroupNeededError();
|
||||
}
|
||||
|
||||
let team = await getConnectionManager().get().getRepository(RunnerTeam).findOne({ id: groupID });
|
||||
if (team) { return team; }
|
||||
|
||||
let org = await getConnectionManager().get().getRepository(RunnerOrganisation).findOne({ id: groupID });
|
||||
if (!org) {
|
||||
throw new RunnerOrganisationNotFoundError();
|
||||
}
|
||||
if (this.team === undefined) { return org; }
|
||||
|
||||
team = await getConnectionManager().get().getRepository(RunnerTeam).findOne({ name: this.team, parentGroup: org });
|
||||
if (!team) {
|
||||
let newRunnerTeam: RunnerTeam = new RunnerTeam();
|
||||
newRunnerTeam.name = this.team;
|
||||
newRunnerTeam.parentGroup = org;
|
||||
team = await getConnectionManager().get().getRepository(RunnerTeam).save(newRunnerTeam);
|
||||
}
|
||||
|
||||
return team;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user