40
									
								
								packages/plugin/src/config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								packages/plugin/src/config.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					import * as yaml from 'js-yaml'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface PluginConfigLoader {
 | 
				
			||||||
 | 
					    load(content: string): any;
 | 
				
			||||||
 | 
					    dump(variable: any): string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class YamlPluginConfig implements PluginConfigLoader {
 | 
				
			||||||
 | 
					    load(content: string) {
 | 
				
			||||||
 | 
					        return yaml.safeLoad(content);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    dump(variable: any): string {
 | 
				
			||||||
 | 
					        return yaml.safeDump(variable);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class JsonPluginConfig implements PluginConfigLoader {
 | 
				
			||||||
 | 
					    load(content: string) {
 | 
				
			||||||
 | 
					        return JSON.parse(content);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    dump(variable: any): string {
 | 
				
			||||||
 | 
					        return JSON.stringify(variable);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const configLoaderMap = new Map<string, PluginConfigLoader>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function getConfigLoader(format: string) {
 | 
				
			||||||
 | 
					    if (!configLoaderMap.has(format)) { throw new Error(`Unsupport config format ${format} !`) }
 | 
				
			||||||
 | 
					    return configLoaderMap.get(format);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function init() {
 | 
				
			||||||
 | 
					    configLoaderMap.set("json", new JsonPluginConfig())
 | 
				
			||||||
 | 
					    let yaml = new YamlPluginConfig()
 | 
				
			||||||
 | 
					    configLoaderMap.set("yml", yaml)
 | 
				
			||||||
 | 
					    configLoaderMap.set("yaml", yaml)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					init()
 | 
				
			||||||
@@ -24,7 +24,6 @@ export function plugin(metadata: interfaces.PluginMetadata) {
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
export function cmd(metadata: interfaces.CommandMetadata = {}) {
 | 
					export function cmd(metadata: interfaces.CommandMetadata = {}) {
 | 
				
			||||||
    return function(target: any, key: string, value: any) {
 | 
					    return function(target: any, key: string, value: any) {
 | 
				
			||||||
        checkFunction("command", target[key]);
 | 
					 | 
				
			||||||
        metadata.name = metadata.name || key;
 | 
					        metadata.name = metadata.name || key;
 | 
				
			||||||
        metadata.executor = key;
 | 
					        metadata.executor = key;
 | 
				
			||||||
        metadata.paramtypes = Reflect.getMetadata("design:paramtypes", target, key)
 | 
					        metadata.paramtypes = Reflect.getMetadata("design:paramtypes", target, key)
 | 
				
			||||||
@@ -40,7 +39,6 @@ export function cmd(metadata: interfaces.CommandMetadata = {}) {
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
export function tab(metadata: interfaces.TabCompleterMetadata = {}) {
 | 
					export function tab(metadata: interfaces.TabCompleterMetadata = {}) {
 | 
				
			||||||
    return function(target: any, key: string, value: any) {
 | 
					    return function(target: any, key: string, value: any) {
 | 
				
			||||||
        checkFunction("tab", target[key]);
 | 
					 | 
				
			||||||
        metadata.name = metadata.name || (key.startsWith('tab') ? key.split('tab', 2)[1] : key);
 | 
					        metadata.name = metadata.name || (key.startsWith('tab') ? key.split('tab', 2)[1] : key);
 | 
				
			||||||
        if (!metadata.name) { return; }
 | 
					        if (!metadata.name) { return; }
 | 
				
			||||||
        metadata.executor = key;
 | 
					        metadata.executor = key;
 | 
				
			||||||
@@ -57,7 +55,6 @@ export function tab(metadata: interfaces.TabCompleterMetadata = {}) {
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
export function listener(metadata: interfaces.ListenerMetadata = {}) {
 | 
					export function listener(metadata: interfaces.ListenerMetadata = {}) {
 | 
				
			||||||
    return function(target: any, key: string, value: any) {
 | 
					    return function(target: any, key: string, value: any) {
 | 
				
			||||||
        checkFunction("listener", target[key]);
 | 
					 | 
				
			||||||
        metadata.name = metadata.name || key;
 | 
					        metadata.name = metadata.name || key;
 | 
				
			||||||
        metadata.executor = key;
 | 
					        metadata.executor = key;
 | 
				
			||||||
        const previousMetadata: interfaces.ListenerMetadata[] = getPluginListenerMetadata(target)
 | 
					        const previousMetadata: interfaces.ListenerMetadata[] = getPluginListenerMetadata(target)
 | 
				
			||||||
@@ -65,20 +62,12 @@ export function listener(metadata: interfaces.ListenerMetadata = {}) {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function config(metadata: interfaces.ConfigMetadata = { version: 1 }) {
 | 
					export function config(metadata: interfaces.ConfigMetadata = { version: 1, format: 'yml' }) {
 | 
				
			||||||
    return function(target: any, key: string, value: any) {
 | 
					    return function(target: any, key: string) {
 | 
				
			||||||
        if (typeof value === "function") {
 | 
					 | 
				
			||||||
            throw new Error(`decorate config must config at prototype but is a ${typeof value}!`)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        metadata.name = metadata.name || key;
 | 
					        metadata.name = metadata.name || key;
 | 
				
			||||||
 | 
					        metadata.variable = key;
 | 
				
			||||||
        const previousMetadata: Map<string, interfaces.ConfigMetadata> = getPluginConfigMetadata(target)
 | 
					        const previousMetadata: Map<string, interfaces.ConfigMetadata> = getPluginConfigMetadata(target)
 | 
				
			||||||
        previousMetadata.set(metadata.name, metadata);
 | 
					        previousMetadata.set(metadata.name, metadata);
 | 
				
			||||||
        Reflect.defineMetadata(METADATA_KEY.config, previousMetadata, target.constructor);
 | 
					        Reflect.defineMetadata(METADATA_KEY.config, previousMetadata, target.constructor);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
function checkFunction(type: string, value: any) {
 | 
					 | 
				
			||||||
    if (typeof value !== "function") {
 | 
					 | 
				
			||||||
        throw new Error(`decorate ${type} must config at function but is a ${typeof value}!`)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -62,6 +62,8 @@ export namespace interfaces {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    export interface ConfigMetadata extends BaseMetadata {
 | 
					    export interface ConfigMetadata extends BaseMetadata {
 | 
				
			||||||
        version?: number;
 | 
					        version?: number;
 | 
				
			||||||
 | 
					        variable?: string;
 | 
				
			||||||
 | 
					        format?: string;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    export type PluginLike = Plugin | string;
 | 
					    export type PluginLike = Plugin | string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ import * as fs from '@ms/common/dist/fs'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPlugin, getPluginTabCompleterMetadata, getPluginConfigMetadata } from './utils'
 | 
					import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPlugin, getPluginTabCompleterMetadata, getPluginConfigMetadata } from './utils'
 | 
				
			||||||
import { interfaces } from './interfaces'
 | 
					import { interfaces } from './interfaces'
 | 
				
			||||||
 | 
					import { getConfigLoader } from './config'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@injectable()
 | 
					@injectable()
 | 
				
			||||||
export class PluginManagerImpl implements plugin.PluginManager {
 | 
					export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			||||||
@@ -11,6 +12,8 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			|||||||
    private container: Container
 | 
					    private container: Container
 | 
				
			||||||
    @inject(plugin.PluginInstance)
 | 
					    @inject(plugin.PluginInstance)
 | 
				
			||||||
    private pluginInstance: any
 | 
					    private pluginInstance: any
 | 
				
			||||||
 | 
					    @inject(plugin.PluginFolder)
 | 
				
			||||||
 | 
					    private pluginFolder: string;
 | 
				
			||||||
    @inject(server.ServerType)
 | 
					    @inject(server.ServerType)
 | 
				
			||||||
    private serverType: string
 | 
					    private serverType: string
 | 
				
			||||||
    @inject(command.Command)
 | 
					    @inject(command.Command)
 | 
				
			||||||
@@ -51,9 +54,9 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			|||||||
    load(...args: any[]): void {
 | 
					    load(...args: any[]): void {
 | 
				
			||||||
        this.checkAndGet(args[0]).forEach((plugin: interfaces.Plugin) => {
 | 
					        this.checkAndGet(args[0]).forEach((plugin: interfaces.Plugin) => {
 | 
				
			||||||
            this.logStage(plugin, "Loading")
 | 
					            this.logStage(plugin, "Loading")
 | 
				
			||||||
 | 
					            this.loadConfig(plugin)
 | 
				
			||||||
            this.runCatch(plugin, 'load')
 | 
					            this.runCatch(plugin, 'load')
 | 
				
			||||||
            this.runCatch(plugin, `${this.serverType}load`)
 | 
					            this.runCatch(plugin, `${this.serverType}load`)
 | 
				
			||||||
            this.loadConfig(plugin)
 | 
					 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -197,9 +200,19 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private loadConfig(pluginInstance: interfaces.Plugin) {
 | 
					    private loadConfig(plugin: interfaces.Plugin) {
 | 
				
			||||||
        let configs = getPluginConfigMetadata(pluginInstance);
 | 
					        let configs = getPluginConfigMetadata(plugin);
 | 
				
			||||||
 | 
					        for (let [_, config] of configs) {
 | 
				
			||||||
 | 
					            let configFile = fs.concat(root, this.pluginFolder, plugin.description.name, config.name + '.' + config.format)
 | 
				
			||||||
 | 
					            console.log(configFile)
 | 
				
			||||||
 | 
					            let configFactory = getConfigLoader(config.format);
 | 
				
			||||||
 | 
					            if (!fs.exists(configFile)) {
 | 
				
			||||||
 | 
					                base.save(configFile, configFactory.dump(plugin[config.variable]))
 | 
				
			||||||
 | 
					                console.log(`[${plugin.description.name}] config ${config.name}.${config.format} don't exists auto create from default variable...`)
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                plugin[config.variable] = configFactory.load(base.read(configFile));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private registryCommand(pluginInstance: interfaces.Plugin) {
 | 
					    private registryCommand(pluginInstance: interfaces.Plugin) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user