Skip to content
Snippets Groups Projects
Commit de4e3a62 authored by Steve Reis's avatar Steve Reis
Browse files

Merge branch...

Merge branch '24-as-a-developer-i-want-to-use-husky-so-that-i-can-keep-my-code-clean' into 'develop'

Resolve "As a developer, I want to use husky so that I can keep my code clean"

Closes #24

See merge request sibmip/gateway!5
parents d65044fc 2b751a7a
No related branches found
No related tags found
No related merge requests found
Showing
with 260 additions and 213 deletions
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
cd api
npm run lint
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
"eslint": "^7.30.0", "eslint": "^7.30.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0", "eslint-plugin-prettier": "^3.4.0",
"husky": "^7.0.2",
"jest": "^27.0.6", "jest": "^27.0.6",
"prettier": "^2.3.2", "prettier": "^2.3.2",
"supertest": "^6.1.3", "supertest": "^6.1.3",
...@@ -5727,6 +5728,21 @@ ...@@ -5727,6 +5728,21 @@
"node": ">=10.17.0" "node": ">=10.17.0"
} }
}, },
"node_modules/husky": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/husky/-/husky-7.0.2.tgz",
"integrity": "sha512-8yKEWNX4z2YsofXAMT7KvA1g8p+GxtB1ffV8XtpAEGuXNAbCV5wdNKH+qTpw8SM9fh4aMPDR+yQuKfgnreyZlg==",
"dev": true,
"bin": {
"husky": "lib/bin.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/typicode"
}
},
"node_modules/iconv-lite": { "node_modules/iconv-lite": {
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
...@@ -14973,6 +14989,12 @@ ...@@ -14973,6 +14989,12 @@
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
"dev": true "dev": true
}, },
"husky": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/husky/-/husky-7.0.2.tgz",
"integrity": "sha512-8yKEWNX4z2YsofXAMT7KvA1g8p+GxtB1ffV8XtpAEGuXNAbCV5wdNKH+qTpw8SM9fh4aMPDR+yQuKfgnreyZlg==",
"dev": true
},
"iconv-lite": { "iconv-lite": {
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
......
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
"test:watch": "jest --watch", "test:watch": "jest --watch",
"test:cov": "jest --coverage", "test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json" "test:e2e": "jest --config ./test/jest-e2e.json",
"prepare": "cd .. && husky install api/.husky"
}, },
"dependencies": { "dependencies": {
"@nestjs/axios": "^0.0.1", "@nestjs/axios": "^0.0.1",
...@@ -48,6 +49,7 @@ ...@@ -48,6 +49,7 @@
"eslint": "^7.30.0", "eslint": "^7.30.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0", "eslint-plugin-prettier": "^3.4.0",
"husky": "^7.0.2",
"jest": "^27.0.6", "jest": "^27.0.6",
"prettier": "^2.3.2", "prettier": "^2.3.2",
"supertest": "^6.1.3", "supertest": "^6.1.3",
...@@ -74,4 +76,4 @@ ...@@ -74,4 +76,4 @@
"coverageDirectory": "../coverage", "coverageDirectory": "../coverage",
"testEnvironment": "node" "testEnvironment": "node"
} }
} }
\ No newline at end of file
import { HttpService } from "@nestjs/axios"; import { HttpService } from '@nestjs/axios';
import { Request } from "express"; import { Observable } from 'rxjs';
import { Observable } from "rxjs"; import { IEngineOptions, IEngineService } from 'src/engine/engine.interfaces';
import { IEngineOptions, IEngineService } from "src/engine/engine.interfaces";
export default class DataShieldService implements IEngineService { export default class DataShieldService implements IEngineService {
constructor(private readonly options: IEngineOptions, private readonly httpService: HttpService) { } constructor(
private readonly options: IEngineOptions,
demo(): string { private readonly httpService: HttpService,
return "datashield"; ) {}
}
demo(): string {
getExperiment(uuid: string): Observable<string> { return 'datashield';
throw new Error("Method not implemented."); }
}
getExperiment(): Observable<string> {
deleteExperiment(uuid: string, request: Request): Observable<string> { throw new Error('Method not implemented.');
throw new Error("Method not implemented."); }
}
deleteExperiment(): Observable<string> {
editExperiment(uuid: string, request: Request): Observable<string> { throw new Error('Method not implemented.');
throw new Error("Method not implemented."); }
}
editExperiment(): Observable<string> {
startExperimentTransient(request: Request): Observable<string> { throw new Error('Method not implemented.');
throw new Error("Method not implemented."); }
}
startExperimentTransient(): Observable<string> {
startExperiment(request: Request): Observable<string> { throw new Error('Method not implemented.');
throw new Error("Method not implemented."); }
}
startExperiment(): Observable<string> {
getExperiments(): Observable<string> { throw new Error('Method not implemented.');
throw new Error("Method not implemented."); }
}
getExperiments(): Observable<string> {
getAlgorithms(): Observable<string> { throw new Error('Method not implemented.');
throw new Error("Method not implemented."); }
}
} getAlgorithms(): Observable<string> {
\ No newline at end of file throw new Error('Method not implemented.');
}
}
import { HttpService } from "@nestjs/axios"; import { HttpService } from '@nestjs/axios';
import { Request } from "express"; import { Request } from 'express';
import { map, Observable } from "rxjs"; import { map, Observable } from 'rxjs';
import { IEngineOptions, IEngineService } from "src/engine/engine.interfaces"; import { IEngineOptions, IEngineService } from 'src/engine/engine.interfaces';
export default class ExaremeService implements IEngineService { export default class ExaremeService implements IEngineService {
constructor(private readonly options: IEngineOptions, private readonly httpService: HttpService) { } constructor(
private readonly options: IEngineOptions,
demo(): string { private readonly httpService: HttpService,
return "exareme" ) {}
}
demo(): string {
getExperiment(uuid: string): Observable<string> { return 'exareme';
const path = this.options.baseurl + `experiments/${uuid}`; }
return this.httpService.get<string>(path).pipe( getExperiment(uuid: string): Observable<string> {
map(response => response.data) const path = this.options.baseurl + `experiments/${uuid}`;
);
} return this.httpService
.get<string>(path)
deleteExperiment(uuid: string): Observable<string> { .pipe(map((response) => response.data));
const path = this.options.baseurl + `experiments/${uuid}`; }
return this.httpService.delete(path).pipe( deleteExperiment(uuid: string): Observable<string> {
map(response => response.data) const path = this.options.baseurl + `experiments/${uuid}`;
)
} return this.httpService.delete(path).pipe(map((response) => response.data));
}
editExperiment(uuid: string, request: Request): Observable<string> {
const path = this.options.baseurl + `experiments/${uuid}`; editExperiment(uuid: string, request: Request): Observable<string> {
const path = this.options.baseurl + `experiments/${uuid}`;
return this.httpService.post(path,request.body).pipe(
map(response => response.data) return this.httpService
) .post(path, request.body)
} .pipe(map((response) => response.data));
}
startExperimentTransient(request: Request): Observable<string> {
const path = this.options.baseurl + "experiments/transient"; startExperimentTransient(request: Request): Observable<string> {
const path = this.options.baseurl + 'experiments/transient';
return this.httpService.post(path, request.body).pipe(
map(response => response.data) return this.httpService
) .post(path, request.body)
} .pipe(map((response) => response.data));
}
startExperiment(request: Request): Observable<string> {
const path = this.options.baseurl + "experiments"; startExperiment(request: Request): Observable<string> {
const path = this.options.baseurl + 'experiments';
return this.httpService.post(path, request.body).pipe(
map(response => response.data) return this.httpService
) .post(path, request.body)
} .pipe(map((response) => response.data));
}
getExperiments(): Observable<string> {
const path = this.options.baseurl + "experiments"; getExperiments(): Observable<string> {
const path = this.options.baseurl + 'experiments';
return this.httpService.get<string>(path).pipe(
map(response => response.data) return this.httpService
); .get<string>(path)
} .pipe(map((response) => response.data));
}
getAlgorithms(): Observable<string> {
const path = this.options.baseurl + "algorithms"; getAlgorithms(): Observable<string> {
const path = this.options.baseurl + 'algorithms';
return this.httpService.get<string>(path).pipe(
map(response => response.data) return this.httpService
); .get<string>(path)
} .pipe(map((response) => response.data));
} }
\ No newline at end of file }
export const ENGINE_MODULE_OPTIONS = "EngineModuleOption"; export const ENGINE_MODULE_OPTIONS = 'EngineModuleOption';
export const ENGINE_SERVICE = "EngineService" export const ENGINE_SERVICE = 'EngineService';
\ No newline at end of file
import { Controller, Delete, Get, Inject, Param, Patch, Post, Req } from '@nestjs/common'; import {
Controller,
Delete,
Get,
Inject,
Param,
Patch,
Post,
Req,
} from '@nestjs/common';
import { Request } from 'express'; import { Request } from 'express';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { ENGINE_SERVICE } from './engine.constants'; import { ENGINE_SERVICE } from './engine.constants';
...@@ -6,9 +15,11 @@ import { IEngineService } from './engine.interfaces'; ...@@ -6,9 +15,11 @@ import { IEngineService } from './engine.interfaces';
@Controller() @Controller()
export class EngineController { export class EngineController {
constructor(@Inject(ENGINE_SERVICE) private readonly engineService: IEngineService) { } constructor(
@Inject(ENGINE_SERVICE) private readonly engineService: IEngineService,
) {}
@Get("/test") @Get('/test')
getTest(): string { getTest(): string {
return this.engineService.demo(); return this.engineService.demo();
} }
...@@ -23,27 +34,33 @@ export class EngineController { ...@@ -23,27 +34,33 @@ export class EngineController {
return this.engineService.getExperiments(request); return this.engineService.getExperiments(request);
} }
@Get("/experiments/:uuid") @Get('/experiments/:uuid')
getExperiment(@Param('uuid') uuid: string): Observable<string> { getExperiment(@Param('uuid') uuid: string): Observable<string> {
return this.engineService.getExperiment(uuid); return this.engineService.getExperiment(uuid);
} }
@Delete("/experiments/:uuid") @Delete('/experiments/:uuid')
deleteExperiment(@Param('uuid') uuid: string, @Req() request: Request): Observable<string> { deleteExperiment(
@Param('uuid') uuid: string,
@Req() request: Request,
): Observable<string> {
return this.engineService.deleteExperiment(uuid, request); return this.engineService.deleteExperiment(uuid, request);
} }
@Patch("/experiments/:uuid") @Patch('/experiments/:uuid')
editExperiment(@Param('uuid') uuid: string, @Req() request: Request): Observable<string> { editExperiment(
@Param('uuid') uuid: string,
@Req() request: Request,
): Observable<string> {
return this.engineService.editExperiment(uuid, request); return this.engineService.editExperiment(uuid, request);
} }
@Post("experiments/transient") @Post('experiments/transient')
startExperimentTransient(@Req() request: Request): Observable<string> { startExperimentTransient(@Req() request: Request): Observable<string> {
return this.engineService.startExperimentTransient(request); return this.engineService.startExperimentTransient(request);
} }
@Post("experiments") @Post('experiments')
startExperiment(@Req() request: Request): Observable<string> { startExperiment(@Req() request: Request): Observable<string> {
return this.engineService.startExperiment(request); return this.engineService.startExperiment(request);
} }
......
import { Request } from "express"; import { Request } from 'express';
import { Observable } from "rxjs"; import { Observable } from 'rxjs';
export interface IEngineOptions { export interface IEngineOptions {
type: string; type: string;
baseurl: string; baseurl: string;
} }
export interface IEngineService { export interface IEngineService {
demo(): string; demo(): string;
getAlgorithms(request: Request): Observable<string>; getAlgorithms(request: Request): Observable<string>;
getExperiments(request: Request): Observable<string>; getExperiments(request: Request): Observable<string>;
getExperiment(uuid: string): Observable<string>; getExperiment(uuid: string): Observable<string>;
deleteExperiment(uuid: string, request: Request): Observable<string>; deleteExperiment(uuid: string, request: Request): Observable<string>;
editExperiment(uuid: string, request: Request): Observable<string>; editExperiment(uuid: string, request: Request): Observable<string>;
startExperimentTransient(request: Request): Observable<string>; startExperimentTransient(request: Request): Observable<string>;
startExperiment(request: Request): Observable<string>; startExperiment(request: Request): Observable<string>;
} }
\ No newline at end of file
...@@ -19,9 +19,9 @@ export class EngineModule { ...@@ -19,9 +19,9 @@ export class EngineModule {
const engineProvider = { const engineProvider = {
provide: ENGINE_SERVICE, provide: ENGINE_SERVICE,
useFactory: async (httpService: HttpService) => { useFactory: async (httpService: HttpService) => {
return await this.createEngineConnection(options, httpService) return await this.createEngineConnection(options, httpService);
}, },
inject: [HttpService] inject: [HttpService],
}; };
return { return {
...@@ -32,22 +32,18 @@ export class EngineModule { ...@@ -32,22 +32,18 @@ export class EngineModule {
autoSchemaFile: join(process.cwd(), 'src/schema.gql'), autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
}), }),
], ],
providers: [ providers: [optionsProvider, engineProvider, EngineResolver],
optionsProvider, controllers: [EngineController],
engineProvider,
EngineResolver
],
controllers: [
EngineController
],
exports: [optionsProvider, engineProvider], exports: [optionsProvider, engineProvider],
} };
} }
private static async createEngineConnection(options: IEngineOptions, httpService: HttpService): Promise<IEngineService> { private static async createEngineConnection(
let service = await import(`./connectors/${options.type}/main.connector`); options: IEngineOptions,
httpService: HttpService,
): Promise<IEngineService> {
const service = await import(`./connectors/${options.type}/main.connector`);
return new service.default(options, httpService); return new service.default(options, httpService);
} }
} }
...@@ -6,19 +6,21 @@ import { Domain } from './models/domain.model'; ...@@ -6,19 +6,21 @@ import { Domain } from './models/domain.model';
@Resolver() @Resolver()
export class EngineResolver { export class EngineResolver {
constructor(@Inject(ENGINE_SERVICE) private readonly engineService: IEngineService) { } constructor(
@Inject(ENGINE_SERVICE) private readonly engineService: IEngineService,
) {}
@Query(() => Domain) @Query(() => Domain)
async hello() { async hello() {
let dummy: Domain = { const dummy: Domain = {
id: "test", id: 'test',
label: "test", label: 'test',
description: "test", description: 'test',
groups: [], groups: [],
variables: [], variables: [],
datasets: [] datasets: [],
} };
return dummy; return dummy;
} }
} }
\ No newline at end of file
import { Field, ObjectType } from "@nestjs/graphql"; import { Field, ObjectType } from '@nestjs/graphql';
@ObjectType() @ObjectType()
export class Category { export class Category {
@Field() @Field()
id: string id: string;
@Field() @Field()
label: string; label: string;
} }
\ No newline at end of file
import { Field, ObjectType } from "@nestjs/graphql"; import { Field, ObjectType } from '@nestjs/graphql';
import { Category } from "./category.model"; import { Category } from './category.model';
import { Group } from "./group.model"; import { Group } from './group.model';
@ObjectType() @ObjectType()
export class Domain extends Group { export class Domain extends Group {
@Field(type => [Category]) @Field(() => [Category])
datasets: Category[]; datasets: Category[];
} }
\ No newline at end of file
import { Field, ObjectType } from "@nestjs/graphql"; import { Field, ObjectType } from '@nestjs/graphql';
import { Variable } from "./variable.model"; import { Variable } from './variable.model';
@ObjectType() @ObjectType()
export class Group { export class Group {
@Field() @Field()
id: string; id: string;
@Field() @Field()
label: string; label: string;
@Field({ nullable: true }) @Field({ nullable: true })
description?: string; description?: string;
@Field(type => [Group]) @Field(() => [Group])
groups: Group[]; groups: Group[];
@Field(type => [Variable]) @Field(() => [Variable])
variables: Variable[]; variables: Variable[];
} }
\ No newline at end of file
import { Field, ObjectType } from "@nestjs/graphql"; import { Field, ObjectType } from '@nestjs/graphql';
import { Category } from "./category.model"; import { Category } from './category.model';
import { Group } from "./group.model"; import { Group } from './group.model';
@ObjectType() @ObjectType()
export class Variable { export class Variable {
@Field() @Field()
id: string; id: string;
@Field({ nullable: true }) @Field({ nullable: true })
label?: string; label?: string;
@Field() @Field()
type: string; type: string;
@Field({ nullable: true }) @Field({ nullable: true })
description?: string; description?: string;
@Field(type => [Category]) @Field(() => [Category])
enumerations: Category[]; enumerations: Category[];
@Field(type => [Group]) @Field(() => [Group])
groups: Group[]; groups: Group[];
} }
\ No newline at end of file
...@@ -2,7 +2,7 @@ import { NestFactory } from '@nestjs/core'; ...@@ -2,7 +2,7 @@ import { NestFactory } from '@nestjs/core';
import { AppModule } from './main/app.module'; import { AppModule } from './main/app.module';
async function bootstrap() { async function bootstrap() {
const app = await NestFactory.create(AppModule, {cors: true}); const app = await NestFactory.create(AppModule, { cors: true });
await app.listen(process.env.GATEWAY_PORT); await app.listen(process.env.GATEWAY_PORT);
} }
bootstrap(); bootstrap();
import { HttpService } from '@nestjs/axios';
import { Controller, Get } from '@nestjs/common'; import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service'; import { AppService } from './app.service';
@Controller() @Controller()
export class AppController { export class AppController {
constructor(private readonly appService: AppService) { } constructor(private readonly appService: AppService) {}
@Get() @Get()
getHello(): string { getHello(): string {
......
...@@ -8,13 +8,14 @@ import { AppService } from './app.service'; ...@@ -8,13 +8,14 @@ import { AppService } from './app.service';
imports: [ imports: [
ConfigModule.forRoot({ ConfigModule.forRoot({
isGlobal: true, isGlobal: true,
envFilePath: ['.env', '.env.defaults'] envFilePath: ['.env', '.env.defaults'],
}), }),
EngineModule.forRootAsync({ EngineModule.forRootAsync({
type: process.env.ENGINE_TYPE, type: process.env.ENGINE_TYPE,
baseurl: process.env.ENGINE_BASE_URL, baseurl: process.env.ENGINE_BASE_URL,
})], }),
],
controllers: [AppController], controllers: [AppController],
providers: [AppService], providers: [AppService],
}) })
export class AppModule { } export class AppModule {}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment