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 { ConcurrencyStrategy, NotificationWhen, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task, ResultError } from "../dt/index.js";
 | 
				
			||||||
import { RunHistory, RunnableCollection } from "./run-history.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 { ContextFactory, IContext } from "./context.js";
 | 
				
			||||||
import { IStorage } from "./storage.js";
 | 
					import { IStorage } from "./storage.js";
 | 
				
			||||||
import { createAxiosService, hashUtils, HttpRequestConfig, ILogger, logger, utils } from "@certd/basic";
 | 
					import { createAxiosService, hashUtils, HttpRequestConfig, ILogger, logger, utils } from "@certd/basic";
 | 
				
			||||||
| 
						 | 
					@ -261,6 +261,7 @@ export class Executor {
 | 
				
			||||||
    const resList: ResultType[] = [];
 | 
					    const resList: ResultType[] = [];
 | 
				
			||||||
    for (const step of task.steps) {
 | 
					    for (const step of task.steps) {
 | 
				
			||||||
      step.runnableType = "step";
 | 
					      step.runnableType = "step";
 | 
				
			||||||
 | 
					      // @ts-ignore
 | 
				
			||||||
      const res: ResultType = await this.runWithHistory(step, "step", async () => {
 | 
					      const res: ResultType = await this.runWithHistory(step, "step", async () => {
 | 
				
			||||||
        return await this.runStep(step);
 | 
					        return await this.runStep(step);
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
| 
						 | 
					@ -276,8 +277,22 @@ export class Executor {
 | 
				
			||||||
    //执行任务
 | 
					    //执行任务
 | 
				
			||||||
    const plugin: RegistryItem<AbstractTaskPlugin> = pluginRegistry.get(step.type);
 | 
					    const plugin: RegistryItem<AbstractTaskPlugin> = pluginRegistry.get(step.type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // @ts-ignore
 | 
					    //@ts-ignore
 | 
				
			||||||
    const instance: ITaskPlugin = new plugin.target();
 | 
					    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
 | 
					    // @ts-ignore
 | 
				
			||||||
    const define: PluginDefine = plugin.define;
 | 
					    const define: PluginDefine = plugin.define;
 | 
				
			||||||
    const pluginName = define.name;
 | 
					    const pluginName = define.name;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,10 +8,10 @@ export type Registrable = {
 | 
				
			||||||
  deprecated?: string;
 | 
					  deprecated?: string;
 | 
				
			||||||
  order?: number;
 | 
					  order?: number;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					export type TargetGetter<T> = () => Promise<T>;
 | 
				
			||||||
export type RegistryItem<T> = {
 | 
					export type RegistryItem<T> = {
 | 
				
			||||||
  define: Registrable;
 | 
					  define: Registrable;
 | 
				
			||||||
  target: T;
 | 
					  target: T | TargetGetter<T>;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type OnRegisterContext<T> = {
 | 
					export type OnRegisterContext<T> = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,8 @@ title: 阿里云授权
 | 
				
			||||||
desc: 阿里云授权
 | 
					desc: 阿里云授权
 | 
				
			||||||
icon: fa-cloud
 | 
					icon: fa-cloud
 | 
				
			||||||
type: access
 | 
					type: access
 | 
				
			||||||
 | 
					dependentPlugins:
 | 
				
			||||||
 | 
					  - greper/AliyunSdk
 | 
				
			||||||
metadata:
 | 
					metadata:
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    - "@alicloud/pop-core": "^1.7.10"
 | 
					    - "@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 { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core";
 | 
				
			||||||
import { BaseService, PageReq } from '@certd/lib-server';
 | 
					import { BaseService, PageReq } from "@certd/lib-server";
 | 
				
			||||||
import { PluginEntity } from '../entity/plugin.js';
 | 
					import { PluginEntity } from "../entity/plugin.js";
 | 
				
			||||||
import { InjectEntityModel } from '@midwayjs/typeorm';
 | 
					import { InjectEntityModel } from "@midwayjs/typeorm";
 | 
				
			||||||
import { Repository } from 'typeorm';
 | 
					import { Repository } from "typeorm";
 | 
				
			||||||
import { isComm } from '@certd/plus-core';
 | 
					import { isComm } from "@certd/plus-core";
 | 
				
			||||||
import { BuiltInPluginService } from '../../pipeline/service/builtin-plugin-service.js';
 | 
					import { BuiltInPluginService } from "../../pipeline/service/builtin-plugin-service.js";
 | 
				
			||||||
import { merge } from 'lodash-es';
 | 
					import { merge } from "lodash-es";
 | 
				
			||||||
 | 
					import { accessRegistry, pluginRegistry } from "@certd/pipeline";
 | 
				
			||||||
 | 
					import { dnsProviderRegistry } from "@certd/plugin-cert";
 | 
				
			||||||
 | 
					import { logger } from "@certd/basic";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Provide()
 | 
					@Provide()
 | 
				
			||||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
 | 
					@Scope(ScopeEnum.Request, { allowDowngrade: true })
 | 
				
			||||||
| 
						 | 
					@ -28,7 +31,7 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
				
			||||||
      records: builtInList,
 | 
					      records: builtInList,
 | 
				
			||||||
      total: builtInList.length,
 | 
					      total: builtInList.length,
 | 
				
			||||||
      offset: 0,
 | 
					      offset: 0,
 | 
				
			||||||
      limit: 99999,
 | 
					      limit: 99999
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,9 +49,9 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const list = await this.list({
 | 
					    const list = await this.list({
 | 
				
			||||||
      query: {
 | 
					      query: {
 | 
				
			||||||
        type: 'builtIn',
 | 
					        type: "builtIn",
 | 
				
			||||||
        disabled: true,
 | 
					        disabled: true
 | 
				
			||||||
      },
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    const disabledNames = list.map(it => it.name);
 | 
					    const disabledNames = list.map(it => it.name);
 | 
				
			||||||
    for (const key in groups) {
 | 
					    for (const key in groups) {
 | 
				
			||||||
| 
						 | 
					@ -60,6 +63,7 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return groups;
 | 
					    return groups;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async getEnabledBuiltInList(): Promise<any> {
 | 
					  async getEnabledBuiltInList(): Promise<any> {
 | 
				
			||||||
    const builtInList = this.builtInPluginService.getList();
 | 
					    const builtInList = this.builtInPluginService.getList();
 | 
				
			||||||
    if (!isComm()) {
 | 
					    if (!isComm()) {
 | 
				
			||||||
| 
						 | 
					@ -68,9 +72,9 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const list = await this.list({
 | 
					    const list = await this.list({
 | 
				
			||||||
      query: {
 | 
					      query: {
 | 
				
			||||||
        type: 'builtIn',
 | 
					        type: "builtIn",
 | 
				
			||||||
        disabled: true,
 | 
					        disabled: true
 | 
				
			||||||
      },
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    const disabledNames = list.map(it => it.name);
 | 
					    const disabledNames = list.map(it => it.name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,8 +85,8 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
				
			||||||
    const builtInList = this.builtInPluginService.getList();
 | 
					    const builtInList = this.builtInPluginService.getList();
 | 
				
			||||||
    const list = await this.list({
 | 
					    const list = await this.list({
 | 
				
			||||||
      query: {
 | 
					      query: {
 | 
				
			||||||
        type: 'builtIn',
 | 
					        type: "builtIn"
 | 
				
			||||||
      },
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const records: PluginEntity[] = [];
 | 
					    const records: PluginEntity[] = [];
 | 
				
			||||||
| 
						 | 
					@ -96,10 +100,10 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
				
			||||||
      merge(record, {
 | 
					      merge(record, {
 | 
				
			||||||
        name: item.name,
 | 
					        name: item.name,
 | 
				
			||||||
        title: item.title,
 | 
					        title: item.title,
 | 
				
			||||||
        type: 'builtIn',
 | 
					        type: "builtIn",
 | 
				
			||||||
        icon: item.icon,
 | 
					        icon: item.icon,
 | 
				
			||||||
        desc: item.desc,
 | 
					        desc: item.desc,
 | 
				
			||||||
        group: item.group,
 | 
					        group: item.group
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      records.push(record);
 | 
					      records.push(record);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -109,7 +113,7 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
				
			||||||
  async setDisabled(opts: { id?: number; name?: string; type: string; disabled: boolean }) {
 | 
					  async setDisabled(opts: { id?: number; name?: string; type: string; disabled: boolean }) {
 | 
				
			||||||
    const { id, name, type, disabled } = opts;
 | 
					    const { id, name, type, disabled } = opts;
 | 
				
			||||||
    if (!type) {
 | 
					    if (!type) {
 | 
				
			||||||
      throw new Error('参数错误: type 不能为空');
 | 
					      throw new Error("参数错误: type 不能为空");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (id > 0) {
 | 
					    if (id > 0) {
 | 
				
			||||||
      //update
 | 
					      //update
 | 
				
			||||||
| 
						 | 
					@ -117,7 +121,7 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (name && type === 'builtIn') {
 | 
					    if (name && type === "builtIn") {
 | 
				
			||||||
      const pluginEntity = new PluginEntity();
 | 
					      const pluginEntity = new PluginEntity();
 | 
				
			||||||
      pluginEntity.name = name;
 | 
					      pluginEntity.name = name;
 | 
				
			||||||
      pluginEntity.type = type;
 | 
					      pluginEntity.type = type;
 | 
				
			||||||
| 
						 | 
					@ -125,10 +129,71 @@ export class PluginService extends BaseService<PluginEntity> {
 | 
				
			||||||
      await this.repository.save(pluginEntity);
 | 
					      await this.repository.save(pluginEntity);
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    throw new Error('参数错误: id 和 name 必须有一个');
 | 
					    throw new Error("参数错误: id 和 name 必须有一个");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async getDefineByType(type: string) {
 | 
					  async getDefineByType(type: string) {
 | 
				
			||||||
    return this.builtInPluginService.getByType(type);
 | 
					    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