axios-miniprogram/src/core/MiddlewareManager.ts

77 lines
2.0 KiB
TypeScript
Raw Normal View History

2023-04-23 23:05:30 +08:00
import { assert } from '../helpers/error';
import { combineURL } from '../helpers/combineURL';
import { isFunction, isString } from '../helpers/isTypes';
2023-04-23 23:05:30 +08:00
export interface MiddlewareNext {
(): Promise<void>;
}
2023-04-25 14:28:28 +08:00
export interface MiddlewareCallback<Context extends AnyObject> {
(ctx: Context, next: MiddlewareNext): Promise<void>;
2023-04-23 23:05:30 +08:00
}
2023-04-25 14:28:28 +08:00
export interface MiddlewareUse<Context extends AnyObject> {
/**
*
*
* @param path
* @param callback
*/
(
path: string,
callback: MiddlewareCallback<Context>,
): MiddlewareManager<Context>;
/**
*
*
* @param callback
*/
(callback: MiddlewareCallback<Context>): MiddlewareManager<Context>;
2023-04-23 23:05:30 +08:00
}
2023-04-25 14:28:28 +08:00
export default class MiddlewareManager<Context extends AnyObject = AnyObject> {
#map = new Map<string, MiddlewareCallback<Context>[]>();
2023-04-25 14:28:28 +08:00
/**
*
*/
use: MiddlewareUse<Context> = (
path: string | MiddlewareCallback<Context>,
callback?: MiddlewareCallback<Context>,
) => {
2023-04-23 23:05:30 +08:00
if (isFunction(path)) {
callback = path;
path = '/';
}
assert(isString(path), 'path 不是一个 string');
assert(!!path, 'path 不是一个长度大于零的 string');
assert(isFunction(callback), 'callback 不是一个 function');
2023-04-23 23:05:30 +08:00
const middlewares = this.#map.get(path) ?? [];
middlewares.push(callback!);
this.#map.set(path, middlewares);
return this;
2023-04-25 14:28:28 +08:00
};
2023-04-23 23:05:30 +08:00
2023-04-25 14:28:28 +08:00
flush(ctx: Context, finish: MiddlewareNext) {
const allMiddlewares: MiddlewareCallback<Context>[] = [];
2023-04-23 23:05:30 +08:00
2023-04-25 14:28:28 +08:00
for (const [path, middlewares] of this.#map.entries()) {
const url = combineURL(ctx.req.baseURL, path);
const checkRE = new RegExp(`^${url}([/?].*)?`);
2023-04-23 23:05:30 +08:00
2023-04-25 14:28:28 +08:00
if (path === '/') {
allMiddlewares.push(...middlewares);
} else if (checkRE.test(ctx.req.url!)) {
allMiddlewares.push(...middlewares);
2023-04-23 23:05:30 +08:00
}
2023-04-25 14:28:28 +08:00
}
2023-04-23 23:05:30 +08:00
2023-04-25 14:28:28 +08:00
const tasks = [...allMiddlewares, finish];
return (function next(): Promise<void> {
return tasks.shift()!(ctx, next);
})();
2023-04-23 23:05:30 +08:00
}
}