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