UNPKG

dynamicl

Version:

A library for auto-detecting and loading classes

55 lines (46 loc) 1.9 kB
import 'reflect-metadata'; import * as fs from 'fs'; import * as path from 'path'; export abstract class Detectable { constructor(public name: string) {} } export function autodetect<T extends Detectable>(options: { baseClass: new (...args: any[]) => T, location: string }) { return function (target: any, propertyKey: string) { const location = path.resolve(options.location); Reflect.defineMetadata('autodetect:options', options, target, propertyKey); Object.defineProperty(target, propertyKey, { get: function() { if (!this._loadedItems) { this._loadedItems = loadItems(location, options.baseClass); } return this._loadedItems; }, configurable: true, enumerable: true }); }; } function loadItems<T extends Detectable>(directoryPath: string, BaseClass: new (...args: any[]) => T): T[] { const items: T[] = []; const files = fs.readdirSync(directoryPath); for (const file of files) { if (file.endsWith('.ts') || file.endsWith('.js')) { const filePath = path.join(directoryPath, file); let module; try { module = require(filePath); } catch (error) { console.error(`Error loading module ${filePath}:`, error); continue; } for (const exportedItem of Object.values(module)) { if (typeof exportedItem === 'function' && exportedItem.prototype instanceof BaseClass) { const ItemClass = exportedItem as new (name: string) => T; items.push(new ItemClass(path.basename(file, path.extname(file)))); } } } } return items; }