@akala/core
Version:
102 lines • 4.37 kB
JavaScript
import { convertToMiddleware } from '../middlewares/shared.js';
import { MiddlewareCompositeAsync } from '../middlewares/composite-async.js';
import { MiddlewareRouteAsync } from './route-async.js';
import { each } from '../each.js';
/**
* Dynamically applies asynchronous routes to a middleware composite.
*
* This function recursively processes route definitions and attaches them to the parent middleware chain.
*
* @template T - The context type containing the routable request and parameters.
* @template TSpecialNextParam - The type for special next parameters (defaults to {@link SpecialNextParam})
* @param {Routes<T, Promise<unknown>, TSpecialNextParam>} routes - Route definitions mapping URI templates to handler functions or nested route objects
* @param {MiddlewareCompositeAsync<T, TSpecialNextParam> & { route: RouteBuilderAsync<T, TSpecialNextParam> }} [parent] - Parent middleware container to attach routes to
* @returns {MiddlewareCompositeAsync<T, TSpecialNextParam>} Configured middleware composite with attached routes
*/
export function useRoutesAsync(routes, parent) {
if (!parent)
parent = Object.assign(new MiddlewareCompositeAsync('byroutes'), { route(...args) { return new MiddlewareRouteAsync(...args); } });
each(routes, (route, match) => {
if (typeof match == 'number')
return;
const routed = new MiddlewareRouteAsync(match);
if (typeof (route) == 'object') {
useRoutesAsync(route, routed);
}
else
routed.useMiddleware(convertToMiddleware(route));
parent.useMiddleware(routed);
});
return parent;
}
/**
* Base class for defining asynchronous routing middleware chains.
*
* Extends the middleware composite to provide route configuration capabilities for asynchronous handlers.
*
* @template T - The context type containing the routable request and parameters
* @template TSpecialNextParam - The type for special next parameters (defaults to {@link SpecialNextParam})
* @extends {MiddlewareCompositeAsync<T, TSpecialNextParam>}
* @implements {MiddlewareAsync<T, TSpecialNextParam>}
*/
export class RouterAsync extends MiddlewareCompositeAsync {
/**
* Creates a new RouterAsync instance with optional configuration.
*
* @param {RouterOptions} [options] - Configuration options including middleware priority and name
*/
constructor(options) {
super(options?.name);
}
/**
* Creates a new route configuration chain for defining route handlers.
*
* @function route
* @param {...RouteBuilderArguments} args - Route configuration parameters (path template, HTTP method, etc.)
* @returns {MiddlewareRouteAsync<T, TSpecialNextParam>} Newly created route configuration instance
*/
route(...args) {
return new MiddlewareRouteAsync(...args);
}
/**
* Attaches a collection of route definitions to the router.
*
* @param {Routes<T, Promise<unknown>, TSpecialNextParam>} routes - Route definitions to be applied
* @returns {this} Current router instance for method chaining
*/
useRoutes(routes) {
useRoutesAsync(routes, this);
return this;
}
useMiddleware(routeOrMiddleware, ...middlewares) {
if (typeof routeOrMiddleware === 'string' || Array.isArray(routeOrMiddleware)) {
const routed = new MiddlewareRouteAsync(routeOrMiddleware);
routed.useMiddleware(...middlewares);
super.useMiddleware(routed);
}
else
super.useMiddleware(routeOrMiddleware, ...middlewares);
return this;
}
use(routeOrHandler, ...handlers) {
if (typeof routeOrHandler === 'string' || Array.isArray(routeOrHandler)) {
const routed = new MiddlewareRouteAsync(routeOrHandler);
routed.use(...handlers);
super.useMiddleware(routed);
return this;
}
else
return super.use(routeOrHandler, ...handlers);
}
}
// // create Router#VERB functions
// methods.concat('all').forEach(function (method)
// {
// Router.prototype[method] = function (path)
// {
// var route = this.route(path)
// route[method].apply(route, slice.call(arguments, 1))
// return this
// }
// })
//# sourceMappingURL=router-async.js.map