Support named route groups; canonical namespaces

This commit is contained in:
2021-03-21 21:10:42 -05:00
parent a93cd6d192
commit e8fdb04ae8
2 changed files with 60 additions and 2 deletions

View File

@@ -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) ) {