honion
Version:
119 lines (104 loc) • 3.18 kB
text/typescript
import { Context } from "./context";
import { BaseLogger, ILogger } from "./logger";
import {
Middleware,
MdHook,
HookMiddleware,
HookType,
MiddlewareItem,
invokeMiddlewares,
MiddlewareConstructor,
} from "./middlewares";
import {
initContainer,
MiddlewareContainer,
} from "./middlewares/middleware-container";
export abstract class Honion<TC extends Context = Context> {
constructor() {
initContainer(this, this.#mds);
}
readonly #mds: MiddlewareItem[] = [];
hook<TM extends Middleware<TC> = Middleware<TC>>(
type: HookType.Constructor,
mh: (
ctx: TC,
middlewareConstructor: MiddlewareConstructor<TC, TM>
) => TM | undefined
): this;
hook<TM extends Middleware<TC> = Middleware<TC>>(
type: HookType.Constructor,
mh: (
ctx: TC,
middlewareConstructor: MiddlewareConstructor<TC, TM>
) => Promise<TM | undefined>
): this;
hook<TM extends Middleware<TC> = Middleware<TC>, TE extends Error = Error>(
type: HookType.Error,
mh: (ctx: TC, middleware: TM, error: TE) => boolean
): this;
hook<TM extends Middleware<TC> = Middleware<TC>, TE extends Error = Error>(
type: HookType.Error,
mh: (ctx: TC, middleware: TM, error: TE) => Promise<boolean>
): this;
hook<TM extends Middleware<TC> = Middleware<TC>>(
type: HookType.BeforeInvoke | HookType.BeforeNext,
mh: (ctx: TC, middleware: TM) => boolean | void
): this;
hook<TM extends Middleware<TC> = Middleware<TC>>(
type: HookType.BeforeInvoke | HookType.BeforeNext,
mh: (ctx: TC, middleware: TM) => Promise<boolean | void>
): this;
hook<TM extends Middleware<TC> = Middleware<TC>>(
type: HookType.AfterInvoke,
mh: (ctx: TC, middleware: TM) => void
): this;
hook<TM extends Middleware<TC> = Middleware<TC>>(
type: HookType.AfterInvoke,
mh: (ctx: TC, middleware: TM) => Promise<void>
): this;
hook<TM extends Middleware<TC> = Middleware<TC>>(
mh: (ctx: TC, middleware: TM) => void
): this;
hook<TM extends Middleware<TC> = Middleware<TC>>(
mh: (ctx: TC, middleware: TM) => Promise<void>
): this;
hook<TM extends Middleware<TC> = Middleware<TC>>(
arg1: MdHook<TC, TM> | HookType,
arg2?: MdHook<TC, TM> | HookType
): this {
let mh: MdHook<TC, TM>;
let type: HookType;
if (typeof arg1 == "function") {
mh = arg1;
type = HookType.BeforeInvoke;
} else {
type = arg1;
mh = arg2 as MdHook<TC, TM>;
}
this.#mds.push(() => new HookMiddleware(mh, type));
return this;
}
protected async invoke(ctx?: any): Promise<any> {
ctx = ctx ?? (new Context() as TC);
Object.defineProperty(ctx, "honion", {
configurable: true,
get: () => this,
});
if (!this.#mds.length) {
return ctx;
}
try {
await invokeMiddlewares(ctx, this.#mds);
} catch (err) {
ctx.catchError(err);
}
return ctx;
}
logger: ILogger = new BaseLogger();
setLogger(logger: ILogger) {
this.logger = logger;
}
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface Honion<TC extends Context = Context>
extends MiddlewareContainer<TC> {}