AsyncPipe; table schemata; migrations; File logging
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2021-07-25 09:15:01 -05:00
parent e86cf420df
commit fcce28081b
42 changed files with 3139 additions and 56 deletions

View File

@@ -20,7 +20,17 @@ export interface CanonicalDefinition {
/**
* Type alias for a function that resolves a canonical name to a canonical item, if one exists.
*/
export type CanonicalResolver<T> = (key: string) => T | undefined
export type CanonicalResolverFunction<T> = (key: string) => T | undefined
/**
* Interface for a canonical resolver that provides additional information.
*/
export interface ComplexCanonicalResolver<T> {
get: CanonicalResolverFunction<T>,
all: () => string[],
}
export type CanonicalResolver<T> = CanonicalResolverFunction<T> | ComplexCanonicalResolver<T>
/**
* Base type for a canonical name reference.
@@ -105,10 +115,33 @@ export abstract class Canonical<T> extends Unit {
/**
* Return an array of all loaded canonical names.
*/
public all(): string[] {
public all(namespace?: string): string[] {
if ( namespace ) {
const resolver = this.loadedNamespaces[namespace]
if ( !resolver ) {
throw new ErrorWithContext(`Unable to find namespace for ${this.canonicalItem}: ${namespace}`, {
canonicalItem: this.canonicalItem,
namespace,
})
}
if ( typeof resolver === 'function' ) {
return []
} else {
return resolver.all()
}
}
return Object.keys(this.loadedItems)
}
/**
* Return an array of all loaded canonical namespaces.
*/
public namespaces(): string[] {
return Object.keys(this.loadedNamespaces)
}
/**
* Get a Universal path to the base directory where this unit loads its canonical files from.
*/
@@ -127,7 +160,8 @@ export abstract class Canonical<T> extends Unit {
const [namespace, ...rest] = key.split(':')
key = rest.join(':')
if ( !this.loadedNamespaces[namespace] ) {
const resolver = this.loadedNamespaces[namespace]
if ( !resolver ) {
throw new ErrorWithContext(`Unable to find namespace for ${this.canonicalItem}: ${namespace}`, {
canonicalItem: this.canonicalItem,
namespace,
@@ -135,7 +169,11 @@ export abstract class Canonical<T> extends Unit {
})
}
return this.loadedNamespaces[namespace](key)
if ( typeof resolver === 'function' ) {
return resolver(key)
} else {
return resolver.get(key)
}
}
return this.loadedItems[key]
@@ -208,10 +246,11 @@ export abstract class Canonical<T> extends Unit {
/**
* Given the path to a file in the canonical items directory, create a CanonicalDefinition record from that file.
* @param filePath
* @param basePath
* @protected
*/
protected async buildCanonicalDefinition(filePath: string): Promise<CanonicalDefinition> {
const originalName = filePath.replace(this.path.toLocal, '').substr(1)
protected async buildCanonicalDefinition(filePath: string, basePath?: UniversalPath): Promise<CanonicalDefinition> {
const originalName = filePath.replace((basePath || this.path).toLocal, '').substr(1)
const pathRegex = new RegExp(nodePath.sep, 'g')
const canonicalName = originalName.replace(pathRegex, ':')
.split('')

View File

@@ -3,7 +3,7 @@
* @extends Error
*/
import {Canonical, CanonicalDefinition} from './Canonical'
import {Instantiable, isInstantiable} from '../di'
import {isInstantiable} from '../di'
/**
* Error thrown when the export of a canonical file is determined to be invalid.
@@ -17,8 +17,8 @@ export class InvalidCanonicalExportError extends Error {
/**
* Variant of the Canonical unit whose files export classes which are instantiated using the global container.
*/
export class CanonicalInstantiable<T> extends Canonical<Instantiable<T>> {
public async initCanonicalItem(definition: CanonicalDefinition): Promise<Instantiable<T>> {
export class CanonicalInstantiable<T> extends Canonical<T> {
public async initCanonicalItem(definition: CanonicalDefinition): Promise<T> {
if ( isInstantiable(definition.imported.default) ) {
return this.app().make(definition.imported.default)
}