feat: update ms system
This commit is contained in:
@ -30,6 +30,7 @@ export function plugin(metadata: pluginApi.PluginMetadata | any) {
|
||||
export function cmd(metadata: interfaces.CommandMetadata = {}) {
|
||||
return function (target: any, key: string, value: any) {
|
||||
metadata.name = metadata.name || key
|
||||
metadata.target = target
|
||||
metadata.executor = key
|
||||
metadata.paramtypes = Reflect.getMetadata("design:paramtypes", target, key)
|
||||
const previousMetadata: Map<string, interfaces.CommandMetadata> = getPluginCommandMetadata(target)
|
||||
@ -46,6 +47,7 @@ export function tab(metadata: interfaces.CommandMetadata = {}) {
|
||||
return function (target: any, key: string, value: any) {
|
||||
metadata.name = metadata.name || (key.startsWith('tab') ? key.split('tab', 2)[1] : key)
|
||||
if (!metadata.name) { return }
|
||||
metadata.target = target
|
||||
metadata.executor = key
|
||||
metadata.paramtypes = Reflect.getMetadata("design:paramtypes", target, key)
|
||||
const previousMetadata: Map<string, interfaces.CommandMetadata> = getPluginTabCompleterMetadata(target)
|
||||
@ -61,9 +63,11 @@ export function tab(metadata: interfaces.CommandMetadata = {}) {
|
||||
export function listener(metadata: interfaces.ListenerMetadata = {}) {
|
||||
return function (target: any, key: string, value: any) {
|
||||
metadata.name = metadata.name || key
|
||||
metadata.target = target
|
||||
metadata.executor = key
|
||||
const previousMetadata: interfaces.ListenerMetadata[] = getPluginListenerMetadata(target)
|
||||
Reflect.defineMetadata(METADATA_KEY.listener, [metadata, ...previousMetadata], target.constructor)
|
||||
Reflect.defineMetadata(METADATA_KEY.listener, metadata, target[key])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,10 @@ export class PluginEventManager {
|
||||
// ignore space listener
|
||||
if (!this.ServerChecker.check(event.servers)) { continue }
|
||||
// here must bind this to pluginInstance
|
||||
this.EventManager.listen(pluginInstance, event.name, pluginInstance[event.executor].bind(pluginInstance), event.priority, event.ignoreCancel)
|
||||
let exec = event.target[event.executor]
|
||||
let execBinded = exec.bind(pluginInstance)
|
||||
execBinded.executor = event.executor
|
||||
exec.off = this.EventManager.listen(pluginInstance, event.name, execBinded, event.priority, event.ignoreCancel)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,10 @@ export namespace interfaces {
|
||||
public disable() { }
|
||||
}
|
||||
export interface ExecMetadata extends plugin.BaseMetadata {
|
||||
/**
|
||||
* 执行器所在对象 用于绑定this
|
||||
*/
|
||||
target?: any
|
||||
/**
|
||||
* 执行器
|
||||
*/
|
||||
@ -68,5 +72,4 @@ export namespace interfaces {
|
||||
*/
|
||||
readonly?: boolean
|
||||
}
|
||||
export type PluginLike = Plugin | string
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
import { plugin } from "@ccms/api"
|
||||
import { provideSingleton } from "@ccms/container"
|
||||
import { provideSingletonNamed } from "@ccms/container"
|
||||
|
||||
@provideSingleton(plugin.PluginLoader)
|
||||
const LOADER_TYPE_NAME = 'basic'
|
||||
|
||||
@provideSingletonNamed(plugin.PluginLoader, LOADER_TYPE_NAME)
|
||||
export class BasicLoader implements plugin.PluginLoader {
|
||||
type: string = 'basic'
|
||||
type: string = LOADER_TYPE_NAME
|
||||
|
||||
private pluginRequireMap: Map<string, any>
|
||||
|
||||
@ -22,8 +24,4 @@ export class BasicLoader implements plugin.PluginLoader {
|
||||
build(metadata: plugin.PluginMetadata) {
|
||||
return this.pluginRequireMap.get(metadata.source.toString())
|
||||
}
|
||||
load(plugin: plugin.Plugin): void { }
|
||||
enable(plugin: plugin.Plugin): void { }
|
||||
disable(plugin: plugin.Plugin): void { }
|
||||
reload(plugin: plugin.Plugin): void { }
|
||||
}
|
||||
|
@ -1,16 +1,18 @@
|
||||
import { plugin, server } from "@ccms/api"
|
||||
import { inject, ContainerInstance, Container, provideSingleton } from "@ccms/container"
|
||||
import { inject, ContainerInstance, Container, provideSingletonNamed } from "@ccms/container"
|
||||
|
||||
import { interfaces } from "../interfaces"
|
||||
import { getPluginStageMetadata, getPluginSources } from "../utils"
|
||||
|
||||
@provideSingleton(plugin.PluginLoader)
|
||||
const LOADER_TYPE_NAME = 'ioc'
|
||||
|
||||
@provideSingletonNamed(plugin.PluginLoader, LOADER_TYPE_NAME)
|
||||
export class IocLoader implements plugin.PluginLoader {
|
||||
type: string = 'ioc'
|
||||
type: string = LOADER_TYPE_NAME
|
||||
@inject(ContainerInstance)
|
||||
private container: Container
|
||||
@inject(server.ServerType)
|
||||
private serverType: string
|
||||
@inject(server.ServerChecker)
|
||||
private serverChecker: server.ServerChecker
|
||||
|
||||
private pluginMetadataMap: Map<string, plugin.PluginMetadata>
|
||||
|
||||
@ -28,7 +30,6 @@ export class IocLoader implements plugin.PluginLoader {
|
||||
}
|
||||
|
||||
build(metadata: plugin.PluginMetadata) {
|
||||
if (!this.allowProcess(metadata.servers)) { return }
|
||||
let pluginInstance: plugin.Plugin
|
||||
try {
|
||||
this.bindPlugin(metadata)
|
||||
@ -73,23 +74,10 @@ export class IocLoader implements plugin.PluginLoader {
|
||||
}
|
||||
}
|
||||
|
||||
private allowProcess(servers: string[]) {
|
||||
// Not set servers -> allow
|
||||
if (!servers || !servers.length) return true
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
||||
private stage(pluginInstance: plugin.Plugin, stageName: string) {
|
||||
let stages = getPluginStageMetadata(pluginInstance, stageName)
|
||||
for (const stage of stages) {
|
||||
if (!this.allowProcess(stage.servers)) { continue }
|
||||
if (!this.serverChecker.check(stage.servers)) { continue }
|
||||
console.i18n("ms.plugin.manager.stage.exec", { plugin: pluginInstance.description.name, name: stage.executor, stage: stageName, servers: stage.servers })
|
||||
try {
|
||||
pluginInstance[stage.executor].apply(pluginInstance)
|
||||
|
@ -19,6 +19,8 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
||||
private serverType: string
|
||||
@inject(event.Event)
|
||||
private EventManager: event.Event
|
||||
@inject(server.ServerChecker)
|
||||
private serverChecker: server.ServerChecker
|
||||
|
||||
@inject(PluginCommandManager)
|
||||
private commandManager: PluginCommandManager
|
||||
@ -74,7 +76,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
||||
try {
|
||||
this.loadPlugin(scanner.load(loadMetadata))
|
||||
} catch (error) {
|
||||
console.error(`plugin scanner ${scanner.type} load ${loadMetadata.name} occurred error ${error}`)
|
||||
console.error(`plugin scanner ${scanner.type} load ${loadMetadata.file} occurred error ${error}`)
|
||||
console.ex(error)
|
||||
}
|
||||
})
|
||||
@ -102,7 +104,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
||||
process.emit(`plugin.before.${stage}`, plugin)
|
||||
this.runCatch(plugin, stage)
|
||||
this.runCatch(plugin, `${this.serverType}${stage}`)
|
||||
plugin.description.loadMetadata.loader[stage](plugin)
|
||||
plugin.description.loadMetadata.loader[stage]?.(plugin)
|
||||
process.emit(`plugin.after.${stage}`, plugin)
|
||||
} catch (ex) {
|
||||
console.i18n("ms.plugin.manager.stage.exec.error", { plugin: plugin.description.name, executor: stage, error: ex })
|
||||
@ -112,7 +114,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
||||
|
||||
private loadPlugin(loadMetadata: plugin.PluginLoadMetadata) {
|
||||
if (!loadMetadata) { throw new Error('loadMetadata can\'t be undefiend when loadPlugin!') }
|
||||
if (loadMetadata.loaded) { throw new Error(`Plugin ${loadMetadata.name} is already loaded by ${loadMetadata.loader?.type}!`) }
|
||||
if (loadMetadata.loaded) { throw new Error(`Plugin file ${loadMetadata.file} is already loaded by ${loadMetadata.loader?.type}!`) }
|
||||
try {
|
||||
for (const [, loader] of this.loaderMap) {
|
||||
if (this.loaderRequirePlugin(loadMetadata, loader)?.loaded) return loadMetadata.metadata
|
||||
@ -215,16 +217,17 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
||||
try {
|
||||
this.buildPlugin(metadata)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
console.console(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private buildPlugin(metadata: plugin.PluginMetadata) {
|
||||
if (!this.loaderMap.has(metadata.type)) { throw new Error(`§4无法加载插件 §c${metadata.name} §4请检查 §c${metadata.type} §4加载器是否正常启用!`) }
|
||||
if (this.instanceMap.has(metadata.name)) { throw new Error(`Plugin ${metadata.name} is already load from ${metadata.source}...`) }
|
||||
if (!this.serverChecker.check(metadata.servers)) { throw new Error(`§6插件 §b${metadata.name} §c服务器类型不兼容(${metadata.servers.join(',')}) §6忽略加载...`) }
|
||||
let pluginInstance = this.loaderMap.get(metadata.type).build(metadata)
|
||||
if (!pluginInstance) { throw new Error(`§4加载器 §c${metadata.type} §4加载插件 §c${metadata.name} §4失败!`) }
|
||||
if (this.instanceMap.has(metadata.name)) { throw new Error(`Plugin ${metadata.name} is already load from ${metadata.source}...`) }
|
||||
this.instanceMap.set(metadata.name, pluginInstance)
|
||||
return pluginInstance
|
||||
}
|
||||
|
@ -2,9 +2,11 @@ import { plugin } from "@ccms/api"
|
||||
import * as fs from '@ccms/common/dist/fs'
|
||||
import { provideSingletonNamed } from "@ccms/container"
|
||||
|
||||
@provideSingletonNamed(plugin.PluginScanner, 'file')
|
||||
const SCANNER_TYPE_NAME = 'file'
|
||||
|
||||
@provideSingletonNamed(plugin.PluginScanner, SCANNER_TYPE_NAME)
|
||||
export class JSFileScanner implements plugin.PluginScanner {
|
||||
type: string = 'file'
|
||||
type: string = SCANNER_TYPE_NAME
|
||||
|
||||
scan(target: any): plugin.PluginLoadMetadata[] {
|
||||
return this.scanFolder(fs.concat(root, target)).map((file) => this.read(file))
|
||||
|
Reference in New Issue
Block a user