75 lines
2.0 KiB
TypeScript
75 lines
2.0 KiB
TypeScript
import {Express, Router} from "express";
|
|
import Logger from "./Logger";
|
|
import {sleep} from "./Utils";
|
|
import Application from "./Application";
|
|
import config from "config";
|
|
import SecurityError from "./SecurityError";
|
|
|
|
export default abstract class ApplicationComponent<T> {
|
|
private val?: T;
|
|
protected app?: Application;
|
|
|
|
public async checkSecuritySettings(): Promise<void> {
|
|
}
|
|
|
|
public async start(app: Express): Promise<void> {
|
|
}
|
|
|
|
public async init(router: Router): Promise<void> {
|
|
}
|
|
|
|
public async handle(router: Router): Promise<void> {
|
|
}
|
|
|
|
public async stop(): Promise<void> {
|
|
|
|
}
|
|
|
|
protected export(val: T) {
|
|
this.val = val;
|
|
}
|
|
|
|
public import(): T {
|
|
if (!this.val) throw 'Cannot import if nothing was exported.';
|
|
return this.val;
|
|
}
|
|
|
|
public setApp(app: Application) {
|
|
this.app = app;
|
|
}
|
|
|
|
protected async prepare(name: string, prepare: () => Promise<void>): Promise<void> {
|
|
let err;
|
|
do {
|
|
try {
|
|
await prepare();
|
|
err = null;
|
|
} catch (e) {
|
|
err = e;
|
|
Logger.error(err, `${name} failed to prepare; retrying in 5s...`)
|
|
await sleep(5000);
|
|
}
|
|
} while (err);
|
|
Logger.info(`${name} ready!`);
|
|
}
|
|
|
|
protected async close(thingName: string, thing: any, fn: Function): Promise<void> {
|
|
try {
|
|
await new Promise((resolve, reject) => fn.call(thing, (err: any) => {
|
|
if (err) reject(err);
|
|
else resolve();
|
|
}));
|
|
|
|
Logger.info(`${thingName} closed.`);
|
|
} catch (e) {
|
|
Logger.error(e, `An error occurred while closing the ${thingName}.`);
|
|
}
|
|
}
|
|
|
|
protected checkSecurityConfigField(field: string) {
|
|
if (!config.has(field) || config.get<string>(field) === 'default') {
|
|
throw new SecurityError(`${field} field not configured.`);
|
|
}
|
|
}
|
|
}
|