feat: add node-shim & move plugin interface

Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
MiaoWoo 2020-06-02 18:01:56 +08:00
parent 79f151de5c
commit 73ada5fd17
7 changed files with 172 additions and 126 deletions

View File

@ -26,7 +26,8 @@ export namespace plugin {
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>; getPlugin(name: string): plugin.Plugin;
getPlugins(): Map<string, plugin.Plugin>;
} }
export interface Plugin { export interface Plugin {
description: PluginMetadata; description: PluginMetadata;

View File

@ -1,196 +1,204 @@
/// <reference types="@ccms/types/dist/typings/jdk" />
/** /**
* *
* Created by MiaoWoo on 2017/2/9 0009. * Created by MiaoWoo on 2017/2/9 0009.
*/ */
const JavaClass = Java.type('java.lang.Class'); const JavaClass = Java.type('java.lang.Class')
const JavaObject = Java.type('java.lang.Object') const JavaObject = Java.type('java.lang.Object')
const NoSuchFieldException = Java.type('java.lang.NoSuchFieldException'); const NoSuchFieldException = Java.type('java.lang.NoSuchFieldException')
const methodCache = []; const methodCache = []
class Reflect { class Reflect {
private obj: any; private obj: java.lang.Object
private class: any private class: java.lang.Class
constructor(obj: any) { constructor(obj: any) {
// if (obj === undefined || obj === null) { throw Error(`reflect object can't be ${obj}!`) } // if (obj === undefined || obj === null) { throw Error(`reflect object can't be ${obj}!`) }
if (obj instanceof JavaClass) { if (obj instanceof JavaClass) {
this.obj = null; this.obj = null
this.class = obj; this.class = obj
} else { } else {
this.obj = obj; this.obj = obj
if (obj !== null && obj !== undefined && obj.class) { if (obj !== null && obj !== undefined && obj.class) {
this.class = obj.class; this.class = obj.class
} }
} }
} }
method(...args: any[]) { method(name: string, ...args: any[]) {
return declaredMethod(this.class, args[0], types(args.slice(1))); return declaredMethod(this.class, name, args)
} }
methods() { methods() {
return Java.from(declaredMethods(this.class)); return Java.from(declaredMethods(this.class))
} }
field(name): Reflect { field(name: string | java.lang.String): Reflect {
try { try {
// Try getting a public field // Try getting a public field
let field = this.class.field(name); let field = this.class.getField(name)
return on(field.get(this.obj)); return on(field.get(this.obj))
} catch (ex) { } catch (ex) {
// Try again, getting a non-public field // Try again, getting a non-public field
return on(accessible(declaredField(this.class, name)).get(this.obj)); return on(accessible(declaredField(this.class, name)).get(this.obj))
} }
}; }
fields(declared = false) { fields(declared = false): java.lang.reflect.Field[] {
return Java.from(declared ? this.class.declaredFields : this.class.fields); return Java.from(declared ? this.class.getDeclaredFields() : this.class.getFields())
} }
values(declared = false) { values(declared = false) {
let cache = {}; return this.fields(declared).reduce((cache, field) => { return cache[field.getName()] = this.field(field.getName()).get() }, {}) as any
this.fields(declared).forEach(fed => cache[fed.name] = this.field(fed.name).get())
return cache;
} }
call(...args): Reflect { call(...args: any[]): Reflect {
let params = args.slice(1); let params = args.slice(1)
let method = accessible(declaredMethod(this.class, args[0], types(params))); let method = accessible(declaredMethod(this.class, args[0], ...types(params)))
let result = method.invoke(this.get(), params); let result = method.invoke(this.get(), params)
return result && on(result); return result && on(result)
}; }
get(...args): Reflect | any { get(): any
return args.length === 1 ? this.field(args[0]) : this.obj; get(index: number, declared?: boolean): Reflect
}; get(prop: string): Reflect
get(param?: string | number, declared: boolean = true): Reflect | any {
if (param == undefined || param == null) return this.obj
if (typeof param == "number") {
return on(accessible(this.fields(declared)[param]).get(this.obj))
}
if (typeof param == "string") {
return this.field(param)
}
}
// noinspection JSUnusedGlobalSymbols set(name: any, value: any): Reflect {
set(name, value): Reflect { accessible(declaredField(this.class, name)).set(this.obj, value)
accessible(declaredField(this.class, name)).set(this.obj, value); return this
return this; }
};
create(...args): Reflect { create(...args): Reflect {
return on(declaredConstructor(this.class, args).newInstance(args)); return on(declaredConstructor(this.class, args).newInstance(args))
}; }
} }
/** /**
* Get an array of types for an array of objects * Get an array of types for an array of objects
*/ */
function types(values, def?) { function types(values: any[], def?: any) {
if (values === null) { if (values === null) {
return []; return []
} }
let result: any[] = []; let result: java.lang.Class[] = []
values.forEach(t => result.push((t || def) ? JavaObject.class : t instanceof JavaClass ? t : t.class)); values.forEach(t => result.push((t || def) ? JavaObject.class : t instanceof JavaClass ? t : t.class))
return result; return result
} }
function accessible(accessible) { function accessible<T extends java.lang.reflect.AccessibleObject>(accessible: T): T {
if (accessible === null) { if (accessible === null) {
return null; return null
} }
if (!accessible.isAccessible()) { if (!accessible.isAccessible()) {
accessible.setAccessible(true); accessible.setAccessible(true)
} }
return accessible; return accessible
} }
function declaredConstructor(clazz, param) { function declaredConstructor(clazz, param) {
let constructor; let constructor
try { try {
constructor = clazz.getDeclaredConstructor(types(param)); constructor = clazz.getDeclaredConstructor(types(param))
} catch (ex) { } catch (ex) {
try { try {
constructor = clazz.getDeclaredConstructor(types(param, true)); constructor = clazz.getDeclaredConstructor(types(param, true))
} catch (ex) { } catch (ex) {
constructor = clazz.getDeclaredConstructors()[0]; constructor = clazz.getDeclaredConstructors()[0]
} }
} }
return accessible(constructor); return accessible(constructor)
} }
function declaredField(clazz, name) { function declaredField(clazz: java.lang.Class, name: string | java.lang.String) {
if (!clazz) { throw Error(`target class can't be ${clazz}!`) } if (!clazz) { throw Error(`target class can't be ${clazz}!`) }
let target = clazz; let target = clazz
let field = null; let field = null
// noinspection JSUnresolvedVariable // noinspection JSUnresolvedVariable
while (target !== JavaObject.class) { while (target !== JavaObject.class) {
try { try {
field = target.getDeclaredField(name); field = target.getDeclaredField(name)
if (field !== null) { break; } if (field !== null) { break }
} catch (e) { } catch (e) {
if (target === undefined) { break; } if (target === undefined) { break }
target = target.getSuperclass(); target = target.getSuperclass()
} }
} }
if (field === null) { if (field === null) {
throw new NoSuchFieldException(name + " is not found in " + clazz.name); throw new NoSuchFieldException(name + " is not found in " + clazz.getName())
} }
return field; return field
} }
function declaredMethod(clazz, name, clazzs) { function declaredMethod(clazz: java.lang.Class, name: string, ...clazzs: any[]): java.lang.reflect.Method {
let key = clazz.name + '.' + name + ':' + (clazzs || []).join(':'); let key = clazz.getName() + '.' + name + ':' + (clazzs || []).join(':')
if (!methodCache[key]) { if (!methodCache[key]) {
try { try {
methodCache[key] = clazz.getMethod(name, clazzs); methodCache[key] = clazz.getMethod(name, clazzs as any)
} catch (ex) { } catch (ex) {
try { try {
methodCache[key] = clazz.getDeclaredMethod(name, clazzs); methodCache[key] = clazz.getDeclaredMethod(name, clazzs as any)
} catch (ex) { } catch (ex) {
for (const m of Java.from(declaredMethods(clazz))) { for (const m of Java.from(declaredMethods(clazz))) {
if (m.name == name) { if (m.name == name) {
methodCache[key] = m; methodCache[key] = m
break; break
} }
} }
} }
} }
} }
return methodCache[key]; return methodCache[key]
} }
function declaredMethods(clazz) { function declaredMethods(clazz) {
return clazz.declaredMethods; return clazz.declaredMethods
} }
let classMethodsCache: any[] = []; let classMethodsCache: any[] = []
function mapToObject(javaObj) { function mapToObject(javaObj) {
if (!javaObj || !javaObj.class) { throw new TypeError(`参数 ${javaObj} 不是一个Java对象!`) } if (!javaObj || !javaObj.class) { throw new TypeError(`参数 ${javaObj} 不是一个Java对象!`) }
let target = {}; let target = {}
getJavaObjectMethods(javaObj).forEach(t => mapMethod(target, javaObj, t)); getJavaObjectMethods(javaObj).forEach(t => mapMethod(target, javaObj, t))
return target; return target
} }
function getJavaObjectMethods(javaObj) { function getJavaObjectMethods(javaObj) {
let className = javaObj.class.name; let className = javaObj.class.name
if (!classMethodsCache[className]) { if (!classMethodsCache[className]) {
let names: any[] = []; let names: any[] = []
let methods = javaObj.class.methods; let methods = javaObj.class.methods
for (let i in methods) { for (let i in methods) {
names.push(methods[i].name); names.push(methods[i].name)
} }
classMethodsCache[className] = names; classMethodsCache[className] = names
} }
return classMethodsCache[className]; return classMethodsCache[className]
} }
function mapMethod(target, source, name) { function mapMethod(target, source, name) {
target[name] = function __SimpleDynamicMethod__(...args) { target[name] = function __SimpleDynamicMethod__(...args) {
if (args.length > 0) { if (args.length > 0) {
return source[name](args); return source[name](args)
} else { } else {
return source[name](); return source[name]()
} }
}; }
} }
function on(obj) { function on(obj) {
// if (!obj || !obj.class) { throw new TypeError(`参数 ${obj} 不是一个Java对象!`) } // if (!obj || !obj.class) { throw new TypeError(`参数 ${obj} 不是一个Java对象!`) }
return new Reflect(obj); return new Reflect(obj)
} }
export = { export = {

View File

@ -54,6 +54,7 @@ class MiaoScriptCore {
console.i18n("ms.core.engine.disable") console.i18n("ms.core.engine.disable")
this.pluginManager.disable(this.pluginManager.getPlugins()) this.pluginManager.disable(this.pluginManager.getPlugins())
this.taskManager.disable() this.taskManager.disable()
process.exit(0)
//@ts-ignore //@ts-ignore
require.disable() require.disable()
} }

View File

@ -1,13 +1,13 @@
/// <reference types="@ccms/nashorn" /> /// <reference types="@ccms/nashorn" />
import i18n from '@ccms/i18n' import i18n from '@ccms/i18n'
let ployfillStartTime = new Date().getTime(); let ployfillStartTime = new Date().getTime()
i18n.initialize(); i18n.initialize()
console.i18n("ms.ployfill.initialize"); console.i18n("ms.ployfill.initialize")
require('./es5-ext'); require('./es5-ext')
require('core-js'); require('./node-shim')
require('./node-shim'); require('core-js')
global.setGlobal('Proxy', require('./proxy').Proxy) global.setGlobal('Proxy', require('./proxy').Proxy)
global.setGlobal('XMLHttpRequest', require('./xml-http-request').XMLHttpRequest) global.setGlobal('XMLHttpRequest', require('./xml-http-request').XMLHttpRequest)
global.setGlobal('Blob', require('blob-polyfill').Blob) global.setGlobal('Blob', require('blob-polyfill').Blob)
console.i18n("ms.ployfill.completed", { time: (new Date().getTime() - ployfillStartTime) / 1000 }); console.i18n("ms.ployfill.completed", { time: (new Date().getTime() - ployfillStartTime) / 1000 })

View File

@ -1,8 +1,36 @@
global.setGlobal('process', { import { EventEmitter } from 'events'
env: {
const Thread = Java.type('java.lang.Thread')
const ThreadGroup = Java.type("java.lang.ThreadGroup")
const AtomicInteger = Java.type("java.util.concurrent.atomic.AtomicInteger")
const ThreadPoolExecutor = Java.type('java.util.concurrent.ThreadPoolExecutor')
const LinkedBlockingQueue = Java.type("java.util.concurrent.LinkedBlockingQueue")
const threadCount = new AtomicInteger(0)
const threadGroup = new ThreadGroup("@ccms/ployfill-micro-task")
const microTaskPool = new ThreadPoolExecutor(
10, 100, 60, Packages.java.util.concurrent.TimeUnit.SECONDS,
new LinkedBlockingQueue(500),
(run: any) => new Thread(threadGroup, run, "@ccms/micro-task-" + threadCount.incrementAndGet()),
new ThreadPoolExecutor.CallerRunsPolicy()
)
class Process extends EventEmitter {
env = {
__noSuchProperty__: (prop) => { __noSuchProperty__: (prop) => {
return Packages.java.lang.System.getenv(prop) return Packages.java.lang.System.getenv(prop)
} }
}, }
platform: Packages.java.lang.System.getProperty("os.name") platform = Packages.java.lang.System.getProperty("os.name")
}, {}) nextTick(func: Function) {
microTaskPool.execute(func)
}
queueMicrotask(func: Function) {
microTaskPool.execute(func)
}
exit() {
microTaskPool.shutdown();
}
}
global.setGlobal('process', new Process(), {})
global.setGlobal('queueMicrotask', (func: any) => microTaskPool.execute(func), {})

View File

@ -1,10 +1,10 @@
import { server, MiaoScriptConsole, event } from "@ccms/api"; import { server, MiaoScriptConsole, event, plugin } from "@ccms/api";
import { injectable, inject, postConstruct } from "@ccms/container"; import { injectable, inject, postConstruct } from "@ccms/container";
import { getPluginMetadata } from "./utils"; import { getPluginMetadata } from "./utils";
export namespace interfaces { export namespace interfaces {
@injectable() @injectable()
export abstract class Plugin { export abstract class Plugin implements plugin.Plugin {
public description: PluginMetadata; public description: PluginMetadata;
public logger: Console; public logger: Console;
@inject(server.Console) @inject(server.Console)

View File

@ -26,8 +26,8 @@ export class PluginManagerImpl implements plugin.PluginManager {
private initialized: boolean = false private initialized: boolean = false
private pluginRequireMap: Map<string, any> private pluginRequireMap: Map<string, any>
private pluginInstanceMap: Map<string, interfaces.Plugin> private pluginInstanceMap: Map<string, plugin.Plugin>
private pluginMetadataMap: Map<string, interfaces.PluginMetadata> private pluginMetadataMap: Map<string, plugin.PluginMetadata>
initialize() { initialize() {
if (this.pluginInstance === undefined) { throw new Error("Can't found Plugin Instance!") } if (this.pluginInstance === undefined) { throw new Error("Can't found Plugin Instance!") }
@ -52,23 +52,27 @@ export class PluginManagerImpl implements plugin.PluginManager {
this.buildPlugins() this.buildPlugins()
} }
private logStage(plugin: interfaces.Plugin, stage: string) { private logStage(plugin: plugin.Plugin, stage: string) {
console.i18n("ms.plugin.manager.stage", { stage, plugin: plugin.description.name, version: plugin.description.version, author: plugin.description.author }) console.i18n("ms.plugin.manager.stage", { stage, plugin: plugin.description.name, version: plugin.description.version, author: plugin.description.author })
} }
private runPluginStage(plugin: interfaces.Plugin, stage: string, ext: Function) { private runPluginStage(plugin: plugin.Plugin, stage: string, ext: Function) {
this.logStage(plugin, i18n.translate(`ms.plugin.manager.stage.${stage}`)) try {
ext() this.logStage(plugin, i18n.translate(`ms.plugin.manager.stage.${stage}`))
this.runCatch(plugin, stage) ext()
this.runCatch(plugin, `${this.serverType}${stage}`) this.runCatch(plugin, stage)
this.execPluginStage(plugin, stage) this.runCatch(plugin, `${this.serverType}${stage}`)
this.execPluginStage(plugin, stage)
} catch (ex) {
console.i18n("ms.plugin.manager.stage.exec.error", { plugin: plugin.description.name, executor: stage, error: ex })
}
} }
/** /**
* *
* @param file java.io.File * @param file java.io.File
*/ */
loadFromFile(file: string): interfaces.Plugin { loadFromFile(file: string): plugin.Plugin {
let metadata = this.loadPlugin(file) let metadata = this.loadPlugin(file)
let plugin = this.buildPlugin(metadata && metadata.description ? metadata.description : this.pluginMetadataMap.get(file.toString())) let plugin = this.buildPlugin(metadata && metadata.description ? metadata.description : this.pluginMetadataMap.get(file.toString()))
this.load(plugin) this.load(plugin)
@ -77,7 +81,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
} }
load(...args: any[]): void { load(...args: any[]): void {
this.checkAndGet(args[0]).forEach((plugin: interfaces.Plugin) => { this.checkAndGet(args[0]).forEach((plugin: plugin.Plugin) => {
this.runPluginStage(plugin, 'load', () => { this.runPluginStage(plugin, 'load', () => {
this.loadConfig(plugin) this.loadConfig(plugin)
}) })
@ -85,7 +89,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
} }
enable(...args: any[]): void { enable(...args: any[]): void {
this.checkAndGet(args[0]).forEach((plugin: interfaces.Plugin) => { this.checkAndGet(args[0]).forEach((plugin: plugin.Plugin) => {
this.runPluginStage(plugin, 'enable', () => { this.runPluginStage(plugin, 'enable', () => {
this.registryCommand(plugin) this.registryCommand(plugin)
this.registryListener(plugin) this.registryListener(plugin)
@ -94,7 +98,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
} }
disable(...args: any[]): void { disable(...args: any[]): void {
this.checkAndGet(args[0]).forEach((plugin: interfaces.Plugin) => { this.checkAndGet(args[0]).forEach((plugin: plugin.Plugin) => {
this.runPluginStage(plugin, 'disable', () => { this.runPluginStage(plugin, 'disable', () => {
this.saveConfig(plugin) this.saveConfig(plugin)
this.unregistryCommand(plugin) this.unregistryCommand(plugin)
@ -104,12 +108,16 @@ 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: plugin.Plugin) => {
this.disable(pl) this.disable(pl)
this.loadFromFile(pl.description.source) this.loadFromFile(pl.description.source)
}) })
} }
getPlugin(name: string) {
return this.pluginInstanceMap.get(name)
}
getPlugins() { getPlugins() {
return this.pluginInstanceMap return this.pluginInstanceMap
} }
@ -123,11 +131,11 @@ export class PluginManagerImpl implements plugin.PluginManager {
} }
} }
private checkAndGet(name: string | interfaces.Plugin | undefined | any): Map<string, interfaces.Plugin> | interfaces.Plugin[] { private checkAndGet(name: string | plugin.Plugin | undefined | any): Map<string, plugin.Plugin> | plugin.Plugin[] {
if (name == this.pluginInstanceMap) { return this.pluginInstanceMap } if (name == this.pluginInstanceMap) { return this.pluginInstanceMap }
if (typeof name == 'string' && this.pluginInstanceMap.has(name)) { return [this.pluginInstanceMap.get(name)] } if (typeof name == 'string' && this.pluginInstanceMap.has(name)) { return [this.pluginInstanceMap.get(name)] }
if (name instanceof interfaces.Plugin) { return [name as interfaces.Plugin] } if (name instanceof interfaces.Plugin) { return [name as plugin.Plugin] }
if (name.description || name.description.name) { return [name as interfaces.Plugin] } if (name.description || name.description.name) { return [name as plugin.Plugin] }
throw new Error(`Plugin ${JSON.stringify(name)} not exist!`) throw new Error(`Plugin ${JSON.stringify(name)} not exist!`)
} }
@ -214,12 +222,12 @@ export class PluginManagerImpl implements plugin.PluginManager {
} }
private buildPlugin(metadata: interfaces.PluginMetadata) { private buildPlugin(metadata: interfaces.PluginMetadata) {
let pluginInstance: interfaces.Plugin let pluginInstance: plugin.Plugin
switch (metadata.type) { switch (metadata.type) {
case "ioc": case "ioc":
try { try {
this.bindPlugin(metadata) this.bindPlugin(metadata)
pluginInstance = this.container.getNamed<interfaces.Plugin>(plugin.Plugin, metadata.name) pluginInstance = this.container.getNamed<plugin.Plugin>(plugin.Plugin, metadata.name)
if (!(pluginInstance instanceof interfaces.Plugin)) { if (!(pluginInstance instanceof interfaces.Plugin)) {
console.i18n('ms.plugin.manager.build.not.extends', { source: metadata.source }) console.i18n('ms.plugin.manager.build.not.extends', { source: metadata.source })
return return
@ -235,13 +243,13 @@ export class PluginManagerImpl implements plugin.PluginManager {
default: default:
throw new Error('§4不支持的插件类型 请检查加载器是否正常启用!') throw new Error('§4不支持的插件类型 请检查加载器是否正常启用!')
} }
this.pluginInstanceMap.set(metadata.name, pluginInstance) pluginInstance && this.pluginInstanceMap.set(metadata.name, pluginInstance)
return pluginInstance return pluginInstance
} }
private bindPlugin(metadata: interfaces.PluginMetadata) { private bindPlugin(metadata: interfaces.PluginMetadata) {
try { try {
let pluginInstance = this.container.getNamed<interfaces.Plugin>(plugin.Plugin, metadata.name) let pluginInstance = this.container.getNamed<plugin.Plugin>(plugin.Plugin, metadata.name)
if (pluginInstance.description.source + '' !== metadata.source + '') { if (pluginInstance.description.source + '' !== metadata.source + '') {
console.i18n('ms.plugin.manager.build.duplicate', { exists: pluginInstance.description.source, source: metadata.source }) console.i18n('ms.plugin.manager.build.duplicate', { exists: pluginInstance.description.source, source: metadata.source })
} }
@ -251,7 +259,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
} }
} }
private loadConfig(plugin: interfaces.Plugin) { private loadConfig(plugin: plugin.Plugin) {
let configs = getPluginConfigMetadata(plugin) let configs = getPluginConfigMetadata(plugin)
for (let [_, config] of configs) { for (let [_, config] of configs) {
try { try {
@ -276,7 +284,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
} }
} }
private saveConfig(plugin: interfaces.Plugin) { private saveConfig(plugin: plugin.Plugin) {
let configs = getPluginConfigMetadata(plugin) let configs = getPluginConfigMetadata(plugin)
for (let [_, config] of configs) { for (let [_, config] of configs) {
try { try {
@ -290,7 +298,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
} }
} }
private registryCommand(pluginInstance: interfaces.Plugin) { private registryCommand(pluginInstance: plugin.Plugin) {
let cmds = getPluginCommandMetadata(pluginInstance) let cmds = getPluginCommandMetadata(pluginInstance)
let tabs = getPluginTabCompleterMetadata(pluginInstance) let tabs = getPluginTabCompleterMetadata(pluginInstance)
for (const [_, cmd] of cmds) { for (const [_, cmd] of cmds) {
@ -303,7 +311,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
} }
} }
private registryListener(pluginInstance: interfaces.Plugin) { private registryListener(pluginInstance: plugin.Plugin) {
let events = getPluginListenerMetadata(pluginInstance) let events = getPluginListenerMetadata(pluginInstance)
for (const event of events) { for (const event of events) {
// ignore space listener // ignore space listener
@ -313,18 +321,18 @@ export class PluginManagerImpl implements plugin.PluginManager {
} }
} }
private unregistryCommand(pluginInstance: interfaces.Plugin) { private unregistryCommand(pluginInstance: plugin.Plugin) {
let cmds = getPluginCommandMetadata(pluginInstance) let cmds = getPluginCommandMetadata(pluginInstance)
cmds.forEach(cmd => { cmds.forEach(cmd => {
this.CommandManager.off(pluginInstance, cmd.name) this.CommandManager.off(pluginInstance, cmd.name)
}) })
} }
private unregistryListener(pluginInstance: interfaces.Plugin) { private unregistryListener(pluginInstance: plugin.Plugin) {
this.EventManager.disable(pluginInstance) this.EventManager.disable(pluginInstance)
} }
private execPluginStage(pluginInstance: interfaces.Plugin, stageName: string) { private execPluginStage(pluginInstance: plugin.Plugin, stageName: string) {
let stages = getPluginStageMetadata(pluginInstance, stageName) let stages = getPluginStageMetadata(pluginInstance, stageName)
for (const stage of stages) { for (const stage of stages) {
if (!this.allowProcess(stage.servers)) { continue } if (!this.allowProcess(stage.servers)) { continue }