From c2a71b9a7a92d566ea3dc59c118c42ac4c8105e5 Mon Sep 17 00:00:00 2001 From: MiaoWoo Date: Mon, 24 Feb 2020 16:24:36 +0800 Subject: [PATCH] feat: add config support Signed-off-by: MiaoWoo --- packages/plugin/src/config.ts | 40 +++++++++++++++++++++++++++++++ packages/plugin/src/decorators.ts | 17 +++---------- packages/plugin/src/interfaces.ts | 2 ++ packages/plugin/src/manager.ts | 21 ++++++++++++---- 4 files changed, 62 insertions(+), 18 deletions(-) create mode 100644 packages/plugin/src/config.ts diff --git a/packages/plugin/src/config.ts b/packages/plugin/src/config.ts new file mode 100644 index 00000000..258e4259 --- /dev/null +++ b/packages/plugin/src/config.ts @@ -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(); + +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() diff --git a/packages/plugin/src/decorators.ts b/packages/plugin/src/decorators.ts index 00524f65..be71a1a3 100644 --- a/packages/plugin/src/decorators.ts +++ b/packages/plugin/src/decorators.ts @@ -24,7 +24,6 @@ export function plugin(metadata: interfaces.PluginMetadata) { */ export function cmd(metadata: interfaces.CommandMetadata = {}) { return function(target: any, key: string, value: any) { - checkFunction("command", target[key]); metadata.name = metadata.name || key; metadata.executor = 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 = {}) { 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); if (!metadata.name) { return; } metadata.executor = key; @@ -57,7 +55,6 @@ export function tab(metadata: interfaces.TabCompleterMetadata = {}) { */ export function listener(metadata: interfaces.ListenerMetadata = {}) { return function(target: any, key: string, value: any) { - checkFunction("listener", target[key]); metadata.name = metadata.name || key; metadata.executor = key; const previousMetadata: interfaces.ListenerMetadata[] = getPluginListenerMetadata(target) @@ -65,20 +62,12 @@ export function listener(metadata: interfaces.ListenerMetadata = {}) { }; } -export function config(metadata: interfaces.ConfigMetadata = { version: 1 }) { - return function(target: any, key: string, value: any) { - if (typeof value === "function") { - throw new Error(`decorate config must config at prototype but is a ${typeof value}!`) - } +export function config(metadata: interfaces.ConfigMetadata = { version: 1, format: 'yml' }) { + return function(target: any, key: string) { metadata.name = metadata.name || key; + metadata.variable = key; const previousMetadata: Map = getPluginConfigMetadata(target) previousMetadata.set(metadata.name, metadata); 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}!`) - } -} \ No newline at end of file diff --git a/packages/plugin/src/interfaces.ts b/packages/plugin/src/interfaces.ts index 92650687..bf3a4b86 100644 --- a/packages/plugin/src/interfaces.ts +++ b/packages/plugin/src/interfaces.ts @@ -62,6 +62,8 @@ export namespace interfaces { } export interface ConfigMetadata extends BaseMetadata { version?: number; + variable?: string; + format?: string; } export type PluginLike = Plugin | string; } diff --git a/packages/plugin/src/manager.ts b/packages/plugin/src/manager.ts index 73cb268d..977d77aa 100644 --- a/packages/plugin/src/manager.ts +++ b/packages/plugin/src/manager.ts @@ -4,6 +4,7 @@ import * as fs from '@ms/common/dist/fs' import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPlugin, getPluginTabCompleterMetadata, getPluginConfigMetadata } from './utils' import { interfaces } from './interfaces' +import { getConfigLoader } from './config' @injectable() export class PluginManagerImpl implements plugin.PluginManager { @@ -11,6 +12,8 @@ export class PluginManagerImpl implements plugin.PluginManager { private container: Container @inject(plugin.PluginInstance) private pluginInstance: any + @inject(plugin.PluginFolder) + private pluginFolder: string; @inject(server.ServerType) private serverType: string @inject(command.Command) @@ -51,9 +54,9 @@ export class PluginManagerImpl implements plugin.PluginManager { load(...args: any[]): void { this.checkAndGet(args[0]).forEach((plugin: interfaces.Plugin) => { this.logStage(plugin, "Loading") + this.loadConfig(plugin) this.runCatch(plugin, '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) { - let configs = getPluginConfigMetadata(pluginInstance); - + private loadConfig(plugin: interfaces.Plugin) { + 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) {