Created
April 15, 2020 07:25
-
-
Save Disane87/9f3e37d4b97820dcbdf43a0c8de61c3f to your computer and use it in GitHub Desktop.
NestJS Plugin-System
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Module } from '@nestjs/common'; | |
import { AppController } from './app.controller'; | |
import { AppService } from './app.service'; | |
import { PluginModule } from './plugin/plugin.module'; | |
@Module({ | |
imports: [PluginModule.registerPluginsAsync()], | |
controllers: [AppController], | |
providers: [AppService], | |
}) | |
export class AppModule { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { DynamicModule, Logger, Module } from '@nestjs/common'; | |
import * as fs from 'fs'; | |
import * as path from 'path'; | |
import { PluginController } from './plugin/plugin.controller'; | |
export const PLUGIN_PATH = path.normalize(path.join(process.cwd(), 'dist/libs')); | |
@Module({ | |
controllers: [PluginController], | |
}) | |
export class PluginModule { | |
/** | |
* Registers plugins async | |
* @returns plugins async | |
*/ | |
public static async registerPluginsAsync(): Promise<DynamicModule> { | |
return this.loadPlugins(); | |
} | |
/** | |
* Loads plugins | |
* @returns plugins | |
*/ | |
private static loadPlugins(): Promise<DynamicModule> { | |
Logger.log(`Loading plugins from ${PLUGIN_PATH}`, 'loadPlugins'); | |
const loadedPlugins: Array<Promise<DynamicModule>> = new Array(); | |
this.searchPluginsInFolder(PLUGIN_PATH).forEach(filePath => { | |
loadedPlugins.push( | |
this.loadPlugin(filePath).then(module => (module as DynamicModule)), | |
); | |
}); | |
return Promise.all(loadedPlugins).then((allPlugins: DynamicModule[]) => { | |
// console.log('All modules resolved: ', allPlugins.length, 'plugins'); | |
return { | |
module: PluginModule, | |
imports: [...allPlugins], | |
} as DynamicModule; | |
}); | |
} | |
/** | |
* Loads plugin | |
* @param pluginPath | |
* @returns plugin | |
*/ | |
private static loadPlugin(pluginPath: string): Promise<DynamicModule> { | |
const modulePlugin = import(pluginPath); | |
return modulePlugin; | |
} | |
/** | |
* Searchs plugins in folder | |
* @param folder | |
* @returns plugins in folder | |
*/ | |
private static searchPluginsInFolder(folder: string): string[] { | |
return this.recFindByExt(folder, 'js'); | |
} | |
private static recFindByExt(base: string, ext: string, files?: string[], result?: string[]): any[] { | |
if (!fs.existsSync(base)) { | |
fs.mkdirSync(base); | |
} | |
files = files || fs.readdirSync(base); | |
result = result || []; | |
files.forEach((file) => { | |
const newbase = path.join(base, file); | |
if (fs.statSync(newbase).isDirectory()) { | |
result = this.recFindByExt(newbase, ext, fs.readdirSync(newbase), result); | |
} else { | |
if (file.substr(-1 * (ext.length + 1)) === '.' + ext) { | |
if (result) { | |
result.push(newbase); | |
} | |
} | |
} | |
}, | |
); | |
return result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment