mirror of
https://github.com/certd/certd.git
synced 2026-04-24 12:27:25 +08:00
refactor: decorator
This commit is contained in:
@@ -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,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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user