feat: midway注解方式编写插件

This commit is contained in:
xiaojunnuo
2023-01-11 20:39:48 +08:00
parent 52522f27e9
commit dcd1023a39
47 changed files with 484 additions and 714 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ export type AccessInputDefine = FormItemProps & {
required?: boolean;
};
export type AccessDefine = Registrable & {
inputs?: {
input?: {
[key: string]: AccessInputDefine;
};
};
@@ -20,7 +20,7 @@ export function IsAccess(define: AccessDefine): ClassDecorator {
inputs[property] = input;
}
}
_.merge(define, { inputs });
_.merge(define, { input: inputs });
Reflect.defineMetadata(ACCESS_CLASS_KEY, define, target);
target.define = define;
accessRegistry.register(define.name, {
@@ -30,9 +30,9 @@ export function IsAccess(define: AccessDefine): ClassDecorator {
};
}
export function IsAccessInput(input?: AccessInputDefine): PropertyDecorator {
export function AccessInput(input?: AccessInputDefine): PropertyDecorator {
return (target, propertyKey) => {
target = Decorator.target(target);
target = Decorator.target(target, propertyKey);
// const _type = Reflect.getMetadata("design:type", target, propertyKey);
Reflect.defineMetadata(ACCESS_INPUT_KEY, input, target, propertyKey);
};
+4 -7
View File
@@ -9,6 +9,7 @@ import { Logger } from "log4js";
import { request } from "../utils/util.request";
import { IAccessService } from "../access";
import { RegistryItem } from "../registry";
import { Decorator } from "../decorator";
export class Executor {
userId: any;
@@ -149,21 +150,17 @@ export class Executor {
// @ts-ignore
const define: PluginDefine = plugin.define;
//从outputContext读取输入参数
_.forEach(define.input, (item, key) => {
Decorator.inject(define.input, instance, step.input, (item, key) => {
if (item.component?.name === "pi-output-selector") {
const contextKey = step.input[key];
if (contextKey != null) {
step.input[key] = this.runtime.context[contextKey];
}
} else {
instance[key] = step.input[key];
}
});
_.forEach(define.autowire, (item, key: string) => {
instance[key] = context[key];
});
Decorator.inject(define.autowire, instance, context);
await instance.onInit();
await instance.execute();
//输出到output context
@@ -0,0 +1,17 @@
import { Decorator } from "./index";
export type AutowireProp = {
name?: string;
type?: any;
};
export const AUTOWIRE_KEY = "pipeline:autowire";
export function Autowire(props?: AutowireProp): PropertyDecorator {
return (target, propertyKey) => {
const _type = Reflect.getMetadata("design:type", target, propertyKey);
target = Decorator.target(target, propertyKey);
props = props || {};
props.type = _type;
Reflect.defineMetadata(AUTOWIRE_KEY, props || {}, target, propertyKey);
};
}
+2 -28
View File
@@ -1,28 +1,2 @@
const propertyMap: any = {};
function attachProperty(target: any, propertyKey: string | symbol) {
let props = propertyMap[target];
if (props == null) {
props = {};
propertyMap[target] = props;
}
props[propertyKey] = true;
}
function getClassProperties(target: any) {
return propertyMap[target] || {};
}
function target(target: any, propertyKey?: string | symbol) {
if (typeof target === "object" && target.constructor) {
target = target.constructor;
}
if (propertyKey != null) {
attachProperty(target, propertyKey);
}
return target;
}
export const Decorator = {
target,
attachProperty,
getClassProperties,
};
export * from "./utils";
export * from "./common";
@@ -0,0 +1,42 @@
import _ from "lodash";
const propertyMap: any = {};
function attachProperty(target: any, propertyKey: string | symbol) {
let props = propertyMap[target];
if (props == null) {
props = {};
propertyMap[target] = props;
}
props[propertyKey] = true;
}
function getClassProperties(target: any) {
return propertyMap[target] || {};
}
function target(target: any, propertyKey?: string | symbol) {
if (typeof target === "object" && target.constructor) {
target = target.constructor;
}
if (propertyKey != null) {
attachProperty(target, propertyKey);
}
return target;
}
function inject(define: any, instance: any, context: any, preHandler?: (item: any, key: string, instance: any, context: any) => void) {
_.forEach(define, (item, key) => {
if (preHandler) {
preHandler(item, key, instance, context);
}
if (context[key] != undefined) {
instance[key] = context[key];
}
});
}
export const Decorator = {
target,
attachProperty,
getClassProperties,
inject,
};
@@ -1,22 +0,0 @@
import { AbstractRegistrable } from "../registry";
import { CreateRecordOptions, IDnsProvider, DnsProviderDefine, RemoveRecordOptions } from "./api";
import { AbstractAccess } from "../access";
import { Logger } from "log4js";
import { AxiosInstance } from "axios";
export abstract class AbstractDnsProvider extends AbstractRegistrable<DnsProviderDefine> implements IDnsProvider {
access!: AbstractAccess;
logger!: Logger;
http!: AxiosInstance;
doInit(options: { access: AbstractAccess; logger: Logger; http: AxiosInstance }) {
this.access = options.access;
this.logger = options.logger;
this.http = options.http;
this.onInit();
}
protected abstract onInit(): void;
abstract createRecord(options: CreateRecordOptions): Promise<any>;
abstract removeRecord(options: RemoveRecordOptions): Promise<any>;
}
@@ -1,19 +0,0 @@
import { Registrable } from "../registry";
export type DnsProviderDefine = Registrable & {
accessType: string;
};
export type CreateRecordOptions = {
fullRecord: string;
type: string;
value: any;
};
export type RemoveRecordOptions = CreateRecordOptions & {
record: any;
};
export interface IDnsProvider {
createRecord(options: CreateRecordOptions): Promise<any>;
removeRecord(options: RemoveRecordOptions): Promise<any>;
}
@@ -1,20 +0,0 @@
// src/decorator/memoryCache.decorator.ts
import { dnsProviderRegistry } from "./registry";
import { DnsProviderDefine } from "./api";
import { Decorator } from "../decorator";
// 提供一个唯一 key
export const DNS_PROVIDER_CLASS_KEY = "pipeline:dns-provider";
export function IsDnsProvider(define: DnsProviderDefine): ClassDecorator {
return (target: any) => {
target = Decorator.target(target);
Reflect.defineMetadata(DNS_PROVIDER_CLASS_KEY, define, target);
target.define = define;
dnsProviderRegistry.register(define.name, {
define,
target,
});
};
}
@@ -1,3 +0,0 @@
export * from "./api";
export * from "./registry";
export * from "./decorator";
@@ -1,4 +0,0 @@
import { Registry } from "../registry";
// @ts-ignore
export const dnsProviderRegistry = new Registry();
+1 -1
View File
@@ -2,8 +2,8 @@ export * from "./core";
export * from "./d.ts";
export * from "./access";
export * from "./registry";
export * from "./dns-provider";
export * from "./plugin";
export * from "./utils";
export * from "./midway";
export * from "./context";
export * from "./decorator";
+2 -17
View File
@@ -2,6 +2,7 @@ import _ from "lodash";
import { pluginRegistry } from "./registry";
import { PluginDefine, TaskInputDefine, TaskOutputDefine } from "./api";
import { Decorator } from "../decorator";
import { AUTOWIRE_KEY } from "../decorator";
// 提供一个唯一 key
export const PLUGIN_CLASS_KEY = "pipeline:plugin";
@@ -20,7 +21,7 @@ export function IsTaskPlugin(define: PluginDefine): ClassDecorator {
inputs[property] = input;
}
const autowire = Reflect.getMetadata(PLUGIN_AUTOWIRE_KEY, target, property);
const autowire = Reflect.getMetadata(AUTOWIRE_KEY, target, property);
if (autowire) {
autowires[property] = autowire;
}
@@ -59,19 +60,3 @@ export function TaskOutput(output?: TaskOutputDefine): PropertyDecorator {
Reflect.defineMetadata(PLUGIN_OUTPUT_KEY, output, target, propertyKey);
};
}
export type AutowireProp = {
name?: string;
type?: any;
};
export const PLUGIN_AUTOWIRE_KEY = "pipeline:plugin:autowire";
export function Autowire(props?: AutowireProp): PropertyDecorator {
return (target, propertyKey) => {
const _type = Reflect.getMetadata("design:type", target, propertyKey);
target = Decorator.target(target, propertyKey);
props = props || {};
props.type = _type;
Reflect.defineMetadata(PLUGIN_AUTOWIRE_KEY, props || {}, target, propertyKey);
};
}
@@ -20,7 +20,7 @@ export class Registry {
this.storage[key] = value;
}
get(name: string) {
get(name: string): RegistryItem {
if (!name) {
throw new Error("插件名称不能为空");
}
+1 -1
View File
@@ -32,4 +32,4 @@ export function buildLogger(write: (text: string) => void) {
});
return logger;
}
export type LOGGER = Logger;
export type ILogger = Logger;
+2 -2
View File
@@ -1,4 +1,4 @@
import { IsTaskPlugin, TaskInput, ITaskPlugin, LOGGER, Autowire, TaskOutput } from "../src";
import { IsTaskPlugin, TaskInput, ITaskPlugin, ILogger, Autowire, TaskOutput } from "../src";
@IsTaskPlugin({
name: "EchoPlugin",
@@ -15,7 +15,7 @@ export class EchoPlugin implements ITaskPlugin {
cert!: any;
@Autowire()
logger!: LOGGER;
logger!: ILogger;
@TaskOutput({
title: "cert info",