feat: support source map & reload
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
		@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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]
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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")
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user