Commit 157a8996 authored by Sidson's avatar Sidson
Browse files

refactor: upsdate to new backend

parent 8b835abb
......@@ -3,4 +3,5 @@ node_modules/
# Ignore config files that expose private data.
db.config.json
*.config.json
*.log
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Start Debug",
"type": "node",
"request": "attach",
"name": "Start debug and listen",
"address": "127.0.0.1",
"port": 9229,
"restart": true
}
]
"request": "launch",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "start:debug"], //changement ici
"port": 9230,
"skipFiles": ["<node_internals>/**"],
"outputCapture": "std"
}
]
}
This diff is collapsed.
......@@ -4,48 +4,30 @@
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --env=prod",
"run:debug": "nodemon --quiet --inspect dist/app.js",
"run:dev": "nodemon --quiet dist/app.js",
"start:dev": "webpack --env=dev",
"start:debug": "webpack --env=debug",
"start": "node dist/app.js"
"build": "npm exec m-cli --config=production",
"start:debug": "m-cli --config=debug"
},
"author": "",
"license": "ISC",
"dependencies": {
"@koa/cors": "^3.1.0",
"axios": "^0.19.2",
"chokidar": "^3.3.1",
"@m-backend/cli": "^1.1.10",
"@m-backend/core": "^1.1.5",
"cron": "^1.8.2",
"koa": "^2.11.0",
"koa-joi-router": "^6.0.2",
"koa-ratelimit": "^4.2.1",
"moment": "^2.24.0",
"pg": "^8.2.0",
"reflect-metadata": "^0.1.13",
"tsyringe": "^4.1.0",
"winston": "^3.2.1"
"reflect-metadata": "^0.1.13"
},
"devDependencies": {
"@types/cron": "^1.7.2",
"@types/koa": "^2.11.2",
"@types/koa__cors": "^3.1.1",
"@types/koa-joi-router": "^5.2.3",
"@types/koa-ratelimit": "^4.2.1",
"@types/koa__cors": "^3.0.1",
"@types/moment": "^2.13.0",
"@types/node": "^13.9.4",
"@types/pg": "^7.14.3",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^5.1.1",
"nodemon": "^2.0.2",
"ts-loader": "^6.2.2",
"ts-transform-auto-require": "^1.1.0",
"tsconfig-paths-webpack-plugin": "^3.2.0",
"typescript": "^3.8.3",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11",
"webpack-node-externals": "^1.7.2",
"webpack-shell-plugin-next": "^1.1.7"
"typescript": "^3.8.3"
}
}
{
"port": 3015,
"externalUrl": ["https://www.metromobilite.fr","https://www.mobilites-m.fr","http://localhost:4200"],
"logger": {
"level": "silly",
"transports": [
{ "type": "console" },
{
"type": "file",
"options": {
"filename": "affluence.log",
"maxsize": 100000,
"maxFiles": 10,
"tailable": true,
"zippedArchive": true
}
}
]
}
}
import MainApp from '@m-backend/core/src/lib/applications/main.app'
import { CoreModule, Module } from "@m-backend/core";
import UserReportController from './user-report/user-report.controller';
import DbCron from './db.cron';
import CorsMiddleware from './cors.middleware';
import JoiErrors from './joi-error.middleware';
import RateLimitMiddleware from './ratelimit.middleware';
@Module({
imports: [CoreModule],
applications: [MainApp],
controllers: [UserReportController],
crons: [DbCron],
middlewares: [CorsMiddleware, RateLimitMiddleware, JoiErrors]
})
export class AppModule { }
import { Context, Next } from 'koa';
import cors from '@koa/cors';
import { Middleware } from "@decorators/middleware.decorator";
import { MiddlewareInterface } from "@core/middleware.interface";
import { config } from '@core/config';
import { config, Middleware, MiddlewareInterface } from '@m-backend/core';
@Middleware({ autoloadIn: 'main' })
......
import { CronJob } from "cron";
import { OnTick, OnInit, OnComplete } from "@core/cron.interface";
import { Cron } from "@decorators/cron.decorator";
import { LoggerService } from "@core/logger.service";
import { Cron, OnTick, OnInit, LoggerService, config } from "@m-backend/core";
import { ClientFactoryService } from "./db/client.factory";
import { config } from '@core/config';
import { loggers } from "winston";
import { UserReportService } from "./user-report/user-report.service";
@Cron({
......
import { Client, QueryResult, QueryConfig } from "pg";
import { config } from '@core/config';
import { LoggerService } from "@core/logger.service";
import { config, LoggerService } from "@m-backend/core";
import { Client, QueryConfig } from "pg";
export class AffluenceClient extends Client {
......@@ -12,18 +11,7 @@ export class AffluenceClient extends Client {
await super.connect();
await this.query(`set search_path = '${config.db.affluence.schema}';`);
}
/*async insertReturning(table: string, columns: string, values: string, params: Array<any>): Promise<number> {
try {
let query = `insert into ${table} ${columns} values ${values} returning ident;`;
this.log.logger.silly(`[client][AffluenceClient][insertReturning] ${query}`);
let result = await this.query<{ ident: number }>(query, params);
if (result.rows.length === 0) throw new Error(`${table} : Unable to perform ${result.command}.`);
return result.rows[0].ident;
} catch (e) {
if (e.details) this.log.logger.error(`[client][AffluenceClient][insertReturning] ${e.details}`);
throw (e);
}
}*/
async insert(table: string, columns: string, values: string, params: Array<any>, name?: string): Promise<boolean> {
try {
let queryConfig: QueryConfig = {
......@@ -35,29 +23,9 @@ export class AffluenceClient extends Client {
let result = await this.query<{ ident: number }>(queryConfig);
if (result.rowCount !== 1) throw new Error(`${table} : Unable to perform ${result.command}.`);
return true;
} catch (e) {
} catch (e: any) {
if (e.details) this.log.logger.error(`[client][AffluenceClient][insert] ${e.details}`);
throw (e);
}
}
/*async update(table: string, columns: string, values: string, where: string, params: Array<any>) {
try {
let query = `update ${table} set ${columns} = ${values} where 1=1 ${where};`;
this.log.logger.silly(`[client][AffluenceClient][update] ${query}`);
return await this.query(query, params);
} catch (e) {
if (e.details) this.log.logger.error(`[client][AffluenceClient][update] ${e.details}`);
throw (e);
}
}
async delete(table: string, where: string, params: Array<any>) {
try {
let query = `delete from ${table} where 1=1 ${where};`;
this.log.logger.silly(`[client][AffluenceClient][delete] ${query}`);
return await this.query(query, params);
} catch (e) {
if (e.details) this.log.logger.error(`[client][AffluenceClient][delete] ${e.details}`);
throw (e);
}
}*/
}
import { AffluenceClient } from "@app/db/affluence.client";
import { LoggerService } from "@core/logger.service";
import { Service } from "@decorators/service.decorator";
import { Service, LoggerService } from "@m-backend/core";
@Service()
export class ClientFactoryService {
......
import { Middleware } from "@decorators/middleware.decorator";
import { MiddlewareInterface } from "@core/middleware.interface";
import { Middleware, MiddlewareInterface, LoggerService } from "@m-backend/core";
import { Next, Context } from "koa";
import { LoggerService } from "@core/logger.service";
@Middleware()
export default class JoiErrors implements MiddlewareInterface {
......@@ -11,7 +9,7 @@ export default class JoiErrors implements MiddlewareInterface {
async use(ctx: Context, next: Next) {
try {
await next();
} catch (e) {
} catch (e : any) {
if (e.isJoi) {
this.log.logger.error(`[middleware][JoiErrors] ${e}`);
}
......
import { Middleware, MiddlewareInterface } from '@m-backend/core';
import { Context, Next } from 'koa';
import limit from 'koa-ratelimit';
import { Middleware } from "@decorators/middleware.decorator";
import { MiddlewareInterface } from "@core/middleware.interface";
const db = new Map();
......
import { Context } from "koa";
import { Controller, Post, AttachMiddleware } from "@decorators/controller.decorator";
import { LoggerService } from "@core/logger.service";
import { AffluenceClient } from "@app/db/affluence.client";
import JoiErrors from "@app/joi-error.middleware";
......@@ -8,6 +7,7 @@ import { Joi } from "koa-joi-router";
import { ClientFactoryService } from "@app/db/client.factory";
import { UserReportService } from "./user-report.service";
import RateLimitMiddleware from "@app/ratelimit.middleware";
import { AttachMiddleware, Controller, LoggerService, Post } from "@m-backend/core";
@AttachMiddleware([JoiErrors])
@Controller()
......@@ -45,7 +45,7 @@ export default class UserReportController {
})
client = this.clientFactory.getAffluenceClient();
ctx.response.body = { success: true, status: 200 };
} catch (e) {
} catch (e: any) {
client?.end();
this.log.logger.error(`[controller][UserReportController][postUserReport] ${e}`);
ctx.response.body = { errors: [{ code: 'OPERATION_FAILED', message: e.message }] };
......
import { Service } from "@decorators/service.decorator";
import { config } from '@core/config';
import { Service, LoggerService } from "@m-backend/core";
import { UserReport } from "./user-report.model";
import { LoggerService } from "@core/logger.service";
@Service()
export class UserReportService {
......
import Koa from 'koa';
import { LoggerService } from '@core/logger.service';
import { MiddlewareInterface } from '@core/middleware.interface';
import { MIDDLEWARE_META } from "@decorators/middleware.decorator";
export abstract class AbstractApp {
public instance: Koa;
// Name and port properties are injected during the decorator 'application' function call.
public name: string | undefined;
public port: string | undefined;
constructor(public log: LoggerService, middlewares: MiddlewareInterface[]) {
this.instance = new Koa();
middlewares.forEach(middleware => {
const autoloadIn = Reflect.getMetadata(MIDDLEWARE_META.AUTOLOAD_IN, middleware.constructor);
if (autoloadIn === this.name) {
this.instance.use(async (ctx, next) => {
return await middleware.use(ctx, next);
});
}
});
}
public listen() {
this.instance.listen(this.port, () => this.log.logger.info(`[application][${this.name}] listening on http://localhost:${this.port}`));
}
}
import { AbstractApp } from "./abstractApp";
import { Application } from "@core/decorators/application.decorator";
import { config } from "@core/config";
import { inject, injectAll } from "tsyringe";
import { LoggerService } from "@core/logger.service";
import { MiddlewareInterface } from "@core/middleware.interface";
@Application('main', config.app.port)
export default class MainApp extends AbstractApp {
constructor(@inject(LoggerService) logger: LoggerService, @injectAll('MiddlewareInterface') middlewares: MiddlewareInterface[] = []) {
super(logger, middlewares);
}
}
import { EventEmitter } from 'events';
import fs from 'fs';
import path from 'path';
import chokidar from 'chokidar';
import { Service } from "@decorators/service.decorator";
import { config, loadConfigFile } from '@core/config';
export enum CONFIG_EVENTS {
CHANGE = 'config:change',
}
@Service()
export default class ConfigService {
[key: string]: any;
change$ = new EventEmitter();
constructor() {
Object.keys(config).forEach(name => this[name] = config[name]);
const watcher = chokidar.watch('**/*.config.json');
watcher.on('change', (filepath) => {
const configName = path.basename(filepath).replace('.config.json', '');
config[configName] = JSON.parse(fs.readFileSync(filepath).toString());
this.change$.emit(CONFIG_EVENTS.CHANGE, configName);
});
}
loadConfigFile(name: string) {
loadConfigFile(name);
this[name] = config[name];
}
}
/**
* Allow user to load and get config files.
* /!\ Need config files to be externals => See the webpack/webpack.config.prod.js
*/
/**
* Config object contains each config file data loaded using the loadConfigFile function.
*/
export const config: { [key: string]: any } = {};
export function loadConfigFile(name: string) {
const _config = require(`../${name}.config.json`);
config[name] = _config;
}
Markdown is supported
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