Skip to content

Instantly share code, notes, and snippets.

@Disane87
Created April 15, 2020 07:25
Show Gist options
  • Save Disane87/9f3e37d4b97820dcbdf43a0c8de61c3f to your computer and use it in GitHub Desktop.
Save Disane87/9f3e37d4b97820dcbdf43a0c8de61c3f to your computer and use it in GitHub Desktop.
NestJS Plugin-System
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 { }
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