@halsp/core
Version:
面向云的现代渐进式轻量 Node.js 框架
123 lines • 3.69 kB
JavaScript
import { isClass, isObject } from "../utils/index.mjs";
import { HookType } from "../hook/index.mjs";
import { execConstructorHooks, execErrorHooks, execHooks, execUnhandledHooks, } from "../hook/hook.exec.mjs";
function isMiddlewareConstructor(md) {
return !!md.prototype;
}
export async function createMiddleware(ctx, middleware) {
if (middleware instanceof Middleware) {
return middleware;
}
else if (isMiddlewareConstructor(middleware)) {
return await execConstructorHooks(ctx, middleware);
}
else if (Array.isArray(middleware)) {
return createMiddleware(ctx, await middleware[0](ctx));
}
else {
return createMiddleware(ctx, await middleware(ctx));
}
}
export class Middleware {
#index;
#mds;
#ctx;
get ctx() {
return this.#ctx;
}
get req() {
return this.#ctx.req;
}
get request() {
return this.#ctx.req;
}
get res() {
return this.#ctx.res;
}
get response() {
return this.#ctx.response;
}
get logger() {
return this.ctx.logger;
}
set logger(val) {
this.ctx.logger = val;
}
isPrevInstanceOf(target) {
const prevMd = this.#mds[this.#index - 1];
return this.#isInstanceOf(prevMd, target);
}
isNextInstanceOf(target) {
const nextMd = this.#mds[this.#index + 1];
return this.#isInstanceOf(nextMd, target);
}
#isInstanceOf(md, target) {
if (!md)
return false;
if (md == target)
return true;
if (Array.isArray(md)) {
return md[1] == target || md[1].prototype instanceof target;
}
else if (isClass(md)) {
return md.prototype instanceof target;
}
else {
return md instanceof target;
}
}
async next() {
let nextMd = undefined;
try {
if (false == (await execHooks(this.ctx, HookType.BeforeNext, this))) {
return;
}
if (this.#mds.length <= this.#index + 1)
return;
nextMd = await this.#createNextMiddleware();
nextMd.init(this.ctx, this.#index + 1, this.#mds);
if (false == (await execHooks(this.ctx, HookType.BeforeInvoke, nextMd))) {
return;
}
await nextMd.invoke();
await execHooks(this.ctx, HookType.AfterInvoke, nextMd);
}
catch (err) {
const error = err;
if (isObject(error) && "breakthrough" in error && error.breakthrough) {
throw error;
}
else {
const md = nextMd ?? this;
const hookResult = await execErrorHooks(this.ctx, md, error);
if (!hookResult) {
await execUnhandledHooks(this.ctx, md, error);
}
}
}
}
#createNextMiddleware = async () => {
const middleware = this.#mds[this.#index + 1];
return await createMiddleware(this.ctx, middleware);
};
init(ctx, index, mds) {
this.#mds = mds;
this.#ctx = ctx;
this.#index = index;
return this;
}
}
export async function invokeMiddlewares(ctx, mds, isRoot = false) {
const md = await createMiddleware(ctx, mds[0]);
try {
await md.init(ctx, 0, mds).invoke();
}
catch (err) {
const error = err;
const hookResult = await execErrorHooks(ctx, md, error);
if (isRoot && !hookResult) {
await execUnhandledHooks(ctx, md, error);
}
}
}
//# sourceMappingURL=middleware.js.map