refactor: decorator

This commit is contained in:
xiaojunnuo
2022-12-27 12:32:09 +08:00
parent c23f6172b5
commit 717d203622
30 changed files with 639 additions and 309 deletions
+7 -24
View File
@@ -1,13 +1,6 @@
import { Registrable } from "../registry";
import { pluginRegistry } from "./registry";
import { FormItemProps } from "../d.ts";
export type TaskInput = {
[key: string]: any;
};
export type TaskOutput = {
[key: string]: any;
};
export enum ContextScope {
global,
@@ -28,17 +21,19 @@ export type TaskOutputDefine = {
export type TaskInputDefine = FormItemProps;
export type PluginDefine = Registrable & {
input: {
default?: any;
inputs?: {
[key: string]: TaskInputDefine;
};
output: {
outputs?: {
[key: string]: TaskOutputDefine;
};
autowire?: any;
};
export interface TaskPlugin {
getDefine(): PluginDefine;
execute(input: TaskInput): Promise<TaskOutput>;
export interface ITaskPlugin {
execute(): Promise<void>;
}
export type OutputVO = {
@@ -46,15 +41,3 @@ export type OutputVO = {
title: string;
value: any;
};
export function IsTask(define: (() => PluginDefine) | PluginDefine) {
return function (target: any) {
if (define instanceof Function) {
target.prototype.define = define();
} else {
target.prototype.define = define;
}
pluginRegistry.install(target);
};
}
@@ -0,0 +1,141 @@
// src/decorator/memoryCache.decorator.ts
import {
attachClassMetadata,
attachPropertyDataToClass,
createCustomPropertyDecorator,
getClassMetadata,
listModule,
listPropertyDataFromClass,
Provide,
saveClassMetadata,
saveModule,
Scope,
ScopeEnum,
} from "@midwayjs/decorator";
import _ from "lodash-es";
import { pluginRegistry } from "./registry";
import { PluginDefine, TaskInputDefine, TaskOutputDefine } from "./api";
// 提供一个唯一 key
export const PLUGIN_CLASS_KEY = "decorator:plugin";
export function IsTaskPlugin(define: PluginDefine): ClassDecorator {
console.log("is task plugin define:", define);
return (target: any) => {
console.log("is task plugin load:", target);
// 将装饰的类,绑定到该装饰器,用于后续能获取到 class
saveModule(PLUGIN_CLASS_KEY, target);
// 保存一些元数据信息,任意你希望存的东西
saveClassMetadata(
PLUGIN_CLASS_KEY,
{
define,
},
target
);
// 指定 IoC 容器创建实例的作用域,这里注册为请求作用域,这样能取到 ctx
Scope(ScopeEnum.Prototype)(target);
// 调用一下 Provide 装饰器,这样用户的 class 可以省略写 @Provide() 装饰器了
Provide()(target);
};
}
export const PLUGIN_INPUT_KEY = "decorator:plugin:input";
export function TaskInput(input?: TaskInputDefine): PropertyDecorator {
return (target, propertyKey) => {
attachPropertyDataToClass(PLUGIN_INPUT_KEY, { input }, target, propertyKey, propertyKey as string);
attachClassMetadata(
PLUGIN_CLASS_KEY,
{
inputs: {
[propertyKey]: input,
},
},
target
);
};
//
// return createCustomPropertyDecorator(CLASS_PROPS_KEY, {
// input,
// });
}
// 装饰器内部的唯一 id
export const PLUGIN_OUTPUT_KEY = "decorator:plugin:output";
export function TaskOutput(output?: TaskOutputDefine): PropertyDecorator {
return (target, propertyKey) => {
attachPropertyDataToClass(PLUGIN_OUTPUT_KEY, { output }, target, propertyKey, propertyKey as string);
attachClassMetadata(
PLUGIN_CLASS_KEY,
{
outputs: {
[propertyKey]: output,
},
},
target
);
};
//
// return createCustomPropertyDecorator(CLASS_PROPS_KEY, {
// input,
// });
}
export type AutowireProp = {
name?: string;
};
export const PLUGIN_AUTOWIRE_KEY = "decorator:plugin:autowire";
export function Autowire(props?: AutowireProp): PropertyDecorator {
return (target, propertyKey) => {
attachPropertyDataToClass(
PLUGIN_AUTOWIRE_KEY,
{
autowire: {
[propertyKey]: props,
},
},
target,
propertyKey,
propertyKey as string
);
};
}
export function registerPlugins() {
const modules = listModule(PLUGIN_CLASS_KEY);
for (const mod of modules) {
console.log("mod", mod);
const define: PluginDefine = getClassMetadata(PLUGIN_CLASS_KEY, mod);
console.log("define", define);
const inputs = listPropertyDataFromClass(PLUGIN_INPUT_KEY, mod);
console.log("inputs", inputs);
for (const input of inputs) {
define.inputs = {};
_.merge(define.inputs, input.inputs);
}
const outputs = listPropertyDataFromClass(PLUGIN_OUTPUT_KEY, mod);
console.log("outputs", outputs);
for (const output of outputs) {
define.outputs = {};
_.merge(define.outputs, output.outputs);
}
const autowire = listPropertyDataFromClass(PLUGIN_AUTOWIRE_KEY, mod);
console.log("autowire", autowire);
for (const auto of autowire) {
define.autowire = {};
_.merge(define.autowire, auto.autowire);
}
pluginRegistry.register(define.name, {
define,
target: mod,
});
}
}
+1 -1
View File
@@ -1,3 +1,3 @@
export * from "./api";
export * from "./registry";
export * from "./abstract-plugin";
export * from "./decorator";
@@ -1,5 +1,4 @@
import { Registry } from "../registry";
import { AbstractPlugin } from "./abstract-plugin";
// @ts-ignore
export const pluginRegistry = new Registry<typeof AbstractPlugin>();
export const pluginRegistry = new Registry();
@@ -0,0 +1,26 @@
import { ILogger } from "@midwayjs/logger";
import { ITaskPlugin } from "../api";
import { Autowire, IsTaskPlugin, TaskInput } from "../decorator";
@IsTaskPlugin({
name: "EchoPlugin",
title: "测试插件",
desc: "test",
})
export class EchoPlugin implements ITaskPlugin {
@TaskInput({
title: "测试属性",
component: {
name: "text",
},
})
test?: string;
@Autowire()
// @ts-ignore
logger: ILogger;
async execute(): Promise<void> {
return Promise.resolve(undefined);
}
}