garrettmills
1d5056b753
All checks were successful
continuous-integration/drone/push Build is passing
116 lines
3.2 KiB
TypeScript
116 lines
3.2 KiB
TypeScript
import {Collection, ErrorWithContext} from '../../util'
|
|
import {AppClass} from '../../lifecycle/AppClass'
|
|
import {RouteHandler} from './Route'
|
|
import {Container} from '../../di'
|
|
import {Logging} from '../../service/Logging'
|
|
|
|
/**
|
|
* Class that defines a group of Routes in the application, with a prefix.
|
|
*/
|
|
export class RouteGroup extends AppClass {
|
|
/**
|
|
* The current set of nested groups. This is used when compiling route groups.
|
|
* @private
|
|
*/
|
|
private static currentGroupNesting: RouteGroup[] = []
|
|
|
|
/**
|
|
* Mapping of group names to group registration functions.
|
|
* @protected
|
|
*/
|
|
protected static namedGroups: {[key: string]: () => void } = {}
|
|
|
|
/**
|
|
* Array of middlewares that should apply to all routes in this group.
|
|
* @protected
|
|
*/
|
|
protected middlewares: Collection<{ stage: 'pre' | 'post', handler: RouteHandler }> = new Collection<{stage: 'pre' | 'post'; handler: RouteHandler}>()
|
|
|
|
/**
|
|
* Get the current group nesting.
|
|
*/
|
|
public static getCurrentGroupHierarchy(): RouteGroup[] {
|
|
return [...this.currentGroupNesting]
|
|
}
|
|
|
|
/**
|
|
* Create a new named group that can be registered at a later time, by name.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* RouteGroup.named('auth', () => {
|
|
* Route.group('/auth', () => {
|
|
* Route.get('/login', 'auth:Forms.getLogin')
|
|
* })
|
|
* })
|
|
* ```
|
|
*
|
|
* @param name
|
|
* @param define
|
|
*/
|
|
public static named(name: string, define: () => void): void {
|
|
if ( this.namedGroups[name] ) {
|
|
Container.getContainer()
|
|
.make<Logging>(Logging)
|
|
.warn(`Replacing named route group: ${name}`)
|
|
}
|
|
|
|
this.namedGroups[name] = define
|
|
}
|
|
|
|
/**
|
|
* Register the routes from a named group by calling its registration function.
|
|
*
|
|
* @example
|
|
* From the example above, we can register the auth `/auth/*` routes, like so:
|
|
* ```typescript
|
|
* RouteGroup.include('auth')
|
|
* ```
|
|
*
|
|
* @param name
|
|
*/
|
|
public static include(name: string): void {
|
|
if (!this.namedGroups[name]) {
|
|
throw new ErrorWithContext(`No route group exists with name: ${name}`, {name})
|
|
}
|
|
|
|
this.namedGroups[name]()
|
|
}
|
|
|
|
|
|
constructor(
|
|
/** Function to register routes for this group. */
|
|
public readonly group: () => void | Promise<void>,
|
|
|
|
/** The route prefix of this group. */
|
|
public readonly prefix: string,
|
|
) {
|
|
super()
|
|
}
|
|
|
|
/** Register the given middleware to be applied before all routes in this group. */
|
|
pre(middleware: RouteHandler): this {
|
|
this.middlewares.push({
|
|
stage: 'pre',
|
|
handler: middleware,
|
|
})
|
|
|
|
return this
|
|
}
|
|
|
|
/** Register the given middleware to be applied after all routes in this group. */
|
|
post(middleware: RouteHandler): this {
|
|
this.middlewares.push({
|
|
stage: 'post',
|
|
handler: middleware,
|
|
})
|
|
|
|
return this
|
|
}
|
|
|
|
/** Return the middlewares that apply to this group. */
|
|
getGroupMiddlewareDefinitions(): Collection<{ stage: 'pre' | 'post', handler: RouteHandler }> {
|
|
return this.middlewares
|
|
}
|
|
}
|