From 40e9d1db6e4e5251d7114be62e5f0760de055bcd Mon Sep 17 00:00:00 2001 From: MiaoWoo Date: Thu, 7 May 2020 17:12:15 +0800 Subject: [PATCH] feat: support source map & reload Signed-off-by: MiaoWoo --- packages/api/src/interfaces/plugin.ts | 44 +++++++++++++++++++++++ packages/nashorn/src/index.ts | 10 +++--- packages/ployfill/src/xml-http-request.ts | 4 +-- packages/plugin/src/constants.ts | 17 ++++----- packages/plugin/src/decorators.ts | 6 +++- packages/plugin/src/interfaces.ts | 3 +- packages/plugin/src/manager.ts | 22 ++++++++---- packages/plugin/src/utils.ts | 9 +++++ 8 files changed, 90 insertions(+), 25 deletions(-) diff --git a/packages/api/src/interfaces/plugin.ts b/packages/api/src/interfaces/plugin.ts index 9f2ec4ab..a44c5307 100644 --- a/packages/api/src/interfaces/plugin.ts +++ b/packages/api/src/interfaces/plugin.ts @@ -21,10 +21,54 @@ export namespace plugin { export interface PluginManager { scan(folder: string): void; build(): void; + loadFromFile(file: string): Plugin; load(...args: any[]): void; enable(...args: any[]): void; disable(...args: any[]): void; reload(...args: any[]): void; getPlugins(): Map; } + export interface Plugin { + description: PluginMetadata; + logger: Console; + load(): void; + enable(): void; + disable(): void; + } + interface BaseMetadata { + /** + * 名称 为空则为对象名称 + */ + name?: string; + /** + * 支持的服务器列表 为空则代表所有 + */ + servers?: string[]; + } + export interface PluginMetadata extends BaseMetadata { + /** + * 插件名称 + */ + name: string; + /** + * 前缀 + */ + prefix?: string; + /** + * 插件版本 + */ + version: string; + /** + * 插件版本 + */ + author: string | string[]; + /** + * 插件源文件 必须指定为 __filename + */ + source: string; + /** + * 插件本体 + */ + target?: any; + } } diff --git a/packages/nashorn/src/index.ts b/packages/nashorn/src/index.ts index 2af33c96..4483298e 100644 --- a/packages/nashorn/src/index.ts +++ b/packages/nashorn/src/index.ts @@ -30,13 +30,13 @@ declare global { } interface String { - trimLeft(); - trimRight(); + trimLeft(): string; + trimRight(): string; } interface Object { - setPrototypeOf(obj: object, prototype: object); - bindProperties(to: object, from: object); + setPrototypeOf(obj: object, prototype: object): void; + bindProperties(to: object, from: object): void; } namespace NodeJS { @@ -68,7 +68,7 @@ declare global { stack(err: Error): string[]; sender(...args: any): void; console(...args: any): void; - i18n(name: string, ...params: any[]); + i18n(name: string, ...params: any[]): void; } } diff --git a/packages/ployfill/src/xml-http-request.ts b/packages/ployfill/src/xml-http-request.ts index 22d0a216..9ce15002 100644 --- a/packages/ployfill/src/xml-http-request.ts +++ b/packages/ployfill/src/xml-http-request.ts @@ -87,7 +87,7 @@ export class XMLHttpRequest { private _statusText: string = null; private _response: any; private _responseURL: string; - private _responseHeaders: HttpHeader; + private _responseHeaders: HttpHeader = {}; private _connection = null; @@ -228,7 +228,7 @@ export class XMLHttpRequest { private setResponseHeaders(header: any) { this._responseHeaders = {}; - header.forEach((key, value) => { + header.forEach((key: string | number, value: string | any[]) => { this._responseHeaders[key] = value[value.length - 1] }); } diff --git a/packages/plugin/src/constants.ts b/packages/plugin/src/constants.ts index b4eecc58..d90ccb57 100644 --- a/packages/plugin/src/constants.ts +++ b/packages/plugin/src/constants.ts @@ -1,12 +1,13 @@ export const METADATA_KEY = { - plugin: "@ccms/plugin:plugin", - cmd: "@ccms/plugin:cmd", - tab: "@ccms/plugin:tab", - listener: "@ccms/plugin:listener", - config: "@ccms/plugin:config", + plugin: Symbol.for("@ccms/plugin:plugin"), + souece: Symbol.for("@ccms/plugin:souece"), + cmd: Symbol.for("@ccms/plugin:cmd"), + tab: Symbol.for("@ccms/plugin:tab"), + listener: Symbol.for("@ccms/plugin:listener"), + config: Symbol.for("@ccms/plugin:config"), stage: { - load: "@ccms/plugin:stage:load", - enable: "@ccms/plugin:stage:enable", - disable: "@ccms/plugin:stage:disable" + load: Symbol.for("@ccms/plugin:stage:load"), + enable: Symbol.for("@ccms/plugin:stage:enable"), + disable: Symbol.for("@ccms/plugin:stage:disable") } }; diff --git a/packages/plugin/src/decorators.ts b/packages/plugin/src/decorators.ts index e262a20c..3f10741e 100644 --- a/packages/plugin/src/decorators.ts +++ b/packages/plugin/src/decorators.ts @@ -1,7 +1,7 @@ import { injectable, decorate } from "@ccms/container"; import { interfaces } from './interfaces' import { METADATA_KEY } from './constants' -import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPluginTabCompleterMetadata, getPluginConfigMetadata, getPluginStageMetadata } from './utils' +import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPluginTabCompleterMetadata, getPluginConfigMetadata, getPluginStageMetadata, getPluginSources } from './utils' /** * MiaoScript plugin @@ -10,11 +10,15 @@ import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata export function plugin(metadata: interfaces.PluginMetadata) { return function (target: any) { metadata.target = target; + metadata.source = metadata.source + ''; decorate(injectable(), target); Reflect.defineMetadata(METADATA_KEY.plugin, metadata, target); const previousMetadata: Map = getPluginMetadatas(); previousMetadata.set(metadata.name, metadata); Reflect.defineMetadata(METADATA_KEY.plugin, previousMetadata, Reflect); + const previousSources: Map = getPluginSources(); + previousSources.set(metadata.source, metadata); + Reflect.defineMetadata(METADATA_KEY.souece, previousSources, Reflect); }; } diff --git a/packages/plugin/src/interfaces.ts b/packages/plugin/src/interfaces.ts index 7a226911..ad5cff50 100644 --- a/packages/plugin/src/interfaces.ts +++ b/packages/plugin/src/interfaces.ts @@ -1,6 +1,5 @@ import { server, MiaoScriptConsole, event } from "@ccms/api"; -import { METADATA_KEY } from './constants' -import { injectable, inject, postConstruct } from "@ccms/container"; +import { injectable, inject } from "@ccms/container"; import { getPluginMetadata } from "./utils"; export namespace interfaces { diff --git a/packages/plugin/src/manager.ts b/packages/plugin/src/manager.ts index 727a5604..70a5da56 100644 --- a/packages/plugin/src/manager.ts +++ b/packages/plugin/src/manager.ts @@ -3,7 +3,7 @@ import { plugin, server, command, event } from '@ccms/api' import { inject, provideSingleton, Container, ContainerInstance } from '@ccms/container' import * as fs from '@ccms/common/dist/fs' -import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPlugin, getPluginTabCompleterMetadata, getPluginConfigMetadata, getPluginStageMetadata } from './utils' +import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPlugin, getPluginTabCompleterMetadata, getPluginConfigMetadata, getPluginStageMetadata, getPluginSources } from './utils' import { interfaces } from './interfaces' import { getConfigLoader } from './config' @@ -26,6 +26,7 @@ export class PluginManagerImpl implements plugin.PluginManager { private initialized: boolean = false private pluginMap: Map + private plugnMappings: Map initialize() { if (this.pluginInstance !== null && this.initialized !== true) { @@ -34,6 +35,7 @@ export class PluginManagerImpl implements plugin.PluginManager { this.pluginMap = new Map() console.i18n('ms.plugin.event.map', { count: this.EventManager.mapEventName().toFixed(0), type: this.serverType }); this.initialized = true; + this.plugnMappings = getPluginSources() } } @@ -60,6 +62,14 @@ export class PluginManagerImpl implements plugin.PluginManager { this.execPluginStage(plugin, stage) } + loadFromFile(file: string): interfaces.Plugin { + this.loadPlugin(file) + let plugin = this.buildPlugin(this.plugnMappings.get(file)) + this.load(plugin) + this.enable(plugin) + return plugin; + } + load(...args: any[]): void { this.checkAndGet(args[0]).forEach((plugin: interfaces.Plugin) => { this.runPluginStage(plugin, 'load', () => { @@ -89,10 +99,7 @@ export class PluginManagerImpl implements plugin.PluginManager { reload(...args: any[]): void { this.checkAndGet(args[0]).forEach((pl: interfaces.Plugin) => { this.disable(pl) - this.loadPlugin(pl.description.source) - pl = this.buildPlugin(getPlugin(pl.description.name)) - this.load(pl) - this.enable(pl) + this.loadFromFile(pl.description.source) }) } @@ -166,13 +173,14 @@ export class PluginManagerImpl implements plugin.PluginManager { } private allowProcess(servers: string[]) { - // Not set servers allow + // Not set servers -> allow if (!servers || !servers.length) return true - // include !type deny + // include !type -> deny let denyServers = servers.filter(svr => svr.startsWith("!")) if (denyServers.length !== 0) { return !denyServers.includes(`!${this.serverType}`) } else { + // only include -> allow return servers.includes(this.serverType) } } diff --git a/packages/plugin/src/utils.ts b/packages/plugin/src/utils.ts index bec360fb..d56476e9 100644 --- a/packages/plugin/src/utils.ts +++ b/packages/plugin/src/utils.ts @@ -9,6 +9,14 @@ function getPlugin(name: string) { return getPluginMetadatas().get(name); } +function getPluginSources() { + let pluginSources: Map = Reflect.getMetadata( + METADATA_KEY.souece, + Reflect + ) || new Map(); + return pluginSources; +} + function getPluginMetadatas() { let pluginMetadatas: Map = Reflect.getMetadata( METADATA_KEY.plugin, @@ -68,6 +76,7 @@ function getPluginStageMetadata(target: any, stage: string) { export { getPlugin, getPlugins, + getPluginSources, getPluginMetadatas, getPluginMetadata, getPluginCommandMetadata,