feat: support source map & reload

Signed-off-by: MiaoWoo <admin@yumc.pw>
clean
MiaoWoo 2020-05-07 17:12:15 +08:00
parent 8566c6a883
commit 098a4f8557
8 changed files with 90 additions and 25 deletions

View File

@ -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<string, any>;
}
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;
}
}

View File

@ -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;
}
}

View File

@ -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]
});
}

View File

@ -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")
}
};

View File

@ -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<string, interfaces.PluginMetadata> = getPluginMetadatas();
previousMetadata.set(metadata.name, metadata);
Reflect.defineMetadata(METADATA_KEY.plugin, previousMetadata, Reflect);
const previousSources: Map<string, interfaces.PluginMetadata> = getPluginSources();
previousSources.set(metadata.source, metadata);
Reflect.defineMetadata(METADATA_KEY.souece, previousSources, Reflect);
};
}

View File

@ -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 {

View File

@ -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<string, interfaces.Plugin>
private plugnMappings: Map<string, interfaces.PluginMetadata>
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)
}
}

View File

@ -9,6 +9,14 @@ function getPlugin(name: string) {
return getPluginMetadatas().get(name);
}
function getPluginSources() {
let pluginSources: Map<string, interfaces.PluginMetadata> = Reflect.getMetadata(
METADATA_KEY.souece,
Reflect
) || new Map<string, interfaces.PluginMetadata>();
return pluginSources;
}
function getPluginMetadatas() {
let pluginMetadatas: Map<string, interfaces.PluginMetadata> = Reflect.getMetadata(
METADATA_KEY.plugin,
@ -68,6 +76,7 @@ function getPluginStageMetadata(target: any, stage: string) {
export {
getPlugin,
getPlugins,
getPluginSources,
getPluginMetadatas,
getPluginMetadata,
getPluginCommandMetadata,