mirror of
https://github.com/certd/certd.git
synced 2026-04-24 20:57:26 +08:00
feat: midway注解方式编写插件
This commit is contained in:
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
@@ -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();
|
||||
@@ -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,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("插件名称不能为空");
|
||||
}
|
||||
|
||||
@@ -32,4 +32,4 @@ export function buildLogger(write: (text: string) => void) {
|
||||
});
|
||||
return logger;
|
||||
}
|
||||
export type LOGGER = Logger;
|
||||
export type ILogger = Logger;
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user