swaf/src/ApplicationComponent.ts

75 lines
1.9 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 not configured.');
}
}
}