TypeDoc all the thngs
This commit is contained in:
@@ -8,12 +8,18 @@ import {Inject} from "@extollo/di";
|
||||
import * as nodePath from 'path'
|
||||
import {Unit} from "../lifecycle/Unit";
|
||||
|
||||
/**
|
||||
* Interface describing a definition of a single canonical item loaded from the app.
|
||||
*/
|
||||
export interface CanonicalDefinition {
|
||||
canonicalName: string,
|
||||
originalName: string,
|
||||
imported: any,
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
/**
|
||||
@@ -25,6 +31,19 @@ export interface CanonicalReference {
|
||||
particular?: string,
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract unit type that loads items recursively from a directory structure, assigning
|
||||
* them normalized names ("canonical names"), and providing a way to fetch the resources
|
||||
* by name.
|
||||
*
|
||||
* @example
|
||||
* The Config service is a Canonical derivative that loads files ending with `.config.js`
|
||||
* from the `app/config` directory.
|
||||
*
|
||||
* If, for example, there is a config file `app/config/auth/Forms.config.js` (in the
|
||||
* generated code), it can be loaded by the canonical name `auth:Forms`.
|
||||
*
|
||||
*/
|
||||
export abstract class Canonical<T> extends Unit {
|
||||
@Inject()
|
||||
protected readonly logging!: Logging
|
||||
@@ -81,18 +100,26 @@ export abstract class Canonical<T> extends Unit {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of all loaded canonical names.
|
||||
*/
|
||||
public all(): string[] {
|
||||
return Object.keys(this.loadedItems)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Universal path to the base directory where this unit loads its canonical files from.
|
||||
*/
|
||||
public get path(): UniversalPath {
|
||||
return this.app().appPath(...this.appPath)
|
||||
}
|
||||
|
||||
/** Get the plural name of the canonical items provided by this unit. */
|
||||
public get canonicalItems() {
|
||||
return `${this.canonicalItem}s`
|
||||
}
|
||||
|
||||
/** Get a canonical item by key. */
|
||||
public get(key: string): T | undefined {
|
||||
if ( key.startsWith('@') ) {
|
||||
const [namespace, ...rest] = key.split(':')
|
||||
@@ -112,6 +139,34 @@ export abstract class Canonical<T> extends Unit {
|
||||
return this.loadedItems[key]
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a namespace resolver with the canonical unit.
|
||||
*
|
||||
* Namespaces are canonical names that start with a particular key, beginning with the `@` character,
|
||||
* which resolve their resources using a resolver function.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const items = {
|
||||
* 'foo:bar': 123,
|
||||
* 'bob': 456,
|
||||
* }
|
||||
*
|
||||
* const resolver = (key: string) => items[key]
|
||||
*
|
||||
* canonical.registerNamespace('@mynamespace', resolver)
|
||||
* ```
|
||||
*
|
||||
* Now, the items in the `@mynamespace` namespace can be accessed like so:
|
||||
*
|
||||
* ```typescript
|
||||
* canonical.get('@mynamespace:foo:bar') // => 123
|
||||
* canonical.get('@mynamespace:bob') // => 456
|
||||
* ```
|
||||
*
|
||||
* @param name
|
||||
* @param resolver
|
||||
*/
|
||||
public registerNamespace(name: string, resolver: CanonicalResolver<T>) {
|
||||
if ( !name.startsWith('@') ) {
|
||||
throw new ErrorWithContext(`Canonical namespaces must start with @.`, { name })
|
||||
@@ -139,10 +194,20 @@ export abstract class Canonical<T> extends Unit {
|
||||
this.canon.registerCanonical(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Called for each canonical item loaded from a file. This function should do any setup necessary and return the item
|
||||
* that should be associated with the canonical name.
|
||||
* @param definition
|
||||
*/
|
||||
public async initCanonicalItem(definition: CanonicalDefinition): Promise<T> {
|
||||
return definition.imported.default ?? definition.imported[definition.canonicalName.split(':').reverse()[0]]
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the path to a file in the canonical items directory, create a CanonicalDefinition record from that file.
|
||||
* @param filePath
|
||||
* @protected
|
||||
*/
|
||||
protected async buildCanonicalDefinition(filePath: string): Promise<CanonicalDefinition> {
|
||||
const originalName = filePath.replace(this.path.toLocal, '').substr(1)
|
||||
const pathRegex = new RegExp(nodePath.sep, 'g')
|
||||
|
||||
Reference in New Issue
Block a user