Merge branch 'refs/heads/v2-dev' into v2-dev-buy

# Conflicts:
#	docs/.vitepress/config.ts
#	packages/ui/certd-client/src/views/certd/pipeline/sub-domain/index.vue
This commit is contained in:
xiaojunnuo
2025-09-22 22:29:59 +08:00
175 changed files with 4551 additions and 684 deletions
+14
View File
@@ -3,6 +3,20 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.21](https://github.com/publishlab/node-acme-client/compare/v1.36.20...v1.36.21) (2025-09-15)
**Note:** Version bump only for package @certd/acme-client
## [1.36.20](https://github.com/publishlab/node-acme-client/compare/v1.36.19...v1.36.20) (2025-09-13)
**Note:** Version bump only for package @certd/acme-client
## [1.36.19](https://github.com/publishlab/node-acme-client/compare/v1.36.18...v1.36.19) (2025-09-05)
### Performance Improvements
* 支持ssl.com证书颁发机构 ([27b6dfa](https://github.com/publishlab/node-acme-client/commit/27b6dfa4d2ab3bddd284c3a34511a72e1a513a4c))
## [1.36.18](https://github.com/publishlab/node-acme-client/compare/v1.36.17...v1.36.18) (2025-08-28)
**Note:** Version bump only for package @certd/acme-client
+3 -3
View File
@@ -3,7 +3,7 @@
"description": "Simple and unopinionated ACME client",
"private": false,
"author": "nmorsman",
"version": "1.36.18",
"version": "1.36.21",
"type": "module",
"module": "scr/index.js",
"main": "src/index.js",
@@ -18,7 +18,7 @@
"types"
],
"dependencies": {
"@certd/basic": "^1.36.18",
"@certd/basic": "^1.36.21",
"@peculiar/x509": "^1.11.0",
"asn1js": "^3.0.5",
"axios": "^1.7.2",
@@ -69,5 +69,5 @@
"bugs": {
"url": "https://github.com/publishlab/node-acme-client/issues"
},
"gitHead": "ea18a5ad151b296fda54fb5bcbe64c7d80cdff2f"
"gitHead": "3cedef4974708d828fb972acc54af0515e3ec3a0"
}
+1 -1
View File
@@ -502,7 +502,7 @@ class AcmeClient {
await verify[challenge.type](authz, challenge, keyAuthorization);
};
log('Waiting for ACME challenge verification(等待ACME挑战验证)', this.backoffOpts);
log('Waiting for ACME challenge verification(等待ACME挑战验证)');
return util.retry(verifyFn, this.backoffOpts);
}
+4
View File
@@ -25,6 +25,10 @@ export const directory = {
staging: 'https://acme.zerossl.com/v2/DV90',
production: 'https://acme.zerossl.com/v2/DV90',
},
sslcom:{
staging: 'https://acme.ssl.com/sslcom-dv-rsa',
production: 'https://acme.ssl.com/sslcom-dv-rsa',
}
};
/**
+18
View File
@@ -3,6 +3,24 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.21](https://github.com/certd/certd/compare/v1.36.20...v1.36.21) (2025-09-15)
**Note:** Version bump only for package @certd/basic
## [1.36.20](https://github.com/certd/certd/compare/v1.36.19...v1.36.20) (2025-09-13)
**Note:** Version bump only for package @certd/basic
## [1.36.19](https://github.com/certd/certd/compare/v1.36.18...v1.36.19) (2025-09-05)
### Bug Fixes
* 修复批量流水线执行时日志显示错乱的问题 ([4372adc](https://github.com/certd/certd/commit/4372adc703b9a4c785664054ab2a533626d815a8))
### Performance Improvements
* 去掉宝塔url后面的斜杠 ([8a0c2b9](https://github.com/certd/certd/commit/8a0c2b9b13628da750c25757e0cb8ed3038775ba))
## [1.36.18](https://github.com/certd/certd/compare/v1.36.17...v1.36.18) (2025-08-28)
**Note:** Version bump only for package @certd/basic
+1 -1
View File
@@ -1 +1 @@
00:39
20:59
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/basic",
"private": false,
"version": "1.36.18",
"version": "1.36.21",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
@@ -45,5 +45,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "ea18a5ad151b296fda54fb5bcbe64c7d80cdff2f"
"gitHead": "3cedef4974708d828fb972acc54af0515e3ec3a0"
}
+178 -36
View File
@@ -1,22 +1,4 @@
import log4js, { LoggingEvent, Logger } from "log4js";
const OutputAppender = {
configure: (config: any, layouts: any, findAppender: any, levels: any) => {
let layout = layouts.basicLayout;
if (config.layout) {
layout = layouts.layout(config.layout.type, config.layout);
}
function customAppender(layout: any, timezoneOffset: any) {
return (loggingEvent: LoggingEvent) => {
if (loggingEvent.context.outputHandler?.write) {
const text = `${layout(loggingEvent, timezoneOffset)}\n`;
loggingEvent.context.outputHandler.write(text);
}
};
}
return customAppender(layout, config.timezoneOffset);
},
};
import log4js, { CallStack, Level } from "log4js";
let logFilePath = "./logs/app.log";
export function resetLogConfigure() {
@@ -24,7 +6,6 @@ export function resetLogConfigure() {
log4js.configure({
appenders: {
std: { type: "stdout" },
output: { type: OutputAppender },
file: {
type: "dateFile",
filename: logFilePath,
@@ -33,7 +14,7 @@ export function resetLogConfigure() {
numBackups: 3,
},
},
categories: { default: { appenders: ["std", "file"], level: "info" }, pipeline: { appenders: ["std", "file", "output"], level: "info" } },
categories: { default: { appenders: ["std", "file"], level: "info" }, pipeline: { appenders: ["std", "file"], level: "info" } },
});
}
resetLogConfigure();
@@ -44,15 +25,98 @@ export function resetLogFilePath(filePath: string) {
resetLogConfigure();
}
export function buildLogger(write: (text: string) => void) {
const logger = log4js.getLogger("pipeline");
const _secrets: string[] = [];
//@ts-ignore
logger.addSecret = (secret: string) => {
_secrets.push(secret);
};
logger.addContext("outputHandler", {
write: (text: string) => {
for (const item of _secrets) {
return new PipelineLogger("pipeline", write);
}
export type ILogger = {
readonly category: string;
level: Level | string;
log(level: Level | string, ...args: any[]): void;
isLevelEnabled(level?: string): boolean;
isTraceEnabled(): boolean;
isDebugEnabled(): boolean;
isInfoEnabled(): boolean;
isWarnEnabled(): boolean;
isErrorEnabled(): boolean;
isFatalEnabled(): boolean;
_log(level: Level, data: any): void;
addContext(key: string, value: any): void;
removeContext(key: string): void;
clearContext(): void;
/**
* Replace the basic parse function with a new custom one
* - Note that linesToSkip will be based on the origin of the Error object in addition to the callStackLinesToSkip (at least 1)
* @param parseFunction the new parseFunction. Use `undefined` to reset to the base implementation
*/
setParseCallStackFunction(parseFunction: (error: Error, linesToSkip: number) => CallStack | undefined): void;
/**
* Adjust the value of linesToSkip when the parseFunction is called.
*
* Cannot be less than 0.
*/
callStackLinesToSkip: number;
trace(message: any, ...args: any[]): void;
debug(message: any, ...args: any[]): void;
info(message: any, ...args: any[]): void;
warn(message: any, ...args: any[]): void;
error(message: any, ...args: any[]): void;
fatal(message: any, ...args: any[]): void;
mark(message: any, ...args: any[]): void;
};
const locale = Intl.DateTimeFormat().resolvedOptions().locale;
const formatter = new Intl.DateTimeFormat(locale, {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false,
});
function formatDateIntl(date = new Date()) {
const milliseconds = date.getMilliseconds(); // 获取毫秒
const formattedMilliseconds = milliseconds.toString().padStart(3, "0");
return formatter.format(date) + "." + formattedMilliseconds;
}
// @ts-ignore
export class PipelineLogger implements ILogger {
callStackLinesToSkip: number = 3;
readonly category: string = "pipeline";
level: Level | string = "info";
_secrets: string[] = [];
logger: ILogger;
customWriter!: (text: string) => void;
constructor(name: string, write: (text: string) => void) {
this.customWriter = write;
this.logger = log4js.getLogger(name);
}
addSecret(secret: string) {
this._secrets.push(secret);
}
_doLog(level: string, ...args: any[]) {
let text = args.join(" ");
if (this.customWriter) {
for (const item of this._secrets) {
if (item == null) {
continue;
}
@@ -66,10 +130,88 @@ export function buildLogger(write: (text: string) => void) {
text = text.replaceAll(item, "*".repeat(item.length));
}
}
write(text);
},
});
return logger;
}
text = `[${formatDateIntl()}] [${level.toUpperCase()}] - ${text} \n`;
this.customWriter(text);
}
// @ts-ignore
this.logger[level](...args);
}
export type ILogger = Logger;
_log(level: Level, data: any): void {}
addContext(key: string, value: any): void {}
clearContext(): void {}
debug(message: any, ...args: any[]): void {
if (this.isDebugEnabled()) {
this._doLog("debug", message, ...args);
}
}
error(message: any, ...args: any[]): void {
if (this.isErrorEnabled()) {
this._doLog("error", message, ...args);
}
}
fatal(message: any, ...args: any[]): void {
if (this.isFatalEnabled()) {
this._doLog("fatal", message, ...args);
}
}
info(message: any, ...args: any[]): void {
if (this.isInfoEnabled()) {
this._doLog("info", message, ...args);
}
}
trace(message: any, ...args: any[]): void {
if (this.isTraceEnabled()) {
this._doLog("trace", message, ...args);
}
}
warn(message: any, ...args: any[]): void {
if (this.isWarnEnabled()) {
this._doLog("warn", message, ...args);
}
}
isDebugEnabled(): boolean {
return logger.isDebugEnabled();
}
isErrorEnabled(): boolean {
return logger.isErrorEnabled();
}
isFatalEnabled(): boolean {
return logger.isFatalEnabled();
}
isInfoEnabled(): boolean {
return logger.isInfoEnabled();
}
isLevelEnabled(level?: string): boolean {
return logger.isLevelEnabled();
}
isTraceEnabled(): boolean {
return logger.isTraceEnabled();
}
isWarnEnabled(): boolean {
return logger.isWarnEnabled();
}
log(level: Level | string, ...args: any[]): void {}
mark(message: any, ...args: any[]): void {}
removeContext(key: string): void {}
setParseCallStackFunction(parseFunction: (error: Error, linesToSkip: number) => CallStack | undefined): void {}
}
+14 -7
View File
@@ -1,6 +1,5 @@
import axios, { AxiosHeaders, AxiosRequestConfig } from "axios";
import { ILogger, logger } from "./util.log.js";
import { Logger } from "log4js";
import { HttpProxyAgent } from "http-proxy-agent";
import { HttpsProxyAgent } from "https-proxy-agent";
import nodeHttp from "http";
@@ -8,6 +7,13 @@ import * as https from "node:https";
import { merge } from "lodash-es";
import { safePromise } from "./util.promise.js";
import fs from "fs";
const errorMap: Record<string, string> = {
"ssl3_get_record:wrong version number": "http协议错误,服务端要求http协议,请检查是否使用了https请求",
"getaddrinfo EAI_AGAIN": "无法解析域名,请检查网络连接或dns配置,更换docker-compose.yaml中dns配置",
"self-signed certificate": "目标站点为自签名证书,请勾选忽略证书校验",
};
export class HttpError extends Error {
status?: number;
statusText?: string;
@@ -22,11 +28,12 @@ export class HttpError extends Error {
super(error.message || error.response?.statusText);
const message = error?.message;
if (message && typeof message === "string") {
if (message.indexOf && message.indexOf("ssl3_get_record:wrong version number") >= 0) {
this.message = `${message}(http协议错误,服务端要求http协议,请检查是否使用了https请求)`;
} else if (message.indexOf("getaddrinfo EAI_AGAIN") >= 0) {
this.message = `${message}(无法解析域名,请检查网络连接或dns配置,更换docker-compose.yaml中dns配置)`;
if (message && typeof message === "string" && message.indexOf) {
for (const key in errorMap) {
if (message.indexOf(key) > -1) {
this.message = `${this.message}(${errorMap[key]})`;
break;
}
}
}
@@ -84,7 +91,7 @@ export function getGlobalAgents() {
/**
* @description 创建请求实例
*/
export function createAxiosService({ logger }: { logger: Logger }) {
export function createAxiosService({ logger }: { logger: ILogger }) {
// 创建一个 axios 实例
const service = axios.create();
+19
View File
@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.21](https://github.com/certd/certd/compare/v1.36.20...v1.36.21) (2025-09-15)
**Note:** Version bump only for package @certd/pipeline
## [1.36.20](https://github.com/certd/certd/compare/v1.36.19...v1.36.20) (2025-09-13)
**Note:** Version bump only for package @certd/pipeline
## [1.36.19](https://github.com/certd/certd/compare/v1.36.18...v1.36.19) (2025-09-05)
### Bug Fixes
* 前置任务输出不存在时输出警告提示 ([b59052c](https://github.com/certd/certd/commit/b59052cc43b7b070fabd8b8e914e4c2a5e0ad61c))
### Performance Improvements
* 支持godaddy ([b7980aa](https://github.com/certd/certd/commit/b7980aad5ab50f58662eaddf5d84aa82876a98eb))
* 支持ssl.com证书颁发机构 ([27b6dfa](https://github.com/certd/certd/commit/27b6dfa4d2ab3bddd284c3a34511a72e1a513a4c))
## [1.36.18](https://github.com/certd/certd/compare/v1.36.17...v1.36.18) (2025-08-28)
**Note:** Version bump only for package @certd/pipeline
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/pipeline",
"private": false,
"version": "1.36.18",
"version": "1.36.21",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
@@ -17,8 +17,8 @@
"pub": "npm publish"
},
"dependencies": {
"@certd/basic": "^1.36.18",
"@certd/plus-core": "^1.36.18",
"@certd/basic": "^1.36.21",
"@certd/plus-core": "^1.36.21",
"dayjs": "^1.11.7",
"lodash-es": "^4.17.21",
"reflect-metadata": "^0.1.13"
@@ -44,5 +44,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "ea18a5ad151b296fda54fb5bcbe64c7d80cdff2f"
"gitHead": "3cedef4974708d828fb972acc54af0515e3ec3a0"
}
+3 -3
View File
@@ -21,9 +21,9 @@ export type PageRes = {
export class Pager {
pageNo: number;
pageSize: number;
constructor(req: PageSearch) {
this.pageNo = req.pageNo ?? 1;
this.pageSize = req.pageSize || 50;
constructor(req?: PageSearch) {
this.pageNo = req?.pageNo ?? 1;
this.pageSize = req?.pageSize || 50;
}
getOffset() {
+1 -1
View File
@@ -314,7 +314,7 @@ export class Executor {
const outputKey = arr[2];
input[key] = this.currentStatusMap.get(id)?.status?.output[outputKey] ?? this.lastStatusMap.get(id)?.status?.output[outputKey];
if (input[key] == null) {
this.logger.warn(`${item.title}的配置未找到对应的输出值,请确认对应的前置任务是否存在或者是否执行正确`);
currentLogger.warn(`${item.title}的配置未找到对应的输出值,请确认对应的前置任务是否存在或者是否执行正确`);
}
}
}
+2 -2
View File
@@ -253,9 +253,9 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
return name + "_" + dayjs().format("YYYYMMDDHHmmssSSS");
}
buildCertName(domain: string) {
buildCertName(domain: string, prefix = "") {
domain = domain.replaceAll("*", "_").replaceAll(".", "_");
return `${domain}_${dayjs().format("YYYYMMDDHHmmssSSS")}`;
return `${prefix}_${domain}_${dayjs().format("YYYYMMDDHHmmssSSS")}`;
}
async onRequest(req: PluginRequestHandleReq<any>) {
@@ -69,9 +69,15 @@ export class Registry<T = any> {
return this.storage;
}
getDefineList() {
getDefineList(prefix?: string) {
let list = [];
if (prefix) {
prefix = prefix + ":";
}
for (const key in this.storage) {
if (prefix && !key.startsWith(prefix)) {
continue;
}
const define = this.getDefine(key);
if (define) {
if (define?.deprecated) {
@@ -90,7 +96,10 @@ export class Registry<T = any> {
return list;
}
getDefine(key: string) {
getDefine(key: string, prefix?: string) {
if (prefix) {
key = prefix + ":" + key;
}
const item = this.storage[key];
if (!item) {
return;