import LifecycleUnit from '../lifecycle/Unit.ts' import {fs, path} from '../external/std.ts' import {Canon} from './Canon.ts' import {Logging} from '../service/logging/Logging.ts' export interface CanonicalDefinition { canonical_name: string, original_name: string, imported: any, } export class Canonical extends LifecycleUnit { protected base_path: string = '.' protected suffix: string = '.ts' protected canonical_item: string = '' protected _items: { [key: string]: T } = {} public all(): string[] { return Object.keys(this._items) } public get path(): string { return path.resolve(this.base_path) } public get canonical_items() { return `${this.canonical_item}s` } public async up() { const logger = this.make(Logging) for await ( const entry of fs.walk(this.path) ) { if ( !entry.isFile || !entry.path.endsWith(this.suffix) ) { if ( entry.isFile ) logger.debug(`Skipping file in canonical path with invalid suffix: ${entry.path}`) continue } const def = await this._get_canonical_definition(entry.path) logger.verbose(`Registering canonical ${this.canonical_item} "${def.canonical_name}" from ${entry.path}.`) this._items[def.canonical_name] = await this.init_canonical_item(def) } this.make(Canon).register_canonical(this) } public async init_canonical_item(definition: CanonicalDefinition): Promise { return definition.imported.default } private async _get_canonical_definition(file_path: string): Promise { const original_name = file_path.replace(this.path, '').substr(1) const path_regex = new RegExp(path.SEP, 'g') const canonical_name = original_name.replace(path_regex, ':') .split('').reverse().join('') .substr(this.suffix.length) .split('').reverse().join('') const imported = await import(file_path) return { canonical_name, original_name, imported } } public get(key: string): T | undefined { return this._items[key] } }