feat: support source map & reload
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
parent
d50506ab9d
commit
40e9d1db6e
@ -21,10 +21,54 @@ export namespace plugin {
|
|||||||
export interface PluginManager {
|
export interface PluginManager {
|
||||||
scan(folder: string): void;
|
scan(folder: string): void;
|
||||||
build(): void;
|
build(): void;
|
||||||
|
loadFromFile(file: string): Plugin;
|
||||||
load(...args: any[]): void;
|
load(...args: any[]): void;
|
||||||
enable(...args: any[]): void;
|
enable(...args: any[]): void;
|
||||||
disable(...args: any[]): void;
|
disable(...args: any[]): void;
|
||||||
reload(...args: any[]): void;
|
reload(...args: any[]): void;
|
||||||
getPlugins(): Map<string, any>;
|
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 {
|
interface String {
|
||||||
trimLeft();
|
trimLeft(): string;
|
||||||
trimRight();
|
trimRight(): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Object {
|
interface Object {
|
||||||
setPrototypeOf(obj: object, prototype: object);
|
setPrototypeOf(obj: object, prototype: object): void;
|
||||||
bindProperties(to: object, from: object);
|
bindProperties(to: object, from: object): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace NodeJS {
|
namespace NodeJS {
|
||||||
@ -68,7 +68,7 @@ declare global {
|
|||||||
stack(err: Error): string[];
|
stack(err: Error): string[];
|
||||||
sender(...args: any): void;
|
sender(...args: any): void;
|
||||||
console(...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 _statusText: string = null;
|
||||||
private _response: any;
|
private _response: any;
|
||||||
private _responseURL: string;
|
private _responseURL: string;
|
||||||
private _responseHeaders: HttpHeader;
|
private _responseHeaders: HttpHeader = {};
|
||||||
|
|
||||||
private _connection = null;
|
private _connection = null;
|
||||||
|
|
||||||
@ -228,7 +228,7 @@ export class XMLHttpRequest {
|
|||||||
|
|
||||||
private setResponseHeaders(header: any) {
|
private setResponseHeaders(header: any) {
|
||||||
this._responseHeaders = {};
|
this._responseHeaders = {};
|
||||||
header.forEach((key, value) => {
|
header.forEach((key: string | number, value: string | any[]) => {
|
||||||
this._responseHeaders[key] = value[value.length - 1]
|
this._responseHeaders[key] = value[value.length - 1]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
export const METADATA_KEY = {
|
export const METADATA_KEY = {
|
||||||
plugin: "@ccms/plugin:plugin",
|
plugin: Symbol.for("@ccms/plugin:plugin"),
|
||||||
cmd: "@ccms/plugin:cmd",
|
souece: Symbol.for("@ccms/plugin:souece"),
|
||||||
tab: "@ccms/plugin:tab",
|
cmd: Symbol.for("@ccms/plugin:cmd"),
|
||||||
listener: "@ccms/plugin:listener",
|
tab: Symbol.for("@ccms/plugin:tab"),
|
||||||
config: "@ccms/plugin:config",
|
listener: Symbol.for("@ccms/plugin:listener"),
|
||||||
|
config: Symbol.for("@ccms/plugin:config"),
|
||||||
stage: {
|
stage: {
|
||||||
load: "@ccms/plugin:stage:load",
|
load: Symbol.for("@ccms/plugin:stage:load"),
|
||||||
enable: "@ccms/plugin:stage:enable",
|
enable: Symbol.for("@ccms/plugin:stage:enable"),
|
||||||
disable: "@ccms/plugin:stage:disable"
|
disable: Symbol.for("@ccms/plugin:stage:disable")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { injectable, decorate } from "@ccms/container";
|
import { injectable, decorate } from "@ccms/container";
|
||||||
import { interfaces } from './interfaces'
|
import { interfaces } from './interfaces'
|
||||||
import { METADATA_KEY } from './constants'
|
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
|
* MiaoScript plugin
|
||||||
@ -10,11 +10,15 @@ import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata
|
|||||||
export function plugin(metadata: interfaces.PluginMetadata) {
|
export function plugin(metadata: interfaces.PluginMetadata) {
|
||||||
return function (target: any) {
|
return function (target: any) {
|
||||||
metadata.target = target;
|
metadata.target = target;
|
||||||
|
metadata.source = metadata.source + '';
|
||||||
decorate(injectable(), target);
|
decorate(injectable(), target);
|
||||||
Reflect.defineMetadata(METADATA_KEY.plugin, metadata, target);
|
Reflect.defineMetadata(METADATA_KEY.plugin, metadata, target);
|
||||||
const previousMetadata: Map<string, interfaces.PluginMetadata> = getPluginMetadatas();
|
const previousMetadata: Map<string, interfaces.PluginMetadata> = getPluginMetadatas();
|
||||||
previousMetadata.set(metadata.name, metadata);
|
previousMetadata.set(metadata.name, metadata);
|
||||||
Reflect.defineMetadata(METADATA_KEY.plugin, previousMetadata, Reflect);
|
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 { server, MiaoScriptConsole, event } from "@ccms/api";
|
||||||
import { METADATA_KEY } from './constants'
|
import { injectable, inject } from "@ccms/container";
|
||||||
import { injectable, inject, postConstruct } from "@ccms/container";
|
|
||||||
import { getPluginMetadata } from "./utils";
|
import { getPluginMetadata } from "./utils";
|
||||||
|
|
||||||
export namespace interfaces {
|
export namespace interfaces {
|
||||||
|
@ -3,7 +3,7 @@ import { plugin, server, command, event } from '@ccms/api'
|
|||||||
import { inject, provideSingleton, Container, ContainerInstance } from '@ccms/container'
|
import { inject, provideSingleton, Container, ContainerInstance } from '@ccms/container'
|
||||||
import * as fs from '@ccms/common/dist/fs'
|
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 { interfaces } from './interfaces'
|
||||||
import { getConfigLoader } from './config'
|
import { getConfigLoader } from './config'
|
||||||
|
|
||||||
@ -26,6 +26,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
|
|
||||||
private initialized: boolean = false
|
private initialized: boolean = false
|
||||||
private pluginMap: Map<string, interfaces.Plugin>
|
private pluginMap: Map<string, interfaces.Plugin>
|
||||||
|
private plugnMappings: Map<string, interfaces.PluginMetadata>
|
||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
if (this.pluginInstance !== null && this.initialized !== true) {
|
if (this.pluginInstance !== null && this.initialized !== true) {
|
||||||
@ -34,6 +35,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
this.pluginMap = new Map()
|
this.pluginMap = new Map()
|
||||||
console.i18n('ms.plugin.event.map', { count: this.EventManager.mapEventName().toFixed(0), type: this.serverType });
|
console.i18n('ms.plugin.event.map', { count: this.EventManager.mapEventName().toFixed(0), type: this.serverType });
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
|
this.plugnMappings = getPluginSources()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +62,14 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
this.execPluginStage(plugin, stage)
|
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 {
|
load(...args: any[]): void {
|
||||||
this.checkAndGet(args[0]).forEach((plugin: interfaces.Plugin) => {
|
this.checkAndGet(args[0]).forEach((plugin: interfaces.Plugin) => {
|
||||||
this.runPluginStage(plugin, 'load', () => {
|
this.runPluginStage(plugin, 'load', () => {
|
||||||
@ -89,10 +99,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
reload(...args: any[]): void {
|
reload(...args: any[]): void {
|
||||||
this.checkAndGet(args[0]).forEach((pl: interfaces.Plugin) => {
|
this.checkAndGet(args[0]).forEach((pl: interfaces.Plugin) => {
|
||||||
this.disable(pl)
|
this.disable(pl)
|
||||||
this.loadPlugin(pl.description.source)
|
this.loadFromFile(pl.description.source)
|
||||||
pl = this.buildPlugin(getPlugin(pl.description.name))
|
|
||||||
this.load(pl)
|
|
||||||
this.enable(pl)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,13 +173,14 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private allowProcess(servers: string[]) {
|
private allowProcess(servers: string[]) {
|
||||||
// Not set servers allow
|
// Not set servers -> allow
|
||||||
if (!servers || !servers.length) return true
|
if (!servers || !servers.length) return true
|
||||||
// include !type deny
|
// include !type -> deny
|
||||||
let denyServers = servers.filter(svr => svr.startsWith("!"))
|
let denyServers = servers.filter(svr => svr.startsWith("!"))
|
||||||
if (denyServers.length !== 0) {
|
if (denyServers.length !== 0) {
|
||||||
return !denyServers.includes(`!${this.serverType}`)
|
return !denyServers.includes(`!${this.serverType}`)
|
||||||
} else {
|
} else {
|
||||||
|
// only include -> allow
|
||||||
return servers.includes(this.serverType)
|
return servers.includes(this.serverType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,14 @@ function getPlugin(name: string) {
|
|||||||
return getPluginMetadatas().get(name);
|
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() {
|
function getPluginMetadatas() {
|
||||||
let pluginMetadatas: Map<string, interfaces.PluginMetadata> = Reflect.getMetadata(
|
let pluginMetadatas: Map<string, interfaces.PluginMetadata> = Reflect.getMetadata(
|
||||||
METADATA_KEY.plugin,
|
METADATA_KEY.plugin,
|
||||||
@ -68,6 +76,7 @@ function getPluginStageMetadata(target: any, stage: string) {
|
|||||||
export {
|
export {
|
||||||
getPlugin,
|
getPlugin,
|
||||||
getPlugins,
|
getPlugins,
|
||||||
|
getPluginSources,
|
||||||
getPluginMetadatas,
|
getPluginMetadatas,
|
||||||
getPluginMetadata,
|
getPluginMetadata,
|
||||||
getPluginCommandMetadata,
|
getPluginCommandMetadata,
|
||||||
|
Loading…
Reference in New Issue
Block a user