Replace custom logging system with tslog
This commit is contained in:
parent
93bff1fdca
commit
88e5e19730
@ -69,6 +69,7 @@
|
|||||||
"on-finished": "^2.3.0",
|
"on-finished": "^2.3.0",
|
||||||
"redis": "^3.0.2",
|
"redis": "^3.0.2",
|
||||||
"ts-node": "^9.0.0",
|
"ts-node": "^9.0.0",
|
||||||
|
"tslog": "^2.10.0",
|
||||||
"uuid": "^8.0.0",
|
"uuid": "^8.0.0",
|
||||||
"ws": "^7.2.3"
|
"ws": "^7.2.3"
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import express, {NextFunction, Request, Response, Router} from 'express';
|
import express, {NextFunction, Request, Response, Router} from 'express';
|
||||||
import {BadRequestError, HttpError, NotFoundHttpError, ServerError, ServiceUnavailableHttpError} from "./HttpError";
|
import {BadRequestError, HttpError, NotFoundHttpError, ServerError, ServiceUnavailableHttpError} from "./HttpError";
|
||||||
import {lib} from "nunjucks";
|
import {lib} from "nunjucks";
|
||||||
import Logger from "./Logger";
|
|
||||||
import WebSocketListener from "./WebSocketListener";
|
import WebSocketListener from "./WebSocketListener";
|
||||||
import ApplicationComponent from "./ApplicationComponent";
|
import ApplicationComponent from "./ApplicationComponent";
|
||||||
import Controller from "./Controller";
|
import Controller from "./Controller";
|
||||||
@ -17,6 +16,7 @@ import * as path from "path";
|
|||||||
import CacheProvider from "./CacheProvider";
|
import CacheProvider from "./CacheProvider";
|
||||||
import RedisComponent from "./components/RedisComponent";
|
import RedisComponent from "./components/RedisComponent";
|
||||||
import Extendable from "./Extendable";
|
import Extendable from "./Extendable";
|
||||||
|
import {log} from "./Logger";
|
||||||
import TemplateError = lib.TemplateError;
|
import TemplateError = lib.TemplateError;
|
||||||
|
|
||||||
export default abstract class Application implements Extendable<ApplicationComponent | WebSocketListener<Application>> {
|
export default abstract class Application implements Extendable<ApplicationComponent | WebSocketListener<Application>> {
|
||||||
@ -46,7 +46,7 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
|||||||
const path = thing.path();
|
const path = thing.path();
|
||||||
this.webSocketListeners[path] = thing;
|
this.webSocketListeners[path] = thing;
|
||||||
thing.init(this);
|
thing.init(this);
|
||||||
Logger.info(`Added websocket listener on ${path}`);
|
log.info(`Added websocket listener on ${path}`);
|
||||||
} else {
|
} else {
|
||||||
thing.setApp(this);
|
thing.setApp(this);
|
||||||
this.components.push(thing);
|
this.components.push(thing);
|
||||||
@ -58,7 +58,7 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async start(): Promise<void> {
|
public async start(): Promise<void> {
|
||||||
Logger.info(`${config.get('app.name')} v${this.version} - hi`);
|
log.info(`${config.get('app.name')} v${this.version} - hi`);
|
||||||
process.once('SIGINT', () => {
|
process.once('SIGINT', () => {
|
||||||
this.stop().catch(console.error);
|
this.stop().catch(console.error);
|
||||||
});
|
});
|
||||||
@ -114,7 +114,7 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const errorId: string = LogRequestsComponent.logRequest(req, res, err, '500 Internal Error',
|
const errorId = LogRequestsComponent.logRequest(req, res, err, '500 Internal Error',
|
||||||
err instanceof BadRequestError || err instanceof ServiceUnavailableHttpError);
|
err instanceof BadRequestError || err instanceof ServiceUnavailableHttpError);
|
||||||
|
|
||||||
let httpError: HttpError;
|
let httpError: HttpError;
|
||||||
@ -183,7 +183,7 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
|||||||
for (let i = 2; i < args.length; i++) {
|
for (let i = 2; i < args.length; i++) {
|
||||||
switch (args[i]) {
|
switch (args[i]) {
|
||||||
case '--verbose':
|
case '--verbose':
|
||||||
Logger.verbose();
|
log.setSettings({minLevel: "trace"});
|
||||||
break;
|
break;
|
||||||
case '--full-http-requests':
|
case '--full-http-requests':
|
||||||
LogRequestsComponent.logFullHttpRequests();
|
LogRequestsComponent.logFullHttpRequests();
|
||||||
@ -192,7 +192,7 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
|||||||
await MysqlConnectionManager.migrationCommand(args.slice(i + 1));
|
await MysqlConnectionManager.migrationCommand(args.slice(i + 1));
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
Logger.warn('Unrecognized argument', args[i]);
|
log.warn('Unrecognized argument', args[i]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,13 +220,13 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async stop(): Promise<void> {
|
public async stop(): Promise<void> {
|
||||||
Logger.info('Stopping application...');
|
log.info('Stopping application...');
|
||||||
|
|
||||||
for (const component of this.components) {
|
for (const component of this.components) {
|
||||||
await component.stop?.();
|
await component.stop?.();
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(`${this.constructor.name} v${this.version} - bye`);
|
log.info(`${this.constructor.name} v${this.version} - bye`);
|
||||||
}
|
}
|
||||||
|
|
||||||
private routes(initRouter: Router, handleRouter: Router) {
|
private routes(initRouter: Router, handleRouter: Router) {
|
||||||
@ -234,7 +234,7 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
|||||||
if (controller.hasGlobalMiddlewares()) {
|
if (controller.hasGlobalMiddlewares()) {
|
||||||
controller.setupGlobalHandlers(handleRouter);
|
controller.setupGlobalHandlers(handleRouter);
|
||||||
|
|
||||||
Logger.info(`Registered global middlewares for controller ${controller.constructor.name}`);
|
log.info(`Registered global middlewares for controller ${controller.constructor.name}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +243,7 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
|||||||
initRouter.use(controller.getRoutesPrefix(), fileUploadFormRouter);
|
initRouter.use(controller.getRoutesPrefix(), fileUploadFormRouter);
|
||||||
handleRouter.use(controller.getRoutesPrefix(), mainRouter);
|
handleRouter.use(controller.getRoutesPrefix(), mainRouter);
|
||||||
|
|
||||||
Logger.info(`> Registered routes for controller ${controller.constructor.name}`);
|
log.info(`> Registered routes for controller ${controller.constructor.name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleRouter.use((req: Request) => {
|
handleRouter.use((req: Request) => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {Express, Router} from "express";
|
import {Express, Router} from "express";
|
||||||
import Logger from "./Logger";
|
import {log} from "./Logger";
|
||||||
import {sleep} from "./Utils";
|
import {sleep} from "./Utils";
|
||||||
import Application from "./Application";
|
import Application from "./Application";
|
||||||
import config from "config";
|
import config from "config";
|
||||||
@ -28,11 +28,11 @@ export default abstract class ApplicationComponent {
|
|||||||
err = null;
|
err = null;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
err = e;
|
err = e;
|
||||||
Logger.error(err, `${name} failed to prepare; retrying in 5s...`);
|
log.error(err, `${name} failed to prepare; retrying in 5s...`);
|
||||||
await sleep(5000);
|
await sleep(5000);
|
||||||
}
|
}
|
||||||
} while (err);
|
} while (err);
|
||||||
Logger.info(`${name} ready!`);
|
log.info(`${name} ready!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async close(thingName: string, fn: (callback: (err?: Error | null) => void) => void): Promise<void> {
|
protected async close(thingName: string, fn: (callback: (err?: Error | null) => void) => void): Promise<void> {
|
||||||
@ -42,9 +42,9 @@ export default abstract class ApplicationComponent {
|
|||||||
else resolve();
|
else resolve();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Logger.info(`${thingName} closed.`);
|
log.info(`${thingName} closed.`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error(e, `An error occurred while closing the ${thingName}.`);
|
log.error(e, `An error occurred while closing the ${thingName}.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import express, {IRouter, RequestHandler, Router} from "express";
|
import express, {IRouter, RequestHandler, Router} from "express";
|
||||||
import {PathParams} from "express-serve-static-core";
|
import {PathParams} from "express-serve-static-core";
|
||||||
import config from "config";
|
import config from "config";
|
||||||
import Logger from "./Logger";
|
import {log} from "./Logger";
|
||||||
import Validator, {ValidationBag} from "./db/Validator";
|
import Validator, {ValidationBag} from "./db/Validator";
|
||||||
import FileUploadMiddleware from "./FileUploadMiddleware";
|
import FileUploadMiddleware from "./FileUploadMiddleware";
|
||||||
import * as querystring from "querystring";
|
import * as querystring from "querystring";
|
||||||
@ -163,10 +163,10 @@ export default abstract class Controller {
|
|||||||
|
|
||||||
if (!Controller.routes[routeName]) {
|
if (!Controller.routes[routeName]) {
|
||||||
if (typeof routePath === 'string') {
|
if (typeof routePath === 'string') {
|
||||||
Logger.info(`Route ${routeName} has path ${routePath}`);
|
log.info(`Route ${routeName} has path ${routePath}`);
|
||||||
Controller.routes[routeName] = routePath;
|
Controller.routes[routeName] = routePath;
|
||||||
} else {
|
} else {
|
||||||
Logger.warn(`Cannot assign path to route ${routeName}.`);
|
log.warn(`Cannot assign path to route ${routeName}.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
141
src/Logger.ts
141
src/Logger.ts
@ -1,140 +1,11 @@
|
|||||||
import config from "config";
|
|
||||||
import {v4 as uuid} from "uuid";
|
import {v4 as uuid} from "uuid";
|
||||||
import Log from "./models/Log";
|
import {Logger as TsLogger} from "tslog";
|
||||||
import {bufferToUuid} from "./Utils";
|
|
||||||
import ModelFactory from "./db/ModelFactory";
|
|
||||||
|
|
||||||
export enum LogLevel {
|
export const log = new TsLogger();
|
||||||
ERROR,
|
|
||||||
WARN,
|
|
||||||
INFO,
|
|
||||||
DEBUG,
|
|
||||||
DEV,
|
|
||||||
}
|
|
||||||
|
|
||||||
export type LogLevelKeys = keyof typeof LogLevel;
|
export function makeUniqueLogger(): TsLogger {
|
||||||
|
const id = uuid();
|
||||||
/**
|
return log.getChildLogger({
|
||||||
* TODO: make logger not static
|
requestId: id,
|
||||||
*/
|
|
||||||
export default class Logger {
|
|
||||||
private static logLevel: LogLevel = LogLevel[<LogLevelKeys>config.get<string>('log.level')];
|
|
||||||
private static dbLogLevel: LogLevel = LogLevel[<LogLevelKeys>config.get<string>('log.db_level')];
|
|
||||||
private static verboseMode: boolean = config.get<boolean>('log.verbose');
|
|
||||||
|
|
||||||
public static verbose(): void {
|
|
||||||
this.verboseMode = true;
|
|
||||||
if (LogLevel[this.logLevel + 1]) this.logLevel++;
|
|
||||||
if (LogLevel[this.dbLogLevel + 1]) this.dbLogLevel++;
|
|
||||||
Logger.info('Verbose mode');
|
|
||||||
}
|
|
||||||
|
|
||||||
public static isVerboseMode(): boolean {
|
|
||||||
return this.verboseMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static silentError(error: Error, ...message: unknown[]): string {
|
|
||||||
return this.log(LogLevel.ERROR, message, error, true) || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static error(error: Error, ...message: unknown[]): string {
|
|
||||||
return this.log(LogLevel.ERROR, message, error) || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static warn(...message: unknown[]): void {
|
|
||||||
this.log(LogLevel.WARN, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static info(...message: unknown[]): void {
|
|
||||||
this.log(LogLevel.INFO, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static debug(...message: unknown[]): void {
|
|
||||||
this.log(LogLevel.DEBUG, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static dev(...message: unknown[]): void {
|
|
||||||
this.log(LogLevel.DEV, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static log(level: LogLevel, message: unknown[], error?: Error, silent: boolean = false): string | null {
|
|
||||||
if (level <= this.logLevel) {
|
|
||||||
if (error) {
|
|
||||||
if (level > LogLevel.ERROR) this.warn(`Wrong log level ${level} with attached error.`);
|
|
||||||
} else {
|
|
||||||
if (level <= LogLevel.ERROR) this.warn(`No error attached with log level ${level}.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const computedMsg = message.map(v => {
|
|
||||||
if (typeof v === 'string') {
|
|
||||||
return v;
|
|
||||||
} else {
|
|
||||||
return JSON.stringify(v, (key: string, value: string | unknown[] | Record<string, unknown>) => {
|
|
||||||
if (!Array.isArray(value) && value instanceof Object) {
|
|
||||||
if (value.type === 'Buffer' && typeof value.data === 'string') {
|
|
||||||
return `Buffer<${Buffer.from(value.data).toString('hex')}>`;
|
|
||||||
} else if (value !== v) {
|
|
||||||
return `[object Object]`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (typeof value === 'string' && value.length > 96) {
|
|
||||||
return value.substr(0, 96) + '...';
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}, 4);
|
|
||||||
}
|
|
||||||
}).join(' ');
|
|
||||||
|
|
||||||
const shouldSaveToDB = level <= this.dbLogLevel;
|
|
||||||
|
|
||||||
let output = `[${LogLevel[level]}] `;
|
|
||||||
const pad = output.length;
|
|
||||||
|
|
||||||
const logId = Buffer.alloc(16);
|
|
||||||
uuid({}, logId);
|
|
||||||
const strLogId = bufferToUuid(logId);
|
|
||||||
if (shouldSaveToDB) output += `${strLogId} - `;
|
|
||||||
|
|
||||||
output += computedMsg.replace(/\n/g, '\n' + ' '.repeat(pad));
|
|
||||||
|
|
||||||
switch (level) {
|
|
||||||
case LogLevel.ERROR:
|
|
||||||
if (silent || !error) {
|
|
||||||
console.error(output);
|
|
||||||
} else {
|
|
||||||
console.error(output, error);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LogLevel.WARN:
|
|
||||||
console.warn(output);
|
|
||||||
break;
|
|
||||||
case LogLevel.INFO:
|
|
||||||
console.info(output);
|
|
||||||
break;
|
|
||||||
case LogLevel.DEBUG:
|
|
||||||
case LogLevel.DEV:
|
|
||||||
console.debug(output);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldSaveToDB && ModelFactory.has(Log)) {
|
|
||||||
const log = Log.create({});
|
|
||||||
log.setLevel(level);
|
|
||||||
log.message = computedMsg;
|
|
||||||
log.setError(error);
|
|
||||||
log.setLogId(logId);
|
|
||||||
log.save().catch(err => {
|
|
||||||
if (!silent && err.message.indexOf('ECONNREFUSED') < 0) {
|
|
||||||
console.error({save_err: err, error});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
return strLogId;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private constructor() {
|
|
||||||
// disable constructor
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import nunjucks from 'nunjucks';
|
|||||||
import * as util from "util";
|
import * as util from "util";
|
||||||
import {WrappingError} from "./Utils";
|
import {WrappingError} from "./Utils";
|
||||||
import mjml2html from "mjml";
|
import mjml2html from "mjml";
|
||||||
import Logger from "./Logger";
|
import {log} from "./Logger";
|
||||||
import Controller from "./Controller";
|
import Controller from "./Controller";
|
||||||
import {ParsedUrlQueryInput} from "querystring";
|
import {ParsedUrlQueryInput} from "querystring";
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ export default class Mail {
|
|||||||
throw new MailError('Connection to mail service unsuccessful.', e);
|
throw new MailError('Connection to mail service unsuccessful.', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(`Mail ready to be distributed via ${config.get('mail.host')}:${config.get('mail.port')}`);
|
log.info(`Mail ready to be distributed via ${config.get('mail.host')}:${config.get('mail.port')}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static end(): void {
|
public static end(): void {
|
||||||
@ -103,7 +103,7 @@ export default class Mail {
|
|||||||
this.data.app = config.get('app');
|
this.data.app = config.get('app');
|
||||||
|
|
||||||
// Log
|
// Log
|
||||||
Logger.dev('Send mail', this.options);
|
log.debug('Send mail', this.options);
|
||||||
|
|
||||||
// Render email
|
// Render email
|
||||||
this.options.html = Mail.parse('mails/' + this.template.template + '.mjml.njk', this.data, false);
|
this.options.html = Mail.parse('mails/' + this.template.template + '.mjml.njk', this.data, false);
|
||||||
|
@ -3,12 +3,12 @@ import config from "config";
|
|||||||
import * as child_process from "child_process";
|
import * as child_process from "child_process";
|
||||||
import ApplicationComponent from "../ApplicationComponent";
|
import ApplicationComponent from "../ApplicationComponent";
|
||||||
import {ForbiddenHttpError} from "../HttpError";
|
import {ForbiddenHttpError} from "../HttpError";
|
||||||
import Logger from "../Logger";
|
import {log} from "../Logger";
|
||||||
|
|
||||||
export default class AutoUpdateComponent extends ApplicationComponent {
|
export default class AutoUpdateComponent extends ApplicationComponent {
|
||||||
private static async runCommand(command: string): Promise<void> {
|
private static async runCommand(command: string): Promise<void> {
|
||||||
Logger.info(`> ${command}`);
|
log.info(`> ${command}`);
|
||||||
Logger.info(child_process.execSync(command).toString());
|
log.info(child_process.execSync(command).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async checkSecuritySettings(): Promise<void> {
|
public async checkSecuritySettings(): Promise<void> {
|
||||||
@ -21,7 +21,7 @@ export default class AutoUpdateComponent extends ApplicationComponent {
|
|||||||
if (!token || token !== config.get<string>('gitlab_webhook_token'))
|
if (!token || token !== config.get<string>('gitlab_webhook_token'))
|
||||||
throw new ForbiddenHttpError('Invalid token', req.url);
|
throw new ForbiddenHttpError('Invalid token', req.url);
|
||||||
|
|
||||||
this.update(req.body).catch(Logger.error);
|
this.update(req.body).catch(req.log.error);
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
'status': 'ok',
|
'status': 'ok',
|
||||||
@ -30,10 +30,10 @@ export default class AutoUpdateComponent extends ApplicationComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async update(params: { [p: string]: unknown }) {
|
private async update(params: { [p: string]: unknown }) {
|
||||||
Logger.info('Update params:', params);
|
log.info('Update params:', params);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Logger.info('Starting auto update...');
|
log.info('Starting auto update...');
|
||||||
|
|
||||||
// Fetch
|
// Fetch
|
||||||
await AutoUpdateComponent.runCommand(`git pull`);
|
await AutoUpdateComponent.runCommand(`git pull`);
|
||||||
@ -47,9 +47,9 @@ export default class AutoUpdateComponent extends ApplicationComponent {
|
|||||||
// Stop app
|
// Stop app
|
||||||
await this.getApp().stop();
|
await this.getApp().stop();
|
||||||
|
|
||||||
Logger.info('Success!');
|
log.info('Success!');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error(e, 'An error occurred while running the auto update.');
|
log.error(e, 'An error occurred while running the auto update.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import ApplicationComponent from "../ApplicationComponent";
|
import ApplicationComponent from "../ApplicationComponent";
|
||||||
import express, {Express, Router} from "express";
|
import express, {Express, Router} from "express";
|
||||||
import Logger from "../Logger";
|
import {log, makeUniqueLogger} from "../Logger";
|
||||||
import {Server} from "http";
|
import {Server} from "http";
|
||||||
import compression from "compression";
|
import compression from "compression";
|
||||||
import Middleware from "../Middleware";
|
import Middleware from "../Middleware";
|
||||||
@ -20,7 +20,7 @@ export default class ExpressAppComponent extends ApplicationComponent {
|
|||||||
|
|
||||||
public async start(app: Express): Promise<void> {
|
public async start(app: Express): Promise<void> {
|
||||||
this.server = app.listen(this.port, this.addr, () => {
|
this.server = app.listen(this.port, this.addr, () => {
|
||||||
Logger.info(`Web server running on ${this.addr}:${this.port}.`);
|
log.info(`Web server running on ${this.addr}:${this.port}.`);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Proxy
|
// Proxy
|
||||||
@ -41,6 +41,7 @@ export default class ExpressAppComponent extends ApplicationComponent {
|
|||||||
router.use(compression());
|
router.use(compression());
|
||||||
|
|
||||||
router.use((req, res, next) => {
|
router.use((req, res, next) => {
|
||||||
|
req.log = makeUniqueLogger();
|
||||||
req.middlewares = [];
|
req.middlewares = [];
|
||||||
req.as = <M extends Middleware>(type: Type<M>): M => {
|
req.as = <M extends Middleware>(type: Type<M>): M => {
|
||||||
const middleware = req.middlewares.find(m => m.constructor === type);
|
const middleware = req.middlewares.find(m => m.constructor === type);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import ApplicationComponent from "../ApplicationComponent";
|
import ApplicationComponent from "../ApplicationComponent";
|
||||||
import onFinished from "on-finished";
|
import onFinished from "on-finished";
|
||||||
import Logger from "../Logger";
|
import {log} from "../Logger";
|
||||||
import {Request, Response, Router} from "express";
|
import {Request, Response, Router} from "express";
|
||||||
import {HttpError} from "../HttpError";
|
import {HttpError} from "../HttpError";
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ export default class LogRequestsComponent extends ApplicationComponent {
|
|||||||
|
|
||||||
public static logFullHttpRequests(): void {
|
public static logFullHttpRequests(): void {
|
||||||
this.fullRequests = true;
|
this.fullRequests = true;
|
||||||
Logger.info('Http requests will be logged with more details.');
|
log.info('Http requests will be logged with more details.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static logRequest(
|
public static logRequest(
|
||||||
@ -18,7 +18,7 @@ export default class LogRequestsComponent extends ApplicationComponent {
|
|||||||
err?: unknown,
|
err?: unknown,
|
||||||
additionalStr: string = '',
|
additionalStr: string = '',
|
||||||
silent: boolean = false,
|
silent: boolean = false,
|
||||||
): string {
|
): string | undefined {
|
||||||
if (LogRequestsComponent.fullRequests) {
|
if (LogRequestsComponent.fullRequests) {
|
||||||
const requestObj = JSON.stringify({
|
const requestObj = JSON.stringify({
|
||||||
ip: req.ip,
|
ip: req.ip,
|
||||||
@ -38,12 +38,12 @@ export default class LogRequestsComponent extends ApplicationComponent {
|
|||||||
}, null, 4);
|
}, null, 4);
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err instanceof Error) {
|
if (err instanceof Error) {
|
||||||
return Logger.error(err, requestObj, err);
|
return req.log.error(err, requestObj, err).requestId;
|
||||||
} else {
|
} else {
|
||||||
return Logger.error(new Error(String(err)), requestObj);
|
return req.log.error(new Error(String(err)), requestObj).requestId;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Logger.info(requestObj);
|
req.log.info(requestObj);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let logStr = `${req.method} ${req.originalUrl} - ${res.statusCode}`;
|
let logStr = `${req.method} ${req.originalUrl} - ${res.statusCode}`;
|
||||||
@ -52,15 +52,15 @@ export default class LogRequestsComponent extends ApplicationComponent {
|
|||||||
if (silent) {
|
if (silent) {
|
||||||
if (err instanceof HttpError) logStr += ` ${err.errorCode}`;
|
if (err instanceof HttpError) logStr += ` ${err.errorCode}`;
|
||||||
logStr += ` ${err.name}`;
|
logStr += ` ${err.name}`;
|
||||||
return Logger.silentError(err, logStr);
|
return req.log.error(err, logStr, additionalStr).requestId;
|
||||||
} else {
|
} else {
|
||||||
return Logger.error(err, logStr, additionalStr, err);
|
return req.log.error(err, logStr, additionalStr, err).requestId;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Logger.error(new Error(String(err)), logStr);
|
return req.log.error(new Error(String(err)), logStr).requestId;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Logger.info(logStr);
|
req.log.info(logStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import {ParsedUrlQueryInput} from "querystring";
|
|||||||
import * as util from "util";
|
import * as util from "util";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import Logger from "../Logger";
|
import {log} from "../Logger";
|
||||||
import Middleware from "../Middleware";
|
import Middleware from "../Middleware";
|
||||||
|
|
||||||
export default class NunjucksComponent extends ApplicationComponent {
|
export default class NunjucksComponent extends ApplicationComponent {
|
||||||
@ -29,7 +29,7 @@ export default class NunjucksComponent extends ApplicationComponent {
|
|||||||
try {
|
try {
|
||||||
coreVersion = JSON.parse(fs.readFileSync(file).toString()).version;
|
coreVersion = JSON.parse(fs.readFileSync(file).toString()).version;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.warn('Couldn\'t determine coreVersion.', e);
|
log.warn('Couldn\'t determine coreVersion.', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.env = new nunjucks.Environment([
|
this.env = new nunjucks.Environment([
|
||||||
|
@ -2,7 +2,6 @@ import ApplicationComponent from "../ApplicationComponent";
|
|||||||
import {Request, Router} from "express";
|
import {Request, Router} from "express";
|
||||||
import {ServerError} from "../HttpError";
|
import {ServerError} from "../HttpError";
|
||||||
import onFinished from "on-finished";
|
import onFinished from "on-finished";
|
||||||
import Logger from "../Logger";
|
|
||||||
|
|
||||||
export default class RedirectBackComponent extends ApplicationComponent {
|
export default class RedirectBackComponent extends ApplicationComponent {
|
||||||
public static getPreviousURL(req: Request, defaultUrl?: string): string | undefined {
|
public static getPreviousURL(req: Request, defaultUrl?: string): string | undefined {
|
||||||
@ -29,10 +28,10 @@ export default class RedirectBackComponent extends ApplicationComponent {
|
|||||||
contentType && typeof contentType !== 'number' && contentType.indexOf('text/html') >= 0
|
contentType && typeof contentType !== 'number' && contentType.indexOf('text/html') >= 0
|
||||||
)) {
|
)) {
|
||||||
session.previousUrl = req.originalUrl;
|
session.previousUrl = req.originalUrl;
|
||||||
Logger.debug('Prev url set to', session.previousUrl);
|
req.log.debug('Prev url set to', session.previousUrl);
|
||||||
session.save((err) => {
|
session.save((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
Logger.error(err, 'Error while saving session');
|
req.log.error(err, 'Error while saving session');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import ApplicationComponent from "../ApplicationComponent";
|
|||||||
import {Express} from "express";
|
import {Express} from "express";
|
||||||
import redis, {RedisClient} from "redis";
|
import redis, {RedisClient} from "redis";
|
||||||
import config from "config";
|
import config from "config";
|
||||||
import Logger from "../Logger";
|
import {log} from "../Logger";
|
||||||
import session, {Store} from "express-session";
|
import session, {Store} from "express-session";
|
||||||
import connect_redis from "connect-redis";
|
import connect_redis from "connect-redis";
|
||||||
import CacheProvider from "../CacheProvider";
|
import CacheProvider from "../CacheProvider";
|
||||||
@ -18,7 +18,7 @@ export default class RedisComponent extends ApplicationComponent implements Cach
|
|||||||
password: config.has('redis.password') ? config.get<string>('redis.password') : undefined,
|
password: config.has('redis.password') ? config.get<string>('redis.password') : undefined,
|
||||||
});
|
});
|
||||||
this.redisClient.on('error', (err: Error) => {
|
this.redisClient.on('error', (err: Error) => {
|
||||||
Logger.error(err, 'An error occurred with redis.');
|
log.error(err, 'An error occurred with redis.');
|
||||||
});
|
});
|
||||||
this.store = new RedisStore({
|
this.store = new RedisStore({
|
||||||
client: this.redisClient,
|
client: this.redisClient,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import ApplicationComponent from "../ApplicationComponent";
|
import ApplicationComponent from "../ApplicationComponent";
|
||||||
import {Express, Request} from "express";
|
import {Express, Request} from "express";
|
||||||
import WebSocket, {Server as WebSocketServer} from "ws";
|
import WebSocket, {Server as WebSocketServer} from "ws";
|
||||||
import Logger from "../Logger";
|
import {log} from "../Logger";
|
||||||
import cookie from "cookie";
|
import cookie from "cookie";
|
||||||
import cookieParser from "cookie-parser";
|
import cookieParser from "cookie-parser";
|
||||||
import config from "config";
|
import config from "config";
|
||||||
@ -28,9 +28,9 @@ export default class WebSocketServerComponent extends ApplicationComponent {
|
|||||||
this.wss = new WebSocketServer({
|
this.wss = new WebSocketServer({
|
||||||
server: this.expressAppComponent.getServer(),
|
server: this.expressAppComponent.getServer(),
|
||||||
}, () => {
|
}, () => {
|
||||||
Logger.info(`Websocket server started over webserver.`);
|
log.info(`Websocket server started over webserver.`);
|
||||||
}).on('error', (err) => {
|
}).on('error', (err) => {
|
||||||
Logger.error(err, 'An error occurred in the websocket server.');
|
log.error(err, 'An error occurred in the websocket server.');
|
||||||
}).on('connection', (socket, request) => {
|
}).on('connection', (socket, request) => {
|
||||||
const listener = request.url ? listeners[request.url] : null;
|
const listener = request.url ? listeners[request.url] : null;
|
||||||
|
|
||||||
@ -39,12 +39,12 @@ export default class WebSocketServerComponent extends ApplicationComponent {
|
|||||||
return;
|
return;
|
||||||
} else if (!request.headers.cookie) {
|
} else if (!request.headers.cookie) {
|
||||||
listener.handle(socket, request, null).catch(err => {
|
listener.handle(socket, request, null).catch(err => {
|
||||||
Logger.error(err, 'Error in websocket listener.');
|
log.error(err, 'Error in websocket listener.');
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.debug(`Websocket on ${request.url}`);
|
log.debug(`Websocket on ${request.url}`);
|
||||||
|
|
||||||
const cookies = cookie.parse(request.headers.cookie);
|
const cookies = cookie.parse(request.headers.cookie);
|
||||||
const sid = cookieParser.signedCookie(cookies['connect.sid'], config.get('session.secret'));
|
const sid = cookieParser.signedCookie(cookies['connect.sid'], config.get('session.secret'));
|
||||||
@ -57,7 +57,7 @@ export default class WebSocketServerComponent extends ApplicationComponent {
|
|||||||
const store = this.storeComponent.getStore();
|
const store = this.storeComponent.getStore();
|
||||||
store.get(sid, (err, session) => {
|
store.get(sid, (err, session) => {
|
||||||
if (err || !session) {
|
if (err || !session) {
|
||||||
Logger.error(err, 'Error while initializing session in websocket.');
|
log.error(err, 'Error while initializing session in websocket.');
|
||||||
socket.close(1011);
|
socket.close(1011);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ export default class WebSocketServerComponent extends ApplicationComponent {
|
|||||||
|
|
||||||
store.createSession(<Request>request, session);
|
store.createSession(<Request>request, session);
|
||||||
listener.handle(socket, request, <Express.Session>session).catch(err => {
|
listener.handle(socket, request, <Express.Session>session).catch(err => {
|
||||||
Logger.error(err, 'Error in websocket listener.');
|
log.error(err, 'Error in websocket listener.');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import mysql, {Connection, FieldInfo, MysqlError, Pool, PoolConnection} from 'mysql';
|
import mysql, {Connection, FieldInfo, MysqlError, Pool, PoolConnection} from 'mysql';
|
||||||
import config from 'config';
|
import config from 'config';
|
||||||
import Migration, {MigrationType} from "./Migration";
|
import Migration, {MigrationType} from "./Migration";
|
||||||
import Logger from "../Logger";
|
import {log} from "../Logger";
|
||||||
import {Type} from "../Utils";
|
import {Type} from "../Utils";
|
||||||
|
|
||||||
export interface QueryResult {
|
export interface QueryResult {
|
||||||
@ -50,7 +50,7 @@ export default class MysqlConnectionManager {
|
|||||||
public static async prepare(runMigrations: boolean = true): Promise<void> {
|
public static async prepare(runMigrations: boolean = true): Promise<void> {
|
||||||
if (config.get('mysql.create_database_automatically') === true) {
|
if (config.get('mysql.create_database_automatically') === true) {
|
||||||
const dbName = config.get('mysql.database');
|
const dbName = config.get('mysql.database');
|
||||||
Logger.info(`Creating database ${dbName}...`);
|
log.info(`Creating database ${dbName}...`);
|
||||||
const connection = mysql.createConnection({
|
const connection = mysql.createConnection({
|
||||||
host: config.get('mysql.host'),
|
host: config.get('mysql.host'),
|
||||||
user: config.get('mysql.user'),
|
user: config.get('mysql.user'),
|
||||||
@ -65,7 +65,7 @@ export default class MysqlConnectionManager {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
connection.end();
|
connection.end();
|
||||||
Logger.info(`Database ${dbName} created!`);
|
log.info(`Database ${dbName} created!`);
|
||||||
}
|
}
|
||||||
this.databaseReady = true;
|
this.databaseReady = true;
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ export default class MysqlConnectionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.currentPool.end(() => {
|
this.currentPool.end(() => {
|
||||||
Logger.info('Mysql connection pool ended.');
|
log.info('Mysql connection pool ended.');
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
this.currentPool = undefined;
|
this.currentPool = undefined;
|
||||||
@ -110,7 +110,9 @@ export default class MysqlConnectionManager {
|
|||||||
connection?: Connection,
|
connection?: Connection,
|
||||||
): Promise<QueryResult> {
|
): Promise<QueryResult> {
|
||||||
return await new Promise<QueryResult>((resolve, reject) => {
|
return await new Promise<QueryResult>((resolve, reject) => {
|
||||||
Logger.dev('SQL:', Logger.isVerboseMode() ? mysql.format(queryString, values) : queryString);
|
log.debug('SQL:', log.settings.minLevel === 'trace' || log.settings.minLevel === 'silly' ?
|
||||||
|
mysql.format(queryString, values) :
|
||||||
|
queryString);
|
||||||
|
|
||||||
(connection ? connection : this.pool).query(queryString, values, (error, results, fields) => {
|
(connection ? connection : this.pool).query(queryString, values, (error, results, fields) => {
|
||||||
if (error !== null) {
|
if (error !== null) {
|
||||||
@ -193,7 +195,7 @@ export default class MysqlConnectionManager {
|
|||||||
const currentVersion = await this.getCurrentMigrationVersion();
|
const currentVersion = await this.getCurrentMigrationVersion();
|
||||||
for (const migration of this.migrations) {
|
for (const migration of this.migrations) {
|
||||||
if (await migration.shouldRun(currentVersion)) {
|
if (await migration.shouldRun(currentVersion)) {
|
||||||
Logger.info('Running migration ', migration.version, migration.constructor.name);
|
log.info('Running migration ', migration.version, migration.constructor.name);
|
||||||
await MysqlConnectionManager.wrapTransaction<void>(async c => {
|
await MysqlConnectionManager.wrapTransaction<void>(async c => {
|
||||||
await migration.install(c);
|
await migration.install(c);
|
||||||
await query('INSERT INTO migrations VALUES(?, ?, NOW())', [
|
await query('INSERT INTO migrations VALUES(?, ?, NOW())', [
|
||||||
@ -215,7 +217,7 @@ export default class MysqlConnectionManager {
|
|||||||
public static async rollbackMigration(migrationId: number = 0): Promise<void> {
|
public static async rollbackMigration(migrationId: number = 0): Promise<void> {
|
||||||
migrationId--;
|
migrationId--;
|
||||||
const migration = this.migrations[migrationId];
|
const migration = this.migrations[migrationId];
|
||||||
Logger.info('Rolling back migration ', migration.version, migration.constructor.name);
|
log.info('Rolling back migration ', migration.version, migration.constructor.name);
|
||||||
await MysqlConnectionManager.wrapTransaction<void>(async c => {
|
await MysqlConnectionManager.wrapTransaction<void>(async c => {
|
||||||
await migration.rollback(c);
|
await migration.rollback(c);
|
||||||
await query('DELETE FROM migrations WHERE id=?', [migration.version]);
|
await query('DELETE FROM migrations WHERE id=?', [migration.version]);
|
||||||
@ -224,7 +226,7 @@ export default class MysqlConnectionManager {
|
|||||||
|
|
||||||
public static async migrationCommand(args: string[]): Promise<void> {
|
public static async migrationCommand(args: string[]): Promise<void> {
|
||||||
try {
|
try {
|
||||||
Logger.info('Current migration:', await this.getCurrentMigrationVersion());
|
log.info('Current migration:', await this.getCurrentMigrationVersion());
|
||||||
|
|
||||||
for (let i = 0; i < args.length; i++) {
|
for (let i = 0; i < args.length; i++) {
|
||||||
if (args[i] === 'rollback') {
|
if (args[i] === 'rollback') {
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
import Migration from "../db/Migration";
|
|
||||||
import {Connection} from "mysql";
|
|
||||||
import ModelFactory from "../db/ModelFactory";
|
|
||||||
import Log from "../models/Log";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Must be the first migration
|
|
||||||
*/
|
|
||||||
export default class CreateLogsTable extends Migration {
|
|
||||||
public async install(connection: Connection): Promise<void> {
|
|
||||||
await this.query(`CREATE TABLE logs
|
|
||||||
(
|
|
||||||
id INT NOT NULL AUTO_INCREMENT,
|
|
||||||
level TINYINT UNSIGNED NOT NULL,
|
|
||||||
message TEXT NOT NULL,
|
|
||||||
log_id BINARY(16),
|
|
||||||
error_name VARCHAR(128),
|
|
||||||
error_message VARCHAR(512),
|
|
||||||
error_stack TEXT,
|
|
||||||
created_at DATETIME NOT NULL DEFAULT NOW(),
|
|
||||||
PRIMARY KEY (id)
|
|
||||||
)`, connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async rollback(connection: Connection): Promise<void> {
|
|
||||||
await this.query('DROP TABLE logs', connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
public registerModels(): void {
|
|
||||||
ModelFactory.register(Log);
|
|
||||||
}
|
|
||||||
}
|
|
12
src/migrations/DropLegacyLogsTable.ts
Normal file
12
src/migrations/DropLegacyLogsTable.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import Migration from "../db/Migration";
|
||||||
|
import {Connection} from "mysql";
|
||||||
|
|
||||||
|
export default class DropLegacyLogsTable extends Migration {
|
||||||
|
public async install(connection: Connection): Promise<void> {
|
||||||
|
await this.query('DROP TABLE IF EXIST logs', connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async rollback(): Promise<void> {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
}
|
11
src/migrations/DummyMigration.ts
Normal file
11
src/migrations/DummyMigration.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import Migration from "../db/Migration";
|
||||||
|
|
||||||
|
export default class DummyMigration extends Migration {
|
||||||
|
public async install(): Promise<void> {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public async rollback(): Promise<void> {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
}
|
@ -1,60 +0,0 @@
|
|||||||
import Model from "../db/Model";
|
|
||||||
import {LogLevel, LogLevelKeys} from "../Logger";
|
|
||||||
import {bufferToUuid} from "../Utils";
|
|
||||||
|
|
||||||
export default class Log extends Model {
|
|
||||||
public readonly id?: number = undefined;
|
|
||||||
private level?: number = undefined;
|
|
||||||
public message?: string = undefined;
|
|
||||||
private log_id?: Buffer = undefined;
|
|
||||||
private error_name?: string = undefined;
|
|
||||||
private error_message?: string = undefined;
|
|
||||||
private error_stack?: string = undefined;
|
|
||||||
private created_at?: Date = undefined;
|
|
||||||
|
|
||||||
protected init(): void {
|
|
||||||
this.setValidation('level').defined();
|
|
||||||
this.setValidation('message').defined().between(0, 65535);
|
|
||||||
this.setValidation('log_id').acceptUndefined().length(16);
|
|
||||||
this.setValidation('error_name').acceptUndefined().between(0, 128);
|
|
||||||
this.setValidation('error_message').acceptUndefined().between(0, 512);
|
|
||||||
this.setValidation('error_stack').acceptUndefined().between(0, 65535);
|
|
||||||
}
|
|
||||||
|
|
||||||
public getLevel(): LogLevelKeys {
|
|
||||||
if (typeof this.level !== 'number') return 'ERROR';
|
|
||||||
return <LogLevelKeys>LogLevel[this.level];
|
|
||||||
}
|
|
||||||
|
|
||||||
public setLevel(level: LogLevel): void {
|
|
||||||
this.level = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getLogId(): string | null {
|
|
||||||
return this.log_id ? bufferToUuid(this.log_id) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setLogId(buffer: Buffer): void {
|
|
||||||
this.log_id = buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getErrorName(): string {
|
|
||||||
return this.error_name || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public getErrorMessage(): string {
|
|
||||||
return this.error_message || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public getErrorStack(): string {
|
|
||||||
return this.error_stack || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public setError(error?: Error): void {
|
|
||||||
if (!error) return;
|
|
||||||
|
|
||||||
this.error_name = error.name;
|
|
||||||
this.error_message = error.message;
|
|
||||||
this.error_stack = error.stack;
|
|
||||||
}
|
|
||||||
}
|
|
3
src/types/Express.d.ts
vendored
3
src/types/Express.d.ts
vendored
@ -2,10 +2,13 @@ import {Files} from "formidable";
|
|||||||
import {Type} from "../Utils";
|
import {Type} from "../Utils";
|
||||||
import Middleware from "../Middleware";
|
import Middleware from "../Middleware";
|
||||||
import {FlashMessages} from "../components/SessionComponent";
|
import {FlashMessages} from "../components/SessionComponent";
|
||||||
|
import {Logger} from "tslog";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
namespace Express {
|
namespace Express {
|
||||||
export interface Request {
|
export interface Request {
|
||||||
|
log: Logger;
|
||||||
|
|
||||||
getSession(): Session;
|
getSession(): Session;
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import Model from "../src/db/Model";
|
|||||||
import {MIGRATIONS} from "./_migrations";
|
import {MIGRATIONS} from "./_migrations";
|
||||||
import ModelFactory from "../src/db/ModelFactory";
|
import ModelFactory from "../src/db/ModelFactory";
|
||||||
import {ValidationBag} from "../src/db/Validator";
|
import {ValidationBag} from "../src/db/Validator";
|
||||||
import Logger from "../src/Logger";
|
import {log} from "../src/Logger";
|
||||||
import {ManyThroughModelRelation, OneModelRelation} from "../src/db/ModelRelation";
|
import {ManyThroughModelRelation, OneModelRelation} from "../src/db/ModelRelation";
|
||||||
|
|
||||||
class FakeDummyModel extends Model {
|
class FakeDummyModel extends Model {
|
||||||
@ -99,7 +99,7 @@ let roleFactory: ModelFactory<Role>;
|
|||||||
let permissionFactory: ModelFactory<Permission>;
|
let permissionFactory: ModelFactory<Permission>;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
Logger.verbose();
|
log.setSettings({minLevel: "trace"});
|
||||||
MysqlConnectionManager.registerMigrations(MIGRATIONS);
|
MysqlConnectionManager.registerMigrations(MIGRATIONS);
|
||||||
ModelFactory.register(FakeDummyModel);
|
ModelFactory.register(FakeDummyModel);
|
||||||
ModelFactory.register(Post);
|
ModelFactory.register(Post);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import CreateMigrationsTable from "../src/migrations/CreateMigrationsTable";
|
import CreateMigrationsTable from "../src/migrations/CreateMigrationsTable";
|
||||||
import CreateLogsTable from "../src/migrations/CreateLogsTable";
|
|
||||||
import CreateUsersAndUserEmailsTable from "../src/auth/migrations/CreateUsersAndUserEmailsTable";
|
import CreateUsersAndUserEmailsTable from "../src/auth/migrations/CreateUsersAndUserEmailsTable";
|
||||||
import FixUserMainEmailRelation from "../src/auth/migrations/FixUserMainEmailRelation";
|
import FixUserMainEmailRelation from "../src/auth/migrations/FixUserMainEmailRelation";
|
||||||
import DropNameFromUsers from "../src/auth/migrations/DropNameFromUsers";
|
import DropNameFromUsers from "../src/auth/migrations/DropNameFromUsers";
|
||||||
@ -7,7 +6,6 @@ import CreateMagicLinksTable from "../src/auth/migrations/CreateMagicLinksTable"
|
|||||||
|
|
||||||
export const MIGRATIONS = [
|
export const MIGRATIONS = [
|
||||||
CreateMigrationsTable,
|
CreateMigrationsTable,
|
||||||
CreateLogsTable,
|
|
||||||
CreateUsersAndUserEmailsTable,
|
CreateUsersAndUserEmailsTable,
|
||||||
FixUserMainEmailRelation,
|
FixUserMainEmailRelation,
|
||||||
DropNameFromUsers,
|
DropNameFromUsers,
|
||||||
|
@ -5621,7 +5621,7 @@ source-map-resolve@^0.5.0:
|
|||||||
source-map-url "^0.4.0"
|
source-map-url "^0.4.0"
|
||||||
urix "^0.1.0"
|
urix "^0.1.0"
|
||||||
|
|
||||||
source-map-support@^0.5.17, source-map-support@^0.5.6:
|
source-map-support@^0.5.17, source-map-support@^0.5.19, source-map-support@^0.5.6:
|
||||||
version "0.5.19"
|
version "0.5.19"
|
||||||
resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
|
resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
|
||||||
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
|
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
|
||||||
@ -6058,6 +6058,13 @@ tslib@^1.8.1:
|
|||||||
resolved "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
|
resolved "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
|
||||||
integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==
|
integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==
|
||||||
|
|
||||||
|
tslog@^2.10.0:
|
||||||
|
version "2.10.0"
|
||||||
|
resolved "https://registry.npmjs.org/tslog/-/tslog-2.10.0.tgz#725fe08e097b31dfabbb1b67929a81b7351dda8f"
|
||||||
|
integrity sha512-quVCes9HYxR3gHkT1JgDPj56OzbFeMxdKKbJwCMEW2lRSM80Awcr/WbBMTqzu9PI++mD9IDwIT4MJOa5CKh99Q==
|
||||||
|
dependencies:
|
||||||
|
source-map-support "^0.5.19"
|
||||||
|
|
||||||
tsutils@^3.17.1:
|
tsutils@^3.17.1:
|
||||||
version "3.17.1"
|
version "3.17.1"
|
||||||
resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"
|
resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"
|
||||||
|
Loading…
Reference in New Issue
Block a user