chore: format

This commit is contained in:
xiaojunnuo
2026-05-31 01:41:33 +08:00
parent acd440106b
commit 4b57a0d729
557 changed files with 12530 additions and 14039 deletions
@@ -1,44 +1,44 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
@Entity('pi_history_log')
@Entity("pi_history_log")
export class HistoryLogEntity {
@PrimaryGeneratedColumn()
id: number;
@Column({ name: 'user_id', comment: '用户id' })
@Column({ name: "user_id", comment: "用户id" })
userId: number;
@Column({ name: 'pipeline_id', comment: '流水线' })
@Column({ name: "pipeline_id", comment: "流水线" })
pipelineId: number;
@Column({ name: 'history_id', comment: '历史id' })
@Column({ name: "history_id", comment: "历史id" })
historyId: number;
@Column({
name: 'node_id',
comment: '任务节点id',
name: "node_id",
comment: "任务节点id",
length: 100,
nullable: true,
})
nodeId: string;
@Column({ comment: '日志内容', length: 40960, nullable: true })
@Column({ comment: "日志内容", length: 40960, nullable: true })
logs: string;
@Column({ name: 'project_id', comment: '项目id' })
@Column({ name: "project_id", comment: "项目id" })
projectId: number;
@Column({
name: 'create_time',
comment: '创建时间',
default: () => 'CURRENT_TIMESTAMP',
name: "create_time",
comment: "创建时间",
default: () => "CURRENT_TIMESTAMP",
})
createTime: Date;
@Column({
name: 'update_time',
comment: '修改时间',
default: () => 'CURRENT_TIMESTAMP',
name: "update_time",
comment: "修改时间",
default: () => "CURRENT_TIMESTAMP",
})
updateTime: Date;
}
@@ -1,47 +1,46 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
@Entity('pi_history')
@Entity("pi_history")
export class HistoryEntity {
@PrimaryGeneratedColumn()
id: number;
@Column({ name: 'user_id', comment: '用户id' })
@Column({ name: "user_id", comment: "用户id" })
userId: number;
@Column({ name: 'pipeline_id', comment: '流水线' })
@Column({ name: "pipeline_id", comment: "流水线" })
pipelineId: number;
@Column({ comment: '运行状态', length: 40960, nullable: true })
@Column({ comment: "运行状态", length: 40960, nullable: true })
pipeline: string;
@Column({ comment: '结果状态', length: 20, nullable: true })
@Column({ comment: "结果状态", length: 20, nullable: true })
status: string;
@Column({ name: 'trigger_type',comment: '触发类型', length: 20, nullable: true })
@Column({ name: "trigger_type", comment: "触发类型", length: 20, nullable: true })
triggerType: string;
@Column({
name: 'end_time',
comment: '结束时间',
name: "end_time",
comment: "结束时间",
nullable: true,
})
endTime: Date;
@Column({ name: 'project_id', comment: '项目id' })
@Column({ name: "project_id", comment: "项目id" })
projectId: number;
@Column({
name: 'create_time',
comment: '创建时间',
default: () => 'CURRENT_TIMESTAMP',
name: "create_time",
comment: "创建时间",
default: () => "CURRENT_TIMESTAMP",
})
createTime: Date;
@Column({
name: 'update_time',
comment: '修改时间',
default: () => 'CURRENT_TIMESTAMP',
name: "update_time",
comment: "修改时间",
default: () => "CURRENT_TIMESTAMP",
})
updateTime: Date;
pipelineTitle: string;
@@ -1,41 +1,41 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
@Entity('pi_notification')
@Entity("pi_notification")
export class NotificationEntity {
@PrimaryGeneratedColumn()
id: number;
@Column({ name: 'key_id', comment: 'key_id', length: 100 })
@Column({ name: "key_id", comment: "key_id", length: 100 })
keyId: string;
@Column({ name: 'user_id', comment: 'UserId' })
@Column({ name: "user_id", comment: "UserId" })
userId: number;
@Column({ name: 'type', comment: '通知类型' })
@Column({ name: "type", comment: "通知类型" })
type: string;
@Column({ name: 'name', comment: '名称' })
@Column({ name: "name", comment: "名称" })
name: string;
@Column({ name: 'setting', comment: '通知配置', length: 10240 })
@Column({ name: "setting", comment: "通知配置", length: 10240 })
setting: string;
@Column({ name: 'is_default', comment: '是否默认' })
@Column({ name: "is_default", comment: "是否默认" })
isDefault: boolean;
@Column({ name: 'project_id', comment: '项目id' })
@Column({ name: "project_id", comment: "项目id" })
projectId: number;
@Column({
name: 'create_time',
comment: '创建时间',
default: () => 'CURRENT_TIMESTAMP',
name: "create_time",
comment: "创建时间",
default: () => "CURRENT_TIMESTAMP",
})
createTime: Date;
@Column({
name: 'update_time',
comment: '修改时间',
default: () => 'CURRENT_TIMESTAMP',
name: "update_time",
comment: "修改时间",
default: () => "CURRENT_TIMESTAMP",
})
updateTime: Date;
}
@@ -1,36 +1,36 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
@Entity('pi_pipeline_group')
@Entity("pi_pipeline_group")
export class PipelineGroupEntity {
@PrimaryGeneratedColumn()
id: number;
@Column({ name: 'user_id', comment: '用户id' })
@Column({ name: "user_id", comment: "用户id" })
userId: number;
@Column({ name: 'name', comment: '分组名称' })
@Column({ name: "name", comment: "分组名称" })
name: string;
@Column({ name: 'icon', comment: '图标' })
@Column({ name: "icon", comment: "图标" })
icon: string;
@Column({ name: 'favorite', comment: '收藏' })
@Column({ name: "favorite", comment: "收藏" })
favorite: boolean;
@Column({ name: 'project_id', comment: '项目id' })
@Column({ name: "project_id", comment: "项目id" })
projectId: number;
@Column({
name: 'create_time',
comment: '创建时间',
default: () => 'CURRENT_TIMESTAMP',
name: "create_time",
comment: "创建时间",
default: () => "CURRENT_TIMESTAMP",
})
createTime: Date;
@Column({
name: 'update_time',
comment: '修改时间',
default: () => 'CURRENT_TIMESTAMP',
name: "update_time",
comment: "修改时间",
default: () => "CURRENT_TIMESTAMP",
})
updateTime: Date;
}
@@ -1,58 +1,58 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
@Entity('pi_pipeline')
@Entity("pi_pipeline")
export class PipelineEntity {
@PrimaryGeneratedColumn()
id: number;
@Column({ name: 'user_id', comment: '用户id' })
@Column({ name: "user_id", comment: "用户id" })
userId: number;
@Column({ name: 'title', comment: '标题' })
@Column({ name: "title", comment: "标题" })
title: string;
@Column({ comment: '配置', length: 40960 })
@Column({ comment: "配置", length: 40960 })
content: string;
@Column({ name: 'keep_history_count', comment: '历史记录保持数量', nullable: true })
@Column({ name: "keep_history_count", comment: "历史记录保持数量", nullable: true })
keepHistoryCount: number;
@Column({ name: 'group_id', comment: '分组id', nullable: true })
@Column({ name: "group_id", comment: "分组id", nullable: true })
groupId: number;
@Column({ comment: '备注', length: 100, nullable: true })
@Column({ comment: "备注", length: 100, nullable: true })
remark: string;
@Column({ comment: '状态', length: 100, nullable: true })
@Column({ comment: "状态", length: 100, nullable: true })
status: string;
@Column({ comment: '启用/禁用', nullable: true, default: false })
@Column({ comment: "启用/禁用", nullable: true, default: false })
disabled: boolean;
// cert_apply: 证书申请;cert_upload: 证书上传; backup: 备份; custom:自定义; template: 模板
@Column({ comment: '类型', nullable: true, default: 'cert' })
@Column({ comment: "类型", nullable: true, default: "cert" })
type: string;
@Column({ name: 'webhook_key', comment: 'webhookkey', length: 100, nullable: true })
@Column({ name: "webhook_key", comment: "webhookkey", length: 100, nullable: true })
webhookKey: string;
@Column({ name: 'trigger_count', comment: '触发器数量', nullable: true, default: 0 })
@Column({ name: "trigger_count", comment: "触发器数量", nullable: true, default: 0 })
triggerCount: number;
// custom: 自定义; monitor: 监控;
@Column({ comment: '来源', nullable: true, default: '' })
@Column({ comment: "来源", nullable: true, default: "" })
from: string;
@Column({ name:"template_id", comment: '关联模版id', nullable: true, default: 0 })
@Column({ name: "template_id", comment: "关联模版id", nullable: true, default: 0 })
templateId: number;
@Column({ name:"is_template", comment: '是否模版', nullable: true, default: false })
@Column({ name: "is_template", comment: "是否模版", nullable: true, default: false })
isTemplate: boolean;
@Column({name: 'last_history_time',comment: '最后一次执行时间',nullable: true,})
@Column({ name: "last_history_time", comment: "最后一次执行时间", nullable: true })
lastHistoryTime: number;
@Column({name: 'valid_time',comment: '到期时间',nullable: true,default: 0})
@Column({ name: "valid_time", comment: "到期时间", nullable: true, default: 0 })
validTime: number;
// 变量
@@ -60,19 +60,18 @@ export class PipelineEntity {
nextRunTime: number;
@Column({name: 'order', comment: '排序', nullable: true,})
@Column({ name: "order", comment: "排序", nullable: true })
order: number;
@Column({ name: 'project_id', comment: '项目id' })
@Column({ name: "project_id", comment: "项目id" })
projectId: number;
@Column({name: 'create_time',comment: '创建时间', default: () => 'CURRENT_TIMESTAMP',})
@Column({ name: "create_time", comment: "创建时间", default: () => "CURRENT_TIMESTAMP" })
createTime: Date;
@Column({
name: 'update_time',
comment: '修改时间',
default: () => 'CURRENT_TIMESTAMP',
name: "update_time",
comment: "修改时间",
default: () => "CURRENT_TIMESTAMP",
})
updateTime: Date;
}
@@ -1,41 +1,41 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
@Entity('pi_storage')
@Entity("pi_storage")
export class StorageEntity {
@PrimaryGeneratedColumn()
id: number;
@Column({ name: 'user_id', comment: '用户id' })
@Column({ name: "user_id", comment: "用户id" })
userId: number;
@Column({ name: 'scope', comment: '范围' })
@Column({ name: "scope", comment: "范围" })
scope: string;
@Column({ name: 'namespace', comment: '命名空间' })
@Column({ name: "namespace", comment: "命名空间" })
namespace: string;
@Column({ comment: 'version', length: 100, nullable: true })
@Column({ comment: "version", length: 100, nullable: true })
version: string;
@Column({ comment: 'key', length: 100, nullable: true })
@Column({ comment: "key", length: 100, nullable: true })
key: string;
@Column({ comment: 'value', length: 40960, nullable: true })
@Column({ comment: "value", length: 40960, nullable: true })
value: string;
@Column({ name: 'project_id', comment: '项目id' })
@Column({ name: "project_id", comment: "项目id" })
projectId: number;
@Column({
name: 'create_time',
comment: '创建时间',
default: () => 'CURRENT_TIMESTAMP',
name: "create_time",
comment: "创建时间",
default: () => "CURRENT_TIMESTAMP",
})
createTime: Date;
@Column({
name: 'update_time',
comment: '修改时间',
default: () => 'CURRENT_TIMESTAMP',
name: "update_time",
comment: "修改时间",
default: () => "CURRENT_TIMESTAMP",
})
updateTime: Date;
}
@@ -1,35 +1,35 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
/**
* 子域名托管
*/
@Entity('pi_sub_domain')
@Entity("pi_sub_domain")
export class SubDomainEntity {
@PrimaryGeneratedColumn()
id: number;
@Column({ name: 'user_id', comment: 'UserId' })
@Column({ name: "user_id", comment: "UserId" })
userId: number;
@Column({ name: 'domain', comment: '子域名' })
@Column({ name: "domain", comment: "子域名" })
domain: string;
@Column({ name: 'disabled', comment: '禁用' })
@Column({ name: "disabled", comment: "禁用" })
disabled: boolean;
@Column({ name: 'project_id', comment: '项目Id' })
@Column({ name: "project_id", comment: "项目Id" })
projectId: number;
@Column({
name: 'create_time',
comment: '创建时间',
default: () => 'CURRENT_TIMESTAMP',
name: "create_time",
comment: "创建时间",
default: () => "CURRENT_TIMESTAMP",
})
createTime: Date;
@Column({
name: 'update_time',
comment: '修改时间',
default: () => 'CURRENT_TIMESTAMP',
name: "update_time",
comment: "修改时间",
default: () => "CURRENT_TIMESTAMP",
})
updateTime: Date;
}
@@ -1,57 +1,55 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
export type PipelineTemplateType = {
input: {
[key: string]: {
value: string;
value: string;
};
}
}
};
};
@Entity('pi_template')
@Entity("pi_template")
export class TemplateEntity {
@PrimaryGeneratedColumn()
id: number;
@Column({ name: 'user_id', comment: '用户id' })
@Column({ name: "user_id", comment: "用户id" })
userId: number;
@Column({ name: 'pipeline_id', comment: '流水线id' })
@Column({ name: "pipeline_id", comment: "流水线id" })
pipelineId: number;
@Column({ name: 'title', comment: '标题' })
@Column({ name: "title", comment: "标题" })
title: string;
@Column({ name: 'desc', comment: '说明' })
@Column({ name: "desc", comment: "说明" })
desc: string;
@Column({ comment: '配置', length: 40960 })
@Column({ comment: "配置", length: 40960 })
content: string;
@Column({ comment: '启用/禁用', nullable: true, default: false })
@Column({ comment: "启用/禁用", nullable: true, default: false })
disabled: boolean;
@Column({
name: 'order',
comment: '排序',
name: "order",
comment: "排序",
nullable: true,
})
order: number;
@Column({ name: 'project_id', comment: '项目id' })
@Column({ name: "project_id", comment: "项目id" })
projectId: number;
@Column({
name: 'create_time',
comment: '创建时间',
default: () => 'CURRENT_TIMESTAMP',
name: "create_time",
comment: "创建时间",
default: () => "CURRENT_TIMESTAMP",
})
createTime: Date;
@Column({
name: 'update_time',
comment: '修改时间',
default: () => 'CURRENT_TIMESTAMP',
name: "update_time",
comment: "修改时间",
default: () => "CURRENT_TIMESTAMP",
})
updateTime: Date;
}
@@ -1,5 +1,5 @@
import { HistoryEntity } from '../history.js';
import { HistoryLogEntity } from '../history-log.js';
import { HistoryEntity } from "../history.js";
import { HistoryLogEntity } from "../history-log.js";
export class HistoryDetail {
history: HistoryEntity;
@@ -1,6 +1,6 @@
import { PipelineEntity } from '../pipeline.js';
import { HistoryEntity } from '../history.js';
import { HistoryLogEntity } from '../history-log.js';
import { PipelineEntity } from "../pipeline.js";
import { HistoryEntity } from "../history.js";
import { HistoryLogEntity } from "../history-log.js";
export class PipelineDetail {
pipeline: PipelineEntity;
@@ -8,15 +8,13 @@ import { AddonService, newAddon, PermissionException, ValidateException } from "
*/
@Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true })
export class AddonGetterService {
export class AddonGetterService {
@Inject()
taskServiceBuilder: TaskServiceBuilder;
@Inject()
addonService: AddonService;
async getAddonById(id: any, checkUserId: boolean, userId?: number, projectId?: number, defaultAddon?:{type:string,name:string} ): Promise<any> {
async getAddonById(id: any, checkUserId: boolean, userId?: number, projectId?: number, defaultAddon?: { type: string; name: string }): Promise<any> {
const serviceGetter = this.taskServiceBuilder.create({
userId,
projectId,
@@ -25,8 +23,8 @@ export class AddonGetterService {
http,
logger,
utils,
serviceGetter
}
serviceGetter,
};
if (!id) {
if (!defaultAddon) {
@@ -53,7 +51,7 @@ export class AddonGetterService {
const setting = JSON.parse(entity.setting ?? "{}");
const input = {
id: entity.id,
...setting
...setting,
};
return await newAddon(entity.addonType, entity.type, input, ctx);
@@ -63,11 +61,10 @@ export class AddonGetterService {
return await this.getAddonById(id, true, userId, projectId);
}
async getBlank(addonType:string,subType:string,projectId?: number){
return await this.getAddonById(null,false,0,projectId,{
type: addonType, name:subType
})
async getBlank(addonType: string, subType: string, projectId?: number) {
return await this.getAddonById(null, false, 0, projectId, {
type: addonType,
name: subType,
});
}
}
@@ -1,6 +1,6 @@
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { pluginGroups, pluginRegistry } from '@certd/pipeline';
import { cloneDeep } from 'lodash-es';
import { Provide, Scope, ScopeEnum } from "@midwayjs/core";
import { pluginGroups, pluginRegistry } from "@certd/pipeline";
import { cloneDeep } from "lodash-es";
@Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true })
@@ -14,23 +14,23 @@ export class BuiltInPluginService {
continue;
}
//@ts-ignore
if(Plugin.define?.type && Plugin.define?.type.toLowerCase() !== 'builtin'){
if (Plugin.define?.type && Plugin.define?.type.toLowerCase() !== "builtin") {
continue;
}
list.push({ ...Plugin.define, key });
}
list = list.sort((a, b) => {
return (a.order ?? 10 )- (b.order ?? 10);
return (a.order ?? 10) - (b.order ?? 10);
});
return list;
}
getGroups() {
const groups:any = cloneDeep(pluginGroups);
const groups: any = cloneDeep(pluginGroups);
for (const key in groups) {
const group = groups[key];
group.plugins = group.plugins.sort((a, b) => {
return (a.order ?? 10 )- (b.order ?? 10);
return (a.order ?? 10) - (b.order ?? 10);
});
}
return groups;
@@ -1,5 +1,5 @@
import { IStorage } from '@certd/pipeline';
import { StorageService } from './storage-service.js';
import { IStorage } from "@certd/pipeline";
import { StorageService } from "./storage-service.js";
export class DbStorage implements IStorage {
/**
@@ -13,7 +13,7 @@ export class DbStorage implements IStorage {
}
async remove(scope: string, namespace: string, version: string, key: string): Promise<void> {
throw new Error('Method not implemented.');
throw new Error("Method not implemented.");
}
async get(scope: string, namespace: string, version: string, key: string): Promise<string | null> {
@@ -1,5 +1,5 @@
import { Provide } from '@midwayjs/core';
import { dnsProviderRegistry } from '@certd/plugin-cert';
import { Provide } from "@midwayjs/core";
import { dnsProviderRegistry } from "@certd/plugin-cert";
@Provide()
export class DnsProviderService {
@@ -1,7 +1,7 @@
import { CertInfo, CertReader, ICertInfoGetter } from '@certd/plugin-lib';
import { CertInfoService } from '../../../monitor/index.js';
import { CertInfo, CertReader, ICertInfoGetter } from "@certd/plugin-lib";
import { CertInfoService } from "../../../monitor/index.js";
export class CertInfoGetter implements ICertInfoGetter {
export class CertInfoGetter implements ICertInfoGetter {
userId: number;
projectId: number;
certInfoService: CertInfoService;
@@ -12,20 +12,20 @@ export class CertInfoGetter implements ICertInfoGetter {
}
async getByPipelineId(pipelineId: number): Promise<CertInfo> {
if (!pipelineId) {
throw new Error(`流水线id不能为空`)
}
const query :any= {
pipelineId,
userId: this.userId,
throw new Error(`流水线id不能为空`);
}
const query: any = {
pipelineId,
userId: this.userId,
};
if (this.projectId) {
query.projectId = this.projectId
query.projectId = this.projectId;
}
const entity = await this.certInfoService.findOne({
where:query
})
const entity = await this.certInfoService.findOne({
where: query,
});
if (!entity || !entity.certInfo) {
throw new Error(`流水线(${pipelineId})还未生成证书,请先运行一次流水线`)
throw new Error(`流水线(${pipelineId})还未生成证书,请先运行一次流水线`);
}
return new CertReader(JSON.parse(entity.certInfo)).cert;
}
@@ -1,4 +1,4 @@
import { CnameRecord, ICnameProxyService } from '@certd/pipeline';
import { CnameRecord, ICnameProxyService } from "@certd/pipeline";
export class CnameProxyService implements ICnameProxyService {
userId: number;
@@ -1,5 +1,5 @@
import {DomainVerifiers, IDomainVerifierGetter} from "@certd/plugin-cert";
import {DomainService} from "../../../cert/service/domain-service.js";
import { DomainVerifiers, IDomainVerifierGetter } from "@certd/plugin-cert";
import { DomainService } from "../../../cert/service/domain-service.js";
export class DomainVerifierGetter implements IDomainVerifierGetter {
private userId: number;
@@ -12,8 +12,7 @@ export class DomainVerifierGetter implements IDomainVerifierGetter {
this.domainService = domainService;
}
async getVerifiers(domains: string[]): Promise<DomainVerifiers>{
return await this.domainService.getDomainVerifiers(this.userId,this.projectId,domains);
async getVerifiers(domains: string[]): Promise<DomainVerifiers> {
return await this.domainService.getDomainVerifiers(this.userId, this.projectId, domains);
}
}
@@ -1,5 +1,5 @@
import { INotificationService, NotificationSendReq } from '@certd/pipeline';
import {NotificationService} from "../notification-service.js";
import { INotificationService, NotificationSendReq } from "@certd/pipeline";
import { NotificationService } from "../notification-service.js";
export class NotificationGetter implements INotificationService {
userId: number;
@@ -1,20 +1,18 @@
import { SysSettingsService, SysInstallInfo } from "@certd/lib-server";
import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core";
import { SiteInfo ,ISiteInfoGetter} from "@certd/plugin-lib";
import { SiteInfo, ISiteInfoGetter } from "@certd/plugin-lib";
@Provide("siteInfoGetter")
@Scope(ScopeEnum.Request, { allowDowngrade: true })
export class SiteInfoGetter implements ISiteInfoGetter{
@Inject()
sysSettingsService: SysSettingsService;
export class SiteInfoGetter implements ISiteInfoGetter {
@Inject()
sysSettingsService: SysSettingsService;
async getSiteInfo(): Promise<SiteInfo> {
const installInfo = await this.sysSettingsService.getSetting<SysInstallInfo>(SysInstallInfo);
async getSiteInfo(): Promise<SiteInfo> {
const installInfo = await this.sysSettingsService.getSetting<SysInstallInfo>(SysInstallInfo);
return {
siteUrl: installInfo?.bindUrl || "",
}
}
return {
siteUrl: installInfo?.bindUrl || "",
};
}
}
@@ -19,7 +19,7 @@ export class SubDomainsGetter implements ISubDomainsGetter {
}
async getSubDomains() {
const projectSubDomains = await this.subDomainService.getListByUserId(this.userId, this.projectId) || [];
const projectSubDomains = (await this.subDomainService.getListByUserId(this.userId, this.projectId)) || [];
const cnameProviderSubDomains = await this.cnameProviderService.getSubDomains();
return [...projectSubDomains, ...cnameProviderSubDomains]
.map(item => item?.trim())
@@ -28,8 +28,8 @@ export class SubDomainsGetter implements ISubDomainsGetter {
}
async hasSubDomain(fullDomain: string) {
let arr = fullDomain.split(".")
const subDomains = await this.getSubDomains()
let arr = fullDomain.split(".");
const subDomains = await this.getSubDomains();
if (subDomains && subDomains.length > 0) {
const fullDomainDot = "." + fullDomain;
for (const subDomain of subDomains) {
@@ -41,40 +41,38 @@ export class SubDomainsGetter implements ISubDomainsGetter {
if (subDomain.startsWith("*.")) {
//如果子域名配置的是泛域名,说明这一层及以下的子域名都是托管的
//以fullDomain在这一层的子域名作为返回值
const nonStarDomain = subDomain.slice(1)
const nonStarDomain = subDomain.slice(1);
if (fullDomainDot.endsWith(nonStarDomain)) {
//提取fullDomain在这一层的子域名
const fullArr = arr.reverse()
const subArr = subDomain.split(".").reverse()
let strBuilder = ""
for (let i =0 ;i<subArr.length;i++) {
const fullArr = arr.reverse();
const subArr = subDomain.split(".").reverse();
let strBuilder = "";
for (let i = 0; i < subArr.length; i++) {
if (strBuilder) {
strBuilder = fullArr[i] + "." + strBuilder
strBuilder = fullArr[i] + "." + strBuilder;
} else {
strBuilder = fullArr[i]
strBuilder = fullArr[i];
}
}
return strBuilder
return strBuilder;
}
}
}
}
while (arr.length > 0) {
const subDomain = arr.join(".")
const subDomain = arr.join(".");
const domain = await this.domainService.findOne({
where: {
userId: this.userId,
domain: subDomain,
challengeType: "dns",
}
})
},
});
if (domain) {
return subDomain
return subDomain;
}
arr = arr.slice(1)
arr = arr.slice(1);
}
return null
return null;
}
}
@@ -14,93 +14,87 @@ import { CertInfoService } from "../../../monitor/index.js";
import { ICertInfoGetter } from "@certd/plugin-lib";
import { CnameProviderService } from "../../../cname/service/cname-provider-service.js";
const serviceNames = [
'ocrService',
]
export class TaskServiceGetter implements IServiceGetter{
const serviceNames = ["ocrService"];
export class TaskServiceGetter implements IServiceGetter {
private userId: number;
private projectId: number;
private appCtx : IMidwayContainer;
constructor(userId:number,projectId:number,appCtx:IMidwayContainer) {
private appCtx: IMidwayContainer;
constructor(userId: number, projectId: number, appCtx: IMidwayContainer) {
this.userId = userId;
this.projectId = projectId;
this.appCtx = appCtx
this.appCtx = appCtx;
}
async get<T>(serviceName: string): Promise<T> {
if(serviceName === 'subDomainsGetter'){
return await this.getSubDomainsGetter() as T
} if (serviceName === 'accessService') {
return await this.getAccessService() as T
} else if (serviceName === 'cnameProxyService') {
return await this.getCnameProxyService() as T
} else if (serviceName === 'notificationService') {
return await this.getNotificationService() as T
} else if (serviceName === 'domainVerifierGetter') {
return await this.getDomainVerifierGetter() as T
} else if (serviceName === 'certInfoGetter') {
return await this.getCertInfoGetter() as T
}else{
if(!serviceNames.includes(serviceName)){
throw new Error(`${serviceName} not in whitelist`)
if (serviceName === "subDomainsGetter") {
return (await this.getSubDomainsGetter()) as T;
}
if (serviceName === "accessService") {
return (await this.getAccessService()) as T;
} else if (serviceName === "cnameProxyService") {
return (await this.getCnameProxyService()) as T;
} else if (serviceName === "notificationService") {
return (await this.getNotificationService()) as T;
} else if (serviceName === "domainVerifierGetter") {
return (await this.getDomainVerifierGetter()) as T;
} else if (serviceName === "certInfoGetter") {
return (await this.getCertInfoGetter()) as T;
} else {
if (!serviceNames.includes(serviceName)) {
throw new Error(`${serviceName} not in whitelist`);
}
const service = await this.appCtx.getAsync(serviceName)
if (! service){
throw new Error(`${serviceName} not found`)
const service = await this.appCtx.getAsync(serviceName);
if (!service) {
throw new Error(`${serviceName} not found`);
}
}
}
async getSubDomainsGetter(): Promise<SubDomainsGetter> {
const subDomainsService:SubDomainService = await this.appCtx.getAsync("subDomainService")
const domainService:DomainService = await this.appCtx.getAsync("domainService")
const cnameProviderService:CnameProviderService = await this.appCtx.getAsync("cnameProviderService")
return new SubDomainsGetter(this.userId,this.projectId, subDomainsService,domainService,cnameProviderService)
const subDomainsService: SubDomainService = await this.appCtx.getAsync("subDomainService");
const domainService: DomainService = await this.appCtx.getAsync("domainService");
const cnameProviderService: CnameProviderService = await this.appCtx.getAsync("cnameProviderService");
return new SubDomainsGetter(this.userId, this.projectId, subDomainsService, domainService, cnameProviderService);
}
async getCertInfoGetter(): Promise<ICertInfoGetter> {
const certInfoService:CertInfoService = await this.appCtx.getAsync("certInfoService")
return new CertInfoGetter(this.userId, this.projectId, certInfoService)
const certInfoService: CertInfoService = await this.appCtx.getAsync("certInfoService");
return new CertInfoGetter(this.userId, this.projectId, certInfoService);
}
async getAccessService(): Promise<AccessGetter> {
const accessService:AccessService = await this.appCtx.getAsync("accessService")
const accessService: AccessService = await this.appCtx.getAsync("accessService");
return new AccessGetter(this.userId, this.projectId, accessService.getById.bind(accessService));
}
async getCnameProxyService(): Promise<CnameProxyService> {
const cnameRecordService:CnameRecordService = await this.appCtx.getAsync("cnameRecordService")
const cnameRecordService: CnameRecordService = await this.appCtx.getAsync("cnameRecordService");
return new CnameProxyService(this.userId, this.projectId, cnameRecordService.getWithAccessByDomain.bind(cnameRecordService));
}
async getNotificationService(): Promise<NotificationGetter> {
const notificationService:NotificationService = await this.appCtx.getAsync("notificationService")
const notificationService: NotificationService = await this.appCtx.getAsync("notificationService");
return new NotificationGetter(this.userId, this.projectId, notificationService);
}
async getDomainVerifierGetter(): Promise<DomainVerifierGetter> {
const domainService:DomainService = await this.appCtx.getAsync("domainService")
const domainService: DomainService = await this.appCtx.getAsync("domainService");
return new DomainVerifierGetter(this.userId, this.projectId, domainService);
}
}
@Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true })
export class TaskServiceBuilder {
export class TaskServiceBuilder {
@ApplicationContext()
appCtx: IMidwayContainer;
create(req:TaskServiceCreateReq){
create(req: TaskServiceCreateReq) {
const userId = req.userId;
const projectId = req.projectId;
return new TaskServiceGetter(userId,projectId,this.appCtx)
return new TaskServiceGetter(userId, projectId, this.appCtx);
}
}
export type TaskServiceCreateReq = {
userId: number;
projectId?: number;
}
};
@@ -1,8 +1,8 @@
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { In, Repository } from 'typeorm';
import { BaseService } from '@certd/lib-server';
import { HistoryLogEntity } from '../entity/history-log.js';
import { Provide, Scope, ScopeEnum } from "@midwayjs/core";
import { InjectEntityModel } from "@midwayjs/typeorm";
import { In, Repository } from "typeorm";
import { BaseService } from "@certd/lib-server";
import { HistoryLogEntity } from "../entity/history-log.js";
/**
* 证书申请
@@ -1,16 +1,16 @@
import { Config, Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { In, MoreThan, Repository } from 'typeorm';
import { BaseService, PageReq } from '@certd/lib-server';
import { HistoryEntity } from '../entity/history.js';
import { PipelineEntity } from '../entity/pipeline.js';
import { HistoryDetail } from '../entity/vo/history-detail.js';
import { HistoryLogService } from './history-log-service.js';
import { FileItem, FileStore, Pipeline, RunnableCollection } from '@certd/pipeline';
import { Config, Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core";
import { InjectEntityModel } from "@midwayjs/typeorm";
import { In, MoreThan, Repository } from "typeorm";
import { BaseService, PageReq } from "@certd/lib-server";
import { HistoryEntity } from "../entity/history.js";
import { PipelineEntity } from "../entity/pipeline.js";
import { HistoryDetail } from "../entity/vo/history-detail.js";
import { HistoryLogService } from "./history-log-service.js";
import { FileItem, FileStore, Pipeline, RunnableCollection } from "@certd/pipeline";
import dayjs from 'dayjs';
import { DbAdapter } from '../../db/index.js';
import { logger } from '@certd/basic';
import dayjs from "dayjs";
import { DbAdapter } from "../../db/index.js";
import { logger } from "@certd/basic";
/**
* 证书申请
@@ -29,7 +29,7 @@ export class HistoryService extends BaseService<HistoryEntity> {
@Inject()
dbAdapter: DbAdapter;
@Config('certd')
@Config("certd")
private certdConfig: any;
//@ts-ignore
@@ -60,12 +60,12 @@ export class HistoryService extends BaseService<HistoryEntity> {
return new HistoryDetail(entity, log);
}
async start(pipeline: PipelineEntity,triggerType:string) {
async start(pipeline: PipelineEntity, triggerType: string) {
const bean = {
userId: pipeline.userId,
pipelineId: pipeline.id,
title: pipeline.title,
status: 'start',
status: "start",
triggerType,
projectId: pipeline.projectId,
};
@@ -104,7 +104,7 @@ export class HistoryService extends BaseService<HistoryEntity> {
pipelineId,
},
order: {
id: 'ASC',
id: "ASC",
},
skip: 0,
take: deleteCountBatch,
@@ -130,7 +130,7 @@ export class HistoryService extends BaseService<HistoryEntity> {
pipelineId,
},
order: {
id: 'DESC',
id: "DESC",
},
});
}
@@ -139,7 +139,7 @@ export class HistoryService extends BaseService<HistoryEntity> {
const status: Pipeline = JSON.parse(history.pipeline);
const files: FileItem[] = [];
RunnableCollection.each([status], runnable => {
if (runnable.runnableType !== 'step') {
if (runnable.runnableType !== "step") {
return;
}
if (runnable.status?.files != null) {
@@ -174,32 +174,32 @@ export class HistoryService extends BaseService<HistoryEntity> {
try {
const fileStore = new FileStore({
rootDir: this.certdConfig.fileRootDir,
scope: id + '',
parent: '0',
scope: id + "",
parent: "0",
});
fileStore.deleteByParent(id + '', '');
fileStore.deleteByParent(id + "", "");
} catch (e) {
logger.error('删除文件失败', e);
logger.error("删除文件失败", e);
}
}
async countPerDay(param: { days: number; userId?: any,projectId?:number }) {
const todayEnd = dayjs().endOf('day');
async countPerDay(param: { days: number; userId?: any; projectId?: number }) {
const todayEnd = dayjs().endOf("day");
const where: any = {
createTime: MoreThan(todayEnd.add(-param.days, 'day').toDate()),
createTime: MoreThan(todayEnd.add(-param.days, "day").toDate()),
};
if (param.projectId > 0) {
where.projectId = param.projectId;
}else if (param.userId > 0) {
} else if (param.userId > 0) {
where.userId = param.userId;
}
const result = await this.getRepository()
.createQueryBuilder('main')
.select(`${this.dbAdapter.date('main.createTime')} AS date`) // 将UNIX时间戳转换为日期
.addSelect('COUNT(1) AS count')
.createQueryBuilder("main")
.select(`${this.dbAdapter.date("main.createTime")} AS date`) // 将UNIX时间戳转换为日期
.addSelect("COUNT(1) AS count")
.where(where)
.groupBy('date')
.groupBy("date")
.getRawMany();
return result;
@@ -1,19 +1,12 @@
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
import {
BaseService,
NeedVIPException,
SysInstallInfo,
SysSettingsService,
SysSiteInfo,
ValidateException
} from "@certd/lib-server";
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { NotificationEntity } from '../entity/notification.js';
import { NotificationInstanceConfig, notificationRegistry, NotificationSendReq, sendNotification } from '@certd/pipeline';
import { http, utils } from '@certd/basic';
import { EmailService } from '../../basic/service/email-service.js';
import { isComm, isPlus } from '@certd/plus-core';
import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core";
import { BaseService, NeedVIPException, SysInstallInfo, SysSettingsService, SysSiteInfo, ValidateException } from "@certd/lib-server";
import { InjectEntityModel } from "@midwayjs/typeorm";
import { Repository } from "typeorm";
import { NotificationEntity } from "../entity/notification.js";
import { NotificationInstanceConfig, notificationRegistry, NotificationSendReq, sendNotification } from "@certd/pipeline";
import { http, utils } from "@certd/basic";
import { EmailService } from "../../basic/service/email-service.js";
import { isComm, isPlus } from "@certd/plus-core";
@Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true })
@@ -35,7 +28,7 @@ export class NotificationService extends BaseService<NotificationEntity> {
async getSimpleInfo(id: number) {
const entity = await this.info(id);
if (entity == null) {
throw new ValidateException('该通知配置不存在,请确认是否已被删除');
throw new ValidateException("该通知配置不存在,请确认是否已被删除");
}
return {
id: entity.id,
@@ -56,32 +49,31 @@ export class NotificationService extends BaseService<NotificationEntity> {
async add(bean: NotificationEntity) {
this.checkNeedPlus(bean.type);
const res = await super.add(bean);
if(bean.isDefault){
if (bean.isDefault) {
await this.setDefault(res.id, bean.userId);
}
bean.keyId = "nt_" + utils.id.simpleNanoId();
return res
return res;
}
async update(bean: NotificationEntity) {
const old = await this.info(bean.id);
this.checkNeedPlus(old.type);
delete bean.userId;
delete bean.type
delete bean.keyId
delete bean.type;
delete bean.keyId;
const res = await super.update(bean);
if(bean.isDefault){
if (bean.isDefault) {
await this.setDefault(bean.id, old.userId);
}
return res
return res;
}
checkNeedPlus(type: string){
const define = this.getDefineByType(type)
//@ts-ignore
checkNeedPlus(type: string) {
const define = this.getDefineByType(type);
//@ts-ignore
if (define.needPlus && !isPlus()) {
throw new NeedVIPException("此通知类型为Certd专业版功能,请升级到专业版或以上级别");
}
@@ -89,10 +81,10 @@ export class NotificationService extends BaseService<NotificationEntity> {
async getById(id: number, userId: number, projectId?: number): Promise<NotificationInstanceConfig> {
if (!id) {
throw new ValidateException('id不能为空');
throw new ValidateException("id不能为空");
}
if (userId==null) {
throw new ValidateException('userId不能为空');
if (userId == null) {
throw new ValidateException("userId不能为空");
}
const res = await this.repository.findOne({
where: {
@@ -125,7 +117,7 @@ export class NotificationService extends BaseService<NotificationEntity> {
projectId,
},
order: {
isDefault: 'DESC',
isDefault: "DESC",
},
});
if (!res) {
@@ -136,30 +128,24 @@ export class NotificationService extends BaseService<NotificationEntity> {
async setDefault(id: number, userId: number, projectId?: number) {
if (!id) {
throw new ValidateException('id不能为空');
throw new ValidateException("id不能为空");
}
if (userId==null) {
throw new ValidateException('userId不能为空');
if (userId == null) {
throw new ValidateException("userId不能为空");
}
const query:any = {
userId,
const query: any = {
userId,
};
if (projectId) {
query.projectId = projectId;
}
if (projectId){
query.projectId = projectId
}
await this.repository.update(
query,
{
isDefault: false,
}
);
query.id = id
await this.repository.update(
query,
{
isDefault: true,
}
);
await this.repository.update(query, {
isDefault: false,
});
query.id = id;
await this.repository.update(query, {
isDefault: true,
});
}
async getOrCreateDefault(email: string, userId: any, projectId?: number) {
@@ -172,8 +158,8 @@ export class NotificationService extends BaseService<NotificationEntity> {
};
const res = await this.repository.save({
userId,
type: 'email',
name: '邮件通知',
type: "email",
name: "邮件通知",
setting: JSON.stringify(setting),
isDefault: true,
projectId,
@@ -199,11 +185,11 @@ export class NotificationService extends BaseService<NotificationEntity> {
if (notifyConfig) {
//发送通知
logger.info('发送通知, 使用通知渠道:' + notifyConfig.name);
logger.info("发送通知, 使用通知渠道:" + notifyConfig.name);
if (notifyConfig.type != 'email') {
if (notifyConfig.type != "email") {
//非邮件通知,需要加上站点名称
let siteTitle = 'Certd';
let siteTitle = "Certd";
if (isComm()) {
const siteInfo = await this.sysSettingsService.getSetting<SysSiteInfo>(SysSiteInfo);
siteTitle = siteInfo?.title || siteTitle;
@@ -223,7 +209,7 @@ export class NotificationService extends BaseService<NotificationEntity> {
});
} else {
if (req.useEmail && req.emailAddress) {
logger.info('使用邮件通知');
logger.info("使用邮件通知");
await this.emailService.send({
receivers: [req.emailAddress],
subject: req.body.title,
@@ -235,7 +221,7 @@ export class NotificationService extends BaseService<NotificationEntity> {
async getBindUrl(path: string) {
const installInfo = await this.sysSettingsService.getSetting<SysInstallInfo>(SysInstallInfo);
const bindUrl = installInfo.bindUrl || 'http://127.0.0.1:7001';
const bindUrl = installInfo.bindUrl || "http://127.0.0.1:7001";
return bindUrl + path;
}
}
@@ -115,7 +115,10 @@ describe("pipeline batch update", () => {
},
};
assert.equal(updateCertApplyStepInputs(pipeline, {}, stepType => inputDefines[stepType]), 0);
assert.equal(
updateCertApplyStepInputs(pipeline, {}, stepType => inputDefines[stepType]),
0
);
assert.equal(
updateCertApplyStepInputs(
pipeline,
@@ -1,9 +1,9 @@
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { BaseService } from '@certd/lib-server';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { PipelineGroupEntity } from '../entity/pipeline-group.js';
import { merge } from 'lodash-es';
import { Provide, Scope, ScopeEnum } from "@midwayjs/core";
import { BaseService } from "@certd/lib-server";
import { InjectEntityModel } from "@midwayjs/typeorm";
import { Repository } from "typeorm";
import { PipelineGroupEntity } from "../entity/pipeline-group.js";
import { merge } from "lodash-es";
@Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true })
@@ -1,32 +1,10 @@
import { Config, Inject, Provide, Scope, ScopeEnum, sleep } from "@midwayjs/core";
import { InjectEntityModel } from "@midwayjs/typeorm";
import { In, MoreThan, Repository } from "typeorm";
import {
AccessService,
BaseService,
isEnterprise,
NeedSuiteException,
NeedVIPException,
PageReq,
SysPublicSettings,
SysSettingsService,
SysSiteInfo
} from "@certd/lib-server";
import { AccessService, BaseService, isEnterprise, NeedSuiteException, NeedVIPException, PageReq, SysPublicSettings, SysSettingsService, SysSiteInfo } from "@certd/lib-server";
import { PipelineEntity } from "../entity/pipeline.js";
import { PipelineDetail } from "../entity/vo/pipeline-detail.js";
import {
Executor,
IAccessService,
ICnameProxyService,
INotificationService, Notification,
Pipeline,
pluginRegistry,
ResultType,
RunHistory,
RunnableCollection,
SysInfo,
UserInfo
} from "@certd/pipeline";
import { Executor, IAccessService, ICnameProxyService, INotificationService, Notification, Pipeline, pluginRegistry, ResultType, RunHistory, RunnableCollection, SysInfo, UserInfo } from "@certd/pipeline";
import { DbStorage } from "./db-storage.js";
import { StorageService } from "./storage-service.js";
import { Cron } from "../../cron/cron.js";
@@ -56,7 +34,6 @@ import { CertApplyStepInputPatch, updateCertApplyStepInputs } from "./pipeline-b
import { calcNextSuiteCountUsed } from "./pipeline-suite-limit.js";
const runningTasks: Map<string | number, Executor> = new Map();
/**
* 证书申请
*/
@@ -154,9 +131,9 @@ export class PipelineService extends BaseService<PipelineEntity> {
//获取下次执行时间
if (pipeline.triggers?.length > 0) {
const triggers = pipeline.triggers.filter((item) => item.type === 'timer');
const triggers = pipeline.triggers.filter(item => item.type === "timer");
if (triggers && triggers.length > 0) {
let nextTimes: any = [];
const nextTimes: any = [];
for (const item of triggers) {
if (!item.props?.cron) {
continue;
@@ -164,9 +141,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
const ret = this.getCronNextTimes(item.props?.cron, 1);
nextTimes.push(...ret);
}
item.nextRunTime = nextTimes[0]
item.nextRunTime = nextTimes[0];
}
}
delete item.content;
@@ -175,7 +151,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
return result;
}
getCronNextTimes(cron: string, count: number = 1) {
getCronNextTimes(cron: string, count = 1) {
if (cron == null) {
return [];
}
@@ -188,7 +164,6 @@ export class PipelineService extends BaseService<PipelineEntity> {
return nextTimes;
}
private async fillLastVars(records: PipelineEntity[]) {
const pipelineIds: number[] = [];
const recordMap = {};
@@ -235,8 +210,6 @@ export class PipelineService extends BaseService<PipelineEntity> {
}
}
/**
* 获取详情
* @param id
@@ -270,7 +243,6 @@ export class PipelineService extends BaseService<PipelineEntity> {
const isUpdate = bean.id > 0 && old != null;
const pipeline = JSON.parse(bean.content || "{}");
RunnableCollection.initPipelineRunnableType(pipeline);
pipeline.userId = bean.userId;
@@ -334,12 +306,12 @@ export class PipelineService extends BaseService<PipelineEntity> {
}
pipeline.version++;
bean.triggerCount = pipeline.triggers?.filter((trigger) => trigger.type === "timer").length || 0;
bean.triggerCount = pipeline.triggers?.filter(trigger => trigger.type === "timer").length || 0;
bean.content = JSON.stringify(pipeline);
await this.addOrUpdate(bean);
await this.registerTrigger(bean);
return bean
return bean;
}
private async checkMaxPipelineCount(bean: PipelineEntity, pipeline: Pipeline, domains: string[], old?: PipelineEntity) {
@@ -351,7 +323,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
// }
if (isEnterprise()) {
//企业模式不限制
checkPlus()
checkPlus();
return;
}
@@ -397,18 +369,17 @@ export class PipelineService extends BaseService<PipelineEntity> {
}
}
}
}
async foreachPipeline(callback: (pipeline: PipelineEntity) => void) {
const idEntityList = await this.repository.find({
select: {
id: true
id: true,
},
where: {
disabled: false,
isTemplate: false
}
isTemplate: false,
},
});
const ids = idEntityList.map(item => {
return item.id;
@@ -428,7 +399,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
//分段加载记录
for (const idArr of idsSpan) {
const list = await this.repository.findBy({
id: In(idArr)
id: In(idArr),
});
for (const entity of list) {
@@ -478,12 +449,9 @@ export class PipelineService extends BaseService<PipelineEntity> {
} catch (e) {
logger.error(e);
}
}
}
async trigger(id: any, stepId?: string, doCheck = false) {
const entity: PipelineEntity = await this.info(id);
if (doCheck) {
@@ -499,7 +467,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
} catch (e) {
logger.error("手动job执行失败:", e);
}
}
},
});
}
@@ -511,7 +479,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
logger.error(e.message);
await this.update({
id: pipelineId,
status: "no_deploy_count"
status: "no_deploy_count",
});
}
throw e;
@@ -595,22 +563,21 @@ export class PipelineService extends BaseService<PipelineEntity> {
} catch (e) {
logger.error("定时job执行失败:", e);
}
}
},
});
}
},
});
logger.info("当前定时器数量:", this.cron.getTaskSize());
}
async isPipelineValidTimeEnabled(entity: PipelineEntity) {
const settings = await this.sysSettingsService.getPublicSettings();
if (isPlus() && settings.pipelineValidTimeEnabled) {
if (entity.validTime > 0 && entity.validTime < Date.now()) {
return false
return false;
}
}
return true
return true;
}
/**
@@ -629,13 +596,12 @@ export class PipelineService extends BaseService<PipelineEntity> {
}
async beforeCheck(entity: PipelineEntity) {
if (isEnterprise()) {
checkPlus()
return {}
checkPlus();
return {};
}
const validTimeEnabled = await this.isPipelineValidTimeEnabled(entity)
const validTimeEnabled = await this.isPipelineValidTimeEnabled(entity);
if (!validTimeEnabled) {
throw new Error(`流水线${entity.id}已过期,不予执行`);
}
@@ -647,16 +613,15 @@ export class PipelineService extends BaseService<PipelineEntity> {
await this.checkUserStatus(entity.userId);
return {
suite
}
suite,
};
}
async doRun(entity: PipelineEntity, triggerId: string, stepId?: string) {
let suite: any = null
let suite: any = null;
try {
const res = await this.beforeCheck(entity);
suite = res.suite
suite = res.suite;
} catch (e) {
logger.error(`流水线${entity.id}触发失败(${triggerId}):${e.message}`);
return;
@@ -668,7 +633,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
pipeline.id = id;
}
if(entity.userId !=null){
if (entity.userId != null) {
pipeline.userId = entity.userId;
pipeline.projectId = entity.projectId;
}
@@ -688,7 +653,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
return;
}
}
const doSaveHistory = async (history: RunHistory) => {
//保存执行历史
try {
@@ -707,8 +672,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
class HistorySaver {
latest: RunHistory = null;
interval: any = null;
started: boolean = false;
async save(){
started = false;
async save() {
const latest = this.latest;
this.latest = null;
if (latest == null) {
@@ -716,43 +681,43 @@ export class PipelineService extends BaseService<PipelineEntity> {
}
await doSaveHistory(latest);
}
async start(){
this.started = true
async start() {
this.started = true;
//先存一次,确保有数据
await this.save();
setTimeout(()=>{
setTimeout(() => {
//2秒后保存一次,尽快显示第一个任务的状态
this.save();
this.save();
}, 1000 * 2);
this.interval = setInterval(()=>{
this.interval = setInterval(() => {
//之后每5秒保存一次
this.save();
}, 1000 * 5);
}
async push(history: RunHistory){
async push(history: RunHistory) {
this.latest = history;
if(!this.started){
await this.start();
if (!this.started) {
await this.start();
}
}
async done(){
async done() {
clearInterval(this.interval);
await this.save();
}
}
const historySaver = new HistorySaver();
const onChanged = async (history: RunHistory)=>{
const onChanged = async (history: RunHistory) => {
await historySaver.push(history);
}
const onFinished = async (history: RunHistory)=>{
};
const onFinished = async (history: RunHistory) => {
await onChanged(history);
await historySaver.done();
}
};
const userId = entity.userId;
const projectId = entity.projectId;
let userIsAdmin = false
let userIsAdmin = false;
if (projectId && projectId > 0) {
userIsAdmin = await this.projectService.isAdmin(projectId);
@@ -761,7 +726,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
}
const user: UserInfo = {
id: userId,
role: userIsAdmin ? "admin" : "user"
role: userIsAdmin ? "admin" : "user",
};
const historyId = await this.historyService.start(entity, triggerType);
@@ -773,7 +738,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
const taskServiceGetter = this.taskServiceBuilder.create({
userId,
projectId
projectId,
});
const accessGetter = await taskServiceGetter.get<IAccessService>("accessService");
const notificationGetter = await taskServiceGetter.get<INotificationService>("notificationService");
@@ -792,7 +757,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
notificationService: notificationGetter,
fileRootDir: this.certdConfig.fileRootDir,
sysInfo,
serviceGetter: taskServiceGetter
serviceGetter: taskServiceGetter,
});
try {
runningTasks.set(historyId, executor);
@@ -875,13 +840,13 @@ export class PipelineService extends BaseService<PipelineEntity> {
},
});
if (!pipelineEntity) {
return null
return null;
}
return pipelineEntity.projectId;
}
private async saveHistory(history: RunHistory) {
//修改pipeline状态
let pipelineEntity = new PipelineEntity();
const pipelineEntity = new PipelineEntity();
pipelineEntity.id = parseInt(history.pipeline.id);
pipelineEntity.status = history.pipeline.status.result + "";
pipelineEntity.lastHistoryTime = history.pipeline.status.startTime;
@@ -909,18 +874,18 @@ export class PipelineService extends BaseService<PipelineEntity> {
await this.historyLogService.addOrUpdate(logEntity);
}
async count(param: { userId?: any, projectId?: number }) {
async count(param: { userId?: any; projectId?: number }) {
const count = await this.repository.count({
where: {
userId: param.userId,
projectId: param.projectId,
isTemplate: false
}
isTemplate: false,
},
});
return count;
}
async statusCount(param: { userId?: any, projectId?: number } = {}) {
async statusCount(param: { userId?: any; projectId?: number } = {}) {
const statusCount = await this.repository
.createQueryBuilder()
.select("status")
@@ -928,14 +893,14 @@ export class PipelineService extends BaseService<PipelineEntity> {
.where({
userId: param.userId,
projectId: param.projectId,
isTemplate: false
isTemplate: false,
})
.groupBy("status")
.getRawMany();
return statusCount;
}
async enableCount(param: { userId?: any, projectId?: number } = {}) {
async enableCount(param: { userId?: any; projectId?: number } = {}) {
const statusCount = await this.repository
.createQueryBuilder()
.select("disabled")
@@ -943,7 +908,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
.where({
userId: param.userId,
projectId: param.projectId,
isTemplate: false
isTemplate: false,
})
.groupBy("disabled")
.getRawMany();
@@ -962,14 +927,14 @@ export class PipelineService extends BaseService<PipelineEntity> {
select: {
id: true,
title: true,
status: true
status: true,
},
where: {
userId,
disabled: false,
projectId,
isTemplate: false
}
isTemplate: false,
},
});
await this.fillLastVars(list);
list = list.filter(item => {
@@ -991,7 +956,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
.where({
// 0点
createTime: MoreThan(todayEnd.add(-param.days, "day").toDate()),
isTemplate: false
isTemplate: false,
})
.groupBy("date")
.getRawMany();
@@ -1008,7 +973,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
await this.checkUserId(id, userId);
}
if (projectId) {
await this.checkUserId(id, projectId, "projectId")
await this.checkUserId(id, projectId, "projectId");
}
await this.delete(id);
}
@@ -1018,7 +983,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
if (!isPlus()) {
throw new NeedVIPException("此功能需要升级Certd专业版");
}
const query: any = {}
const query: any = {};
if (userId && userId > 0) {
query.userId = userId;
}
@@ -1028,15 +993,12 @@ export class PipelineService extends BaseService<PipelineEntity> {
await this.repository.update(
{
id: In(ids),
...query
...query,
},
{ groupId }
);
}
/**
* 批量转移到其他项目
*/
@@ -1050,7 +1012,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
if (!projectId || projectId <= 0) {
throw new Error("projectId不能为空");
}
const userId = -1 // 强制为-1
const userId = -1; // 强制为-1
async function eachSteps(pipeline, callback) {
for (const stage of pipeline.stages) {
@@ -1062,7 +1024,6 @@ export class PipelineService extends BaseService<PipelineEntity> {
}
}
for (const id of ids) {
const pipelineEntity = await this.info(id);
if (!pipelineEntity) {
@@ -1080,16 +1041,16 @@ export class PipelineService extends BaseService<PipelineEntity> {
userId: userId,
projectId: projectId,
groupId: null,
}
};
const pipeline = JSON.parse(pipelineEntity.content);
pipeline.userId = userId;
pipeline.projectId = projectId;
//转移和修改access 和 Notification
await eachSteps(pipeline, async (step) => {
await eachSteps(pipeline, async step => {
const type = step.type;
//plugin
//plugin
const pluginDefine: any = pluginRegistry.getDefine(type);
if (pluginDefine) {
for (const key in step.input) {
@@ -1097,48 +1058,40 @@ export class PipelineService extends BaseService<PipelineEntity> {
if (!value || value <= 0) {
continue;
}
if (!pluginDefine.input[key]){
if (!pluginDefine.input[key]) {
continue;
}
const componentName = pluginDefine.input[key].component?.name;
if (componentName === "access-selector" || componentName === "AccessSelector") {
//这是一个授权ID属性,检查是否需要转移授权
const newAccessId = await this.accessService.copyTo(value,projectId);
const newAccessId = await this.accessService.copyTo(value, projectId);
step.input[key] = newAccessId;
}
}
}
})
pipeline.notifications = [
});
(pipeline.notifications = [
{
"type": "custom",
"when": [
"error",
"turnToSuccess"
],
"notificationId": 0,
"title": "使用默认通知",
"id": nanoid()
}
],
entity.content = JSON.stringify(pipeline);
type: "custom",
when: ["error", "turnToSuccess"],
notificationId: 0,
title: "使用默认通知",
id: nanoid(),
},
]),
(entity.content = JSON.stringify(pipeline));
await this.unregisterTriggers(entity.id);
await this.repository.save(entity);
await this.save(entity)
await this.save(entity);
}
}
async batchUpdateTrigger(ids: number[], trigger: any, userId: any, projectId?: number) {
if (!isPlus()) {
throw new NeedVIPException("此功能需要升级Certd专业版");
}
//允许管理员修改,userId=null
const query: any = {}
const query: any = {};
if (userId && userId > 0) {
query.userId = userId;
}
@@ -1148,15 +1101,15 @@ export class PipelineService extends BaseService<PipelineEntity> {
const list = await this.find({
where: {
id: In(ids),
...query
}
...query,
},
});
for (const item of list) {
const pipeline = JSON.parse(item.content);
if (trigger.props === false) {
//清除trigger
pipeline.triggers = []
pipeline.triggers = [];
} else {
if (trigger.random === true) {
//随机时间
@@ -1170,20 +1123,21 @@ export class PipelineService extends BaseService<PipelineEntity> {
const endTime = dayjs(end).valueOf();
const randomTime = Math.floor(Math.random() * (endTime - startTime)) + startTime;
const time = dayjs(randomTime).format(" ss:mm:HH").replaceAll(":", " ").replaceAll(" 0", " ").trim();
set(trigger, "props.cron", `${time} * * *`)
set(trigger, "props.cron", `${time} * * *`);
}
delete trigger.random
delete trigger.random;
delete trigger.randomRange;
pipeline.triggers = [{
id: nanoid(),
title: "定时触发",
...trigger
}];
pipeline.triggers = [
{
id: nanoid(),
title: "定时触发",
...trigger,
},
];
}
await this.doUpdatePipelineJson(item, pipeline);
}
}
async batchUpdateNotifications(ids: number[], notification: Notification, userId: any, projectId?: number) {
@@ -1191,7 +1145,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
throw new NeedVIPException("此功能需要升级Certd专业版");
}
//允许管理员修改,userId=null
const query: any = {}
const query: any = {};
if (userId && userId > 0) {
query.userId = userId;
}
@@ -1201,26 +1155,28 @@ export class PipelineService extends BaseService<PipelineEntity> {
const list = await this.find({
where: {
id: In(ids),
...query
}
...query,
},
});
for (const item of list) {
const pipeline = JSON.parse(item.content);
pipeline.notifications = [{
id: nanoid(),
title: "通知",
/**
* type: NotificationType;
* when: NotificationWhen[];
* options: EmailOptions;
* notificationId: number;
* title: string;
* subType: string;
*/
type: "other",
...notification
}];
pipeline.notifications = [
{
id: nanoid(),
title: "通知",
/**
* type: NotificationType;
* when: NotificationWhen[];
* options: EmailOptions;
* notificationId: number;
* title: string;
* subType: string;
*/
type: "other",
...notification,
},
];
await this.doUpdatePipelineJson(item, pipeline);
}
}
@@ -1229,7 +1185,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
if (!isPlus()) {
throw new NeedVIPException("此功能需要升级Certd专业版");
}
const query: any = {}
const query: any = {};
if (userId && userId > 0) {
query.userId = userId;
}
@@ -1239,8 +1195,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
const list = await this.find({
where: {
id: In(ids),
...query
}
...query,
},
});
for (const item of list) {
@@ -1267,15 +1223,15 @@ export class PipelineService extends BaseService<PipelineEntity> {
const where: any = {
id: In(ids),
userId,
}
};
if (projectId) {
where.projectId = projectId
where.projectId = projectId;
}
const list = await this.repository.find({
select: {
id: true
id: true,
},
where: where
where: where,
});
ids = list.map(item => item.id);
@@ -1293,12 +1249,11 @@ export class PipelineService extends BaseService<PipelineEntity> {
} else {
await this.run(id, null);
}
}
},
});
}
}
async getUserPipelineCount(userId) {
return await this.repository.count({ where: { userId } });
}
@@ -1307,21 +1262,20 @@ export class PipelineService extends BaseService<PipelineEntity> {
return await this.repository.find({
select: {
id: true,
title: true
title: true,
},
where: {
id: In(pipelineIds),
userId,
projectId
}
projectId,
},
});
}
private async checkUserStatus(userId: number) {
if (isEnterprise()) {
//企业模式不检查用户状态,都允许运行流水线
return
return;
}
const userEntity = await this.userService.info(userId);
if (userEntity == null) {
@@ -1344,12 +1298,12 @@ export class PipelineService extends BaseService<PipelineEntity> {
}
}
async createAutoPipeline(req: { domains: string[]; email: string; userId: number, projectId?: number, from: string }) {
async createAutoPipeline(req: { domains: string[]; email: string; userId: number; projectId?: number; from: string }) {
const randomHour = Math.floor(Math.random() * 6);
const randomMin = Math.floor(Math.random() * 60);
const randomCron = `0 ${randomMin} ${randomHour} * * *`;
let pipeline: any = {
const pipeline: any = {
title: req.domains[0] + `证书自动申请【${req.from ?? "OpenAPI"}`,
runnableType: "pipeline",
triggers: [
@@ -1359,8 +1313,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
props: {
cron: randomCron,
},
type: "timer"
}
type: "timer",
},
],
notifications: [
{
@@ -1369,7 +1323,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
when: ["error", "turnToSuccess", "success"],
notificationId: 0,
title: "默认通知",
}
},
],
stages: [
{
@@ -1391,28 +1345,28 @@ export class PipelineService extends BaseService<PipelineEntity> {
renewDays: 20,
domains: req.domains,
email: req.email,
"challengeType": "auto",
"sslProvider": "letsencrypt",
"privateKeyType": "rsa_2048",
"certProfile": "classic",
"preferredChain": "ISRG Root X1",
"useProxy": false,
"skipLocalVerify": false,
"maxCheckRetryCount": 20,
"waitDnsDiffuseTime": 30,
"pfxArgs": "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES",
"successNotify": true
challengeType: "auto",
sslProvider: "letsencrypt",
privateKeyType: "rsa_2048",
certProfile: "classic",
preferredChain: "ISRG Root X1",
useProxy: false,
skipLocalVerify: false,
maxCheckRetryCount: 20,
waitDnsDiffuseTime: 30,
pfxArgs: "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES",
successNotify: true,
},
strategy: {
runStrategy: 0 // 正常执行
runStrategy: 0, // 正常执行
},
type: "CertApply"
}
]
}
]
}
]
type: "CertApply",
},
],
},
],
},
],
};
const bean = new PipelineEntity();
@@ -1421,11 +1375,10 @@ export class PipelineService extends BaseService<PipelineEntity> {
bean.userId = req.userId;
bean.status = "none";
bean.type = "cert_auto";
bean.disabled = false
bean.keepHistoryCount = 30
bean.projectId = req.projectId
await this.save(bean)
bean.disabled = false;
bean.keepHistoryCount = 30;
bean.projectId = req.projectId;
await this.save(bean);
return bean;
}
@@ -1433,11 +1386,11 @@ export class PipelineService extends BaseService<PipelineEntity> {
async getStatus(pipelineId: number) {
const res = await this.repository.findOne({
select: {
status: true
status: true,
},
where: {
id: pipelineId
}
id: pipelineId,
},
});
return res?.status;
}
@@ -1445,11 +1398,11 @@ export class PipelineService extends BaseService<PipelineEntity> {
async getPipelineUserId(pipelineId: number) {
const res = await this.repository.findOne({
select: {
userId: true
userId: true,
},
where: {
id: pipelineId
}
id: pipelineId,
},
});
return res?.userId;
}
@@ -1474,9 +1427,9 @@ export class PipelineService extends BaseService<PipelineEntity> {
content: true,
},
where: {
webhookKey
}
})
webhookKey,
},
});
if (!pipelineEntity) {
throw new Error("webhookKey不存在");
}
@@ -1,8 +1,8 @@
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { In, Repository } from 'typeorm';
import { BaseService } from '@certd/lib-server';
import { StorageEntity } from '../entity/storage.js';
import { Provide, Scope, ScopeEnum } from "@midwayjs/core";
import { InjectEntityModel } from "@midwayjs/typeorm";
import { In, Repository } from "typeorm";
import { BaseService } from "@certd/lib-server";
import { StorageEntity } from "../entity/storage.js";
/**
*/
@@ -19,7 +19,7 @@ export class StorageService extends BaseService<StorageEntity> {
async get(where: { scope: any; namespace: any; userId: number; version: string; key: string }) {
if (where.userId == null) {
throw new Error('userId 不能为空');
throw new Error("userId 不能为空");
}
return await this.repository.findOne({
where,
@@ -34,7 +34,7 @@ export class StorageService extends BaseService<StorageEntity> {
if (ret != null) {
entity.id = ret.id;
if (ret.userId !== entity.userId) {
throw new Error('您没有权限修改此数据');
throw new Error("您没有权限修改此数据");
}
await this.repository.save(entity);
} else {
@@ -49,9 +49,9 @@ export class StorageService extends BaseService<StorageEntity> {
}
return await this.repository.find({
where: {
scope: 'pipeline',
scope: "pipeline",
namespace: In(pipelineIds),
key: 'vars',
key: "vars",
},
});
}
@@ -62,9 +62,9 @@ export class StorageService extends BaseService<StorageEntity> {
}
const res = await this.repository.findOne({
where: {
scope: 'pipeline',
namespace: pipelineId + '',
key: 'privateVars',
scope: "pipeline",
namespace: pipelineId + "",
key: "privateVars",
},
});
if (!res) {
@@ -1,9 +1,9 @@
import {Inject, Provide, Scope, ScopeEnum} from '@midwayjs/core';
import {BaseService, SysSettingsService} from '@certd/lib-server';
import {InjectEntityModel} from '@midwayjs/typeorm';
import {Repository} from 'typeorm';
import {SubDomainEntity} from '../entity/sub-domain.js';
import {EmailService} from '../../basic/service/email-service.js';
import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core";
import { BaseService, SysSettingsService } from "@certd/lib-server";
import { InjectEntityModel } from "@midwayjs/typeorm";
import { Repository } from "typeorm";
import { SubDomainEntity } from "../entity/sub-domain.js";
import { EmailService } from "../../basic/service/email-service.js";
@Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true })
@@ -22,8 +22,8 @@ export class SubDomainService extends BaseService<SubDomainEntity> {
return this.repository;
}
async getListByUserId(userId:number, projectId?: number):Promise<string[]>{
if (userId==null) {
async getListByUserId(userId: number, projectId?: number): Promise<string[]> {
if (userId == null) {
return [];
}
const list = await this.find({
@@ -34,16 +34,16 @@ export class SubDomainService extends BaseService<SubDomainEntity> {
},
});
return list.map(item=>item.domain);
return list.map(item => item.domain);
}
async add(bean: SubDomainEntity) {
const {domain, userId, projectId} = bean;
const { domain, userId, projectId } = bean;
if (!domain) {
throw new Error('域名不能为空');
throw new Error("域名不能为空");
}
if (userId==null) {
throw new Error('用户ID不能为空');
if (userId == null) {
throw new Error("用户ID不能为空");
}
const exist = await this.repository.findOne({
where: {
@@ -52,10 +52,9 @@ export class SubDomainService extends BaseService<SubDomainEntity> {
projectId,
},
});
if (exist) {
throw new Error('域名已存在');
}
return await super.add(bean)
if (exist) {
throw new Error("域名已存在");
}
return await super.add(bean);
}
}
@@ -1,15 +1,15 @@
import {Inject, Provide, Scope, ScopeEnum} from '@midwayjs/core';
import {BaseService, SysSettingsService} from '@certd/lib-server';
import {InjectEntityModel} from '@midwayjs/typeorm';
import {In, Repository} from 'typeorm';
import {TemplateEntity} from '../entity/template.js';
import {PipelineService} from './pipeline-service.js';
import {cloneDeep} from "lodash-es";
import {PipelineEntity} from "../entity/pipeline.js";
import {Pipeline} from "@certd/pipeline";
import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core";
import { BaseService, SysSettingsService } from "@certd/lib-server";
import { InjectEntityModel } from "@midwayjs/typeorm";
import { In, Repository } from "typeorm";
import { TemplateEntity } from "../entity/template.js";
import { PipelineService } from "./pipeline-service.js";
import { cloneDeep } from "lodash-es";
import { PipelineEntity } from "../entity/pipeline.js";
import { Pipeline } from "@certd/pipeline";
@Provide()
@Scope(ScopeEnum.Request, {allowDowngrade: true})
@Scope(ScopeEnum.Request, { allowDowngrade: true })
export class TemplateService extends BaseService<TemplateEntity> {
@InjectEntityModel(TemplateEntity)
repository: Repository<TemplateEntity>;
@@ -31,82 +31,77 @@ export class TemplateService extends BaseService<TemplateEntity> {
const pipelineEntity = await this.pipelineService.info(pipelineId);
if (!pipelineEntity) {
throw new Error('pipeline not found');
throw new Error("pipeline not found");
}
if (pipelineEntity.userId !== param.userId) {
throw new Error('permission denied');
throw new Error("permission denied");
}
let template = null
let template = null;
await this.transaction(async (tx: any) => {
template = await tx.getRepository(TemplateEntity).save(param);
let newPipeline = cloneDeep(pipelineEntity)
let newPipeline = cloneDeep(pipelineEntity);
//创建pipeline模版
newPipeline.id = undefined;
newPipeline.title = template.title + "模版流水线"
newPipeline.templateId = template.id
newPipeline.isTemplate = true
newPipeline.userId = template.userId
newPipeline.title = template.title + "模版流水线";
newPipeline.templateId = template.id;
newPipeline.isTemplate = true;
newPipeline.userId = template.userId;
const pipelineJson: Pipeline = JSON.parse(newPipeline.content)
delete pipelineJson.triggers
pipelineJson.userId = template.userId
pipelineJson.title = newPipeline.title
newPipeline.content = JSON.stringify(pipelineJson)
newPipeline = await tx.getRepository(PipelineEntity).save(newPipeline)
const pipelineJson: Pipeline = JSON.parse(newPipeline.content);
delete pipelineJson.triggers;
pipelineJson.userId = template.userId;
pipelineJson.title = newPipeline.title;
newPipeline.content = JSON.stringify(pipelineJson);
newPipeline = await tx.getRepository(PipelineEntity).save(newPipeline);
const update: any = {}
update.id = template.id
update.pipelineId = newPipeline.id
await tx.getRepository(TemplateEntity).save(update)
})
return template
const update: any = {};
update.id = template.id;
update.pipelineId = newPipeline.id;
await tx.getRepository(TemplateEntity).save(update);
});
return template;
}
async detail(id: number, userId: number,projectId?:number) {
const info = await this.info(id)
async detail(id: number, userId: number, projectId?: number) {
const info = await this.info(id);
if (!info) {
throw new Error('模板不存在');
throw new Error("模板不存在");
}
if (info.userId !== userId) {
throw new Error('无权限');
throw new Error("无权限");
}
if (projectId && info.projectId !== projectId) {
throw new Error('无权限');
throw new Error("无权限");
}
let pipeline = null
let pipeline = null;
if (info.pipelineId) {
const pipelineEntity = await this.pipelineService.info(info.pipelineId);
pipeline = JSON.parse(pipelineEntity.content)
pipeline = JSON.parse(pipelineEntity.content);
}
return {
template: info,
pipeline,
}
};
}
async batchDelete(ids: number[], userId: number,projectId?:number) {
async batchDelete(ids: number[], userId: number, projectId?: number) {
const where: any = {
id: In(ids),
}
};
if (userId != null) {
where.userId = userId
where.userId = userId;
}
if (projectId) {
where.projectId = projectId
where.projectId = projectId;
}
const list = await this.getRepository().find({where})
ids = list.map(item => item.id)
const pipelineIds = list.map(item => item.pipelineId)
const list = await this.getRepository().find({ where });
ids = list.map(item => item.id);
const pipelineIds = list.map(item => item.pipelineId);
await this.delete(ids);
await this.pipelineService.batchDelete(pipelineIds, userId, projectId)
await this.pipelineService.batchDelete(pipelineIds, userId, projectId);
}
async createPipelineByTemplate(body: PipelineEntity) {
@@ -114,21 +109,20 @@ export class TemplateService extends BaseService<TemplateEntity> {
const template = await this.info(templateId);
if (!template && template.userId !== body.userId) {
throw new Error('模板不存在');
throw new Error("模板不存在");
}
const tempPipeline = await this.pipelineService.info(template.pipelineId)
const tempPipeline = await this.pipelineService.info(template.pipelineId);
const newPipeline = {
type: tempPipeline.type,
from : "template",
from: "template",
keepHistoryCount: tempPipeline.keepHistoryCount,
... body,
}
...body,
};
await this.pipelineService.save(newPipeline)
await this.pipelineService.save(newPipeline);
return newPipeline
return newPipeline;
}
}
@@ -1,6 +1,6 @@
import { IUrlService } from '@certd/pipeline';
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { SysInstallInfo, SysSettingsService } from '@certd/lib-server';
import { IUrlService } from "@certd/pipeline";
import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core";
import { SysInstallInfo, SysSettingsService } from "@certd/lib-server";
@Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true })
@@ -10,7 +10,7 @@ export class UrlService implements IUrlService {
async getPipelineDetailUrl(pipelineId: number, historyId: number): Promise<string> {
const installInfo = await this.sysSettingsService.getSetting<SysInstallInfo>(SysInstallInfo);
let baseUrl = 'http://127.0.0.1:7001';
let baseUrl = "http://127.0.0.1:7001";
if (installInfo.bindUrl) {
baseUrl = installInfo.bindUrl;
}