mirror of https://github.com/certd/certd
				
				
				
			chore:
							parent
							
								
									04acd08ad2
								
							
						
					
					
						commit
						61e322678b
					
				| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
import { ConcurrencyStrategy, NotificationWhen, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task, ResultError } from "../dt/index.js";
 | 
			
		||||
import { RunHistory, RunnableCollection } from "./run-history.js";
 | 
			
		||||
import { AbstractTaskPlugin, PluginDefine, pluginRegistry, TaskInstanceContext, UserInfo } from "../plugin/index.js";
 | 
			
		||||
import { AbstractTaskPlugin, ITaskPlugin, PluginDefine, pluginRegistry, TaskInstanceContext, UserInfo } from "../plugin/index.js";
 | 
			
		||||
import { ContextFactory, IContext } from "./context.js";
 | 
			
		||||
import { IStorage } from "./storage.js";
 | 
			
		||||
import { createAxiosService, hashUtils, HttpRequestConfig, ILogger, logger, utils } from "@certd/basic";
 | 
			
		||||
| 
						 | 
				
			
			@ -261,6 +261,7 @@ export class Executor {
 | 
			
		|||
    const resList: ResultType[] = [];
 | 
			
		||||
    for (const step of task.steps) {
 | 
			
		||||
      step.runnableType = "step";
 | 
			
		||||
      // @ts-ignore
 | 
			
		||||
      const res: ResultType = await this.runWithHistory(step, "step", async () => {
 | 
			
		||||
        return await this.runStep(step);
 | 
			
		||||
      });
 | 
			
		||||
| 
						 | 
				
			
			@ -276,8 +277,22 @@ export class Executor {
 | 
			
		|||
    //执行任务
 | 
			
		||||
    const plugin: RegistryItem<AbstractTaskPlugin> = pluginRegistry.get(step.type);
 | 
			
		||||
 | 
			
		||||
    // @ts-ignore
 | 
			
		||||
    const instance: ITaskPlugin = new plugin.target();
 | 
			
		||||
    //@ts-ignore
 | 
			
		||||
    let instance: ITaskPlugin = null;
 | 
			
		||||
    try {
 | 
			
		||||
      //@ts-ignore
 | 
			
		||||
      if (plugin.target.define) {
 | 
			
		||||
        //@ts-ignore
 | 
			
		||||
        instance = new plugin.target();
 | 
			
		||||
      } else {
 | 
			
		||||
        //@ts-ignore
 | 
			
		||||
        instance = await plugin.target();
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e: any) {
 | 
			
		||||
      currentLogger.error(`实例化插件失败:${e.message}`);
 | 
			
		||||
      throw new Error(`实例化插件失败`, e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // @ts-ignore
 | 
			
		||||
    const define: PluginDefine = plugin.define;
 | 
			
		||||
    const pluginName = define.name;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,10 +8,10 @@ export type Registrable = {
 | 
			
		|||
  deprecated?: string;
 | 
			
		||||
  order?: number;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export type TargetGetter<T> = () => Promise<T>;
 | 
			
		||||
export type RegistryItem<T> = {
 | 
			
		||||
  define: Registrable;
 | 
			
		||||
  target: T;
 | 
			
		||||
  target: T | TargetGetter<T>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export type OnRegisterContext<T> = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,8 @@ title: 阿里云授权
 | 
			
		|||
desc: 阿里云授权
 | 
			
		||||
icon: fa-cloud
 | 
			
		||||
type: access
 | 
			
		||||
 | 
			
		||||
dependentPlugins:
 | 
			
		||||
  - greper/AliyunSdk
 | 
			
		||||
metadata:
 | 
			
		||||
  dependencies:
 | 
			
		||||
    - "@alicloud/pop-core": "^1.7.10"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
ALTER TABLE pi_plugin ADD COLUMN "pluginType" varchar(100);
 | 
			
		||||
ALTER TABLE pi_plugin ADD COLUMN "metadata" varchar(40960);
 | 
			
		||||
ALTER TABLE pi_plugin ADD COLUMN "author" varchar(100);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
import { Autoload, Init, Inject, Scope, ScopeEnum } from "@midwayjs/core";
 | 
			
		||||
import { logger } from "@certd/basic";
 | 
			
		||||
import { PluginService } from "../plugin/service/plugin-service.js";
 | 
			
		||||
 | 
			
		||||
@Autoload()
 | 
			
		||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
 | 
			
		||||
export class AutoBLoadPlugins {
 | 
			
		||||
  @Inject()
 | 
			
		||||
  pluginService: PluginService;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  @Init()
 | 
			
		||||
  async init() {
 | 
			
		||||
    logger.info('加载插件开始');
 | 
			
		||||
    await this.pluginService.registerFromDb()
 | 
			
		||||
    logger.info('加载插件完成');
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +1,14 @@
 | 
			
		|||
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
 | 
			
		||||
import { BaseService, PageReq } from '@certd/lib-server';
 | 
			
		||||
import { PluginEntity } from '../entity/plugin.js';
 | 
			
		||||
import { InjectEntityModel } from '@midwayjs/typeorm';
 | 
			
		||||
import { Repository } from 'typeorm';
 | 
			
		||||
import { isComm } from '@certd/plus-core';
 | 
			
		||||
import { BuiltInPluginService } from '../../pipeline/service/builtin-plugin-service.js';
 | 
			
		||||
import { merge } from 'lodash-es';
 | 
			
		||||
import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core";
 | 
			
		||||
import { BaseService, PageReq } from "@certd/lib-server";
 | 
			
		||||
import { PluginEntity } from "../entity/plugin.js";
 | 
			
		||||
import { InjectEntityModel } from "@midwayjs/typeorm";
 | 
			
		||||
import { Repository } from "typeorm";
 | 
			
		||||
import { isComm } from "@certd/plus-core";
 | 
			
		||||
import { BuiltInPluginService } from "../../pipeline/service/builtin-plugin-service.js";
 | 
			
		||||
import { merge } from "lodash-es";
 | 
			
		||||
import { accessRegistry, pluginRegistry } from "@certd/pipeline";
 | 
			
		||||
import { dnsProviderRegistry } from "@certd/plugin-cert";
 | 
			
		||||
import { logger } from "@certd/basic";
 | 
			
		||||
 | 
			
		||||
@Provide()
 | 
			
		||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
 | 
			
		||||
| 
						 | 
				
			
			@ -28,7 +31,7 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
			
		|||
      records: builtInList,
 | 
			
		||||
      total: builtInList.length,
 | 
			
		||||
      offset: 0,
 | 
			
		||||
      limit: 99999,
 | 
			
		||||
      limit: 99999
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -46,9 +49,9 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
			
		|||
    }
 | 
			
		||||
    const list = await this.list({
 | 
			
		||||
      query: {
 | 
			
		||||
        type: 'builtIn',
 | 
			
		||||
        disabled: true,
 | 
			
		||||
      },
 | 
			
		||||
        type: "builtIn",
 | 
			
		||||
        disabled: true
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    const disabledNames = list.map(it => it.name);
 | 
			
		||||
    for (const key in groups) {
 | 
			
		||||
| 
						 | 
				
			
			@ -60,6 +63,7 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
			
		|||
    }
 | 
			
		||||
    return groups;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async getEnabledBuiltInList(): Promise<any> {
 | 
			
		||||
    const builtInList = this.builtInPluginService.getList();
 | 
			
		||||
    if (!isComm()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -68,9 +72,9 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
			
		|||
 | 
			
		||||
    const list = await this.list({
 | 
			
		||||
      query: {
 | 
			
		||||
        type: 'builtIn',
 | 
			
		||||
        disabled: true,
 | 
			
		||||
      },
 | 
			
		||||
        type: "builtIn",
 | 
			
		||||
        disabled: true
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    const disabledNames = list.map(it => it.name);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -81,8 +85,8 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
			
		|||
    const builtInList = this.builtInPluginService.getList();
 | 
			
		||||
    const list = await this.list({
 | 
			
		||||
      query: {
 | 
			
		||||
        type: 'builtIn',
 | 
			
		||||
      },
 | 
			
		||||
        type: "builtIn"
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const records: PluginEntity[] = [];
 | 
			
		||||
| 
						 | 
				
			
			@ -96,10 +100,10 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
			
		|||
      merge(record, {
 | 
			
		||||
        name: item.name,
 | 
			
		||||
        title: item.title,
 | 
			
		||||
        type: 'builtIn',
 | 
			
		||||
        type: "builtIn",
 | 
			
		||||
        icon: item.icon,
 | 
			
		||||
        desc: item.desc,
 | 
			
		||||
        group: item.group,
 | 
			
		||||
        group: item.group
 | 
			
		||||
      });
 | 
			
		||||
      records.push(record);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -109,7 +113,7 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
			
		|||
  async setDisabled(opts: { id?: number; name?: string; type: string; disabled: boolean }) {
 | 
			
		||||
    const { id, name, type, disabled } = opts;
 | 
			
		||||
    if (!type) {
 | 
			
		||||
      throw new Error('参数错误: type 不能为空');
 | 
			
		||||
      throw new Error("参数错误: type 不能为空");
 | 
			
		||||
    }
 | 
			
		||||
    if (id > 0) {
 | 
			
		||||
      //update
 | 
			
		||||
| 
						 | 
				
			
			@ -117,7 +121,7 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
			
		|||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (name && type === 'builtIn') {
 | 
			
		||||
    if (name && type === "builtIn") {
 | 
			
		||||
      const pluginEntity = new PluginEntity();
 | 
			
		||||
      pluginEntity.name = name;
 | 
			
		||||
      pluginEntity.type = type;
 | 
			
		||||
| 
						 | 
				
			
			@ -125,10 +129,71 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
			
		|||
      await this.repository.save(pluginEntity);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    throw new Error('参数错误: id 和 name 必须有一个');
 | 
			
		||||
    throw new Error("参数错误: id 和 name 必须有一个");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async getDefineByType(type: string) {
 | 
			
		||||
    return this.builtInPluginService.getByType(type);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async getPluginTarget(pluginName: string){
 | 
			
		||||
    //获取插件类实例对象
 | 
			
		||||
    let author = undefined;
 | 
			
		||||
    let name = '';
 | 
			
		||||
    if(pluginName.includes('/')){
 | 
			
		||||
      const arr = pluginName.split('/');
 | 
			
		||||
      author = arr[0];
 | 
			
		||||
      name = arr[1];
 | 
			
		||||
    }else {
 | 
			
		||||
      name = pluginName;
 | 
			
		||||
    }
 | 
			
		||||
    const info = await this.find({
 | 
			
		||||
      where: {
 | 
			
		||||
        name: name,
 | 
			
		||||
        author: author
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    if (info.length > 0) {
 | 
			
		||||
      const plugin = info[0];
 | 
			
		||||
      const AsyncFunction = Object.getPrototypeOf(async () => {}).constructor;
 | 
			
		||||
      const getPluginClass =  new AsyncFunction(plugin.content);
 | 
			
		||||
      return await getPluginClass();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * 从数据库加载插件
 | 
			
		||||
   */
 | 
			
		||||
  async registerFromDb() {
 | 
			
		||||
    const res = await this.list({
 | 
			
		||||
      buildQuery: ((bq) => {
 | 
			
		||||
        bq.andWhere( "type != :type", {
 | 
			
		||||
          type: 'builtIn'
 | 
			
		||||
        })
 | 
			
		||||
      })
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    for (const item of res) {
 | 
			
		||||
      const pluginName = item.author ? item.author +"/"+ item.name : item.name;
 | 
			
		||||
      let registry = null
 | 
			
		||||
      if(item.pluginType === 'access'){
 | 
			
		||||
        registry = accessRegistry;
 | 
			
		||||
      }else if (item.pluginType === 'plugin'){
 | 
			
		||||
        registry = pluginRegistry;
 | 
			
		||||
      }else if (item.pluginType === 'dnsProvider'){
 | 
			
		||||
        registry = dnsProviderRegistry
 | 
			
		||||
      }else {
 | 
			
		||||
        logger.warn(`插件${pluginName}类型错误:${item.pluginType}`)
 | 
			
		||||
        continue
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      registry.register(pluginName, {
 | 
			
		||||
        define:item,
 | 
			
		||||
        target: ()=>{
 | 
			
		||||
          return this.getPluginTarget(pluginName);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue