Support named route groups; canonical namespaces
This commit is contained in:
parent
a93cd6d192
commit
e8fdb04ae8
@ -1,16 +1,39 @@
|
||||
import {Collection} from "@extollo/util"
|
||||
import {Collection, ErrorWithContext} from "@extollo/util"
|
||||
import {AppClass} from "../../lifecycle/AppClass"
|
||||
import {RouteHandler} from "./Route"
|
||||
import {Container} from "@extollo/di"
|
||||
import {Logging} from "../../service/Logging";
|
||||
|
||||
export class RouteGroup extends AppClass {
|
||||
private static currentGroupNesting: RouteGroup[] = []
|
||||
|
||||
protected static namedGroups: {[key: string]: () => void } = {}
|
||||
|
||||
protected middlewares: Collection<{ stage: 'pre' | 'post', handler: RouteHandler }> = new Collection<{stage: "pre" | "post"; handler: RouteHandler}>()
|
||||
|
||||
public static getCurrentGroupHierarchy(): RouteGroup[] {
|
||||
return [...this.currentGroupNesting]
|
||||
}
|
||||
|
||||
public static named(name: string, define: () => void) {
|
||||
if ( this.namedGroups[name] ) {
|
||||
Container.getContainer()
|
||||
.make<Logging>(Logging)
|
||||
.warn(`Replacing named route group: ${name}`)
|
||||
}
|
||||
|
||||
this.namedGroups[name] = define
|
||||
}
|
||||
|
||||
public static include(name: string) {
|
||||
if (!this.namedGroups[name]) {
|
||||
throw new ErrorWithContext(`No route group exists with name: ${name}`, {name})
|
||||
}
|
||||
|
||||
this.namedGroups[name]()
|
||||
}
|
||||
|
||||
|
||||
constructor(
|
||||
public readonly group: () => void | Promise<void>,
|
||||
public readonly prefix: string
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Base type for a canonical definition.
|
||||
*/
|
||||
import {Canon} from "./Canon";
|
||||
import {universalPath, UniversalPath} from "@extollo/util";
|
||||
import {universalPath, UniversalPath, ErrorWithContext} from "@extollo/util";
|
||||
import {Logging} from "./Logging";
|
||||
import {Inject} from "@extollo/di";
|
||||
import * as nodePath from 'path'
|
||||
@ -14,6 +14,8 @@ export interface CanonicalDefinition {
|
||||
imported: any,
|
||||
}
|
||||
|
||||
export type CanonicalResolver<T> = (key: string) => T | undefined
|
||||
|
||||
/**
|
||||
* Base type for a canonical name reference.
|
||||
*/
|
||||
@ -55,6 +57,12 @@ export abstract class Canonical<T> extends Unit {
|
||||
*/
|
||||
protected loadedItems: { [key: string]: T } = {}
|
||||
|
||||
/**
|
||||
* Object mapping canonical namespaces to resolver functions.
|
||||
* @protected
|
||||
*/
|
||||
protected loadedNamespaces: { [key: string]: CanonicalResolver<T> } = {}
|
||||
|
||||
/**
|
||||
* Resolve a canonical reference from its string form to a CanonicalReference.
|
||||
* @param {string} reference
|
||||
@ -86,9 +94,36 @@ export abstract class Canonical<T> extends Unit {
|
||||
}
|
||||
|
||||
public get(key: string): T | undefined {
|
||||
if ( key.startsWith('@') ) {
|
||||
const [namespace, ...rest] = key.split(':')
|
||||
key = rest.join(':')
|
||||
|
||||
if ( !this.loadedNamespaces[namespace] ) {
|
||||
throw new ErrorWithContext(`Unable to find namespace for ${this.canonicalItem}: ${namespace}`, {
|
||||
canonicalItem: this.canonicalItem,
|
||||
namespace,
|
||||
key,
|
||||
})
|
||||
}
|
||||
|
||||
return this.loadedNamespaces[namespace](key)
|
||||
}
|
||||
|
||||
return this.loadedItems[key]
|
||||
}
|
||||
|
||||
public registerNamespace(name: string, resolver: CanonicalResolver<T>) {
|
||||
if ( !name.startsWith('@') ) {
|
||||
throw new ErrorWithContext(`Canonical namespaces must start with @.`, { name })
|
||||
}
|
||||
|
||||
if ( this.loadedNamespaces[name] ) {
|
||||
this.logging.warn(`Replacing canonical namespace resolver for: ${name}`)
|
||||
}
|
||||
|
||||
this.loadedNamespaces[name] = resolver
|
||||
}
|
||||
|
||||
public async up() {
|
||||
for await ( const entry of this.path.walk() ) {
|
||||
if ( !entry.endsWith(this.suffix) ) {
|
||||
|
Loading…
Reference in New Issue
Block a user