mirror of
https://github.com/certd/certd.git
synced 2026-04-05 07:20:56 +08:00
Compare commits
170 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d8f329e2d | ||
|
|
351fb70d5d | ||
|
|
b5cbeb9bde | ||
|
|
e7e89b8de7 | ||
|
|
225894d15c | ||
|
|
64ba485b0f | ||
|
|
3a666db36c | ||
|
|
ce7e5a2461 | ||
|
|
b22f94b079 | ||
|
|
3408465df6 | ||
|
|
e97dfb456b | ||
|
|
439c6c8b6c | ||
|
|
afa2b0307a | ||
|
|
56867fa777 | ||
|
|
9c2e33fa39 | ||
|
|
2ca72f838b | ||
|
|
37a9e6aae0 | ||
|
|
6a8a02dae5 | ||
|
|
eaee5db69e | ||
|
|
25d06904c6 | ||
|
|
fa14f87a80 | ||
|
|
4404f99642 | ||
|
|
bafab905b4 | ||
|
|
44d5e54550 | ||
|
|
a23c13d7d9 | ||
|
|
17a7a1432f | ||
|
|
26e8932b85 | ||
|
|
32beb02d40 | ||
|
|
af7177e6bb | ||
|
|
69ac0fd0a8 | ||
|
|
e0998f35e8 | ||
|
|
6d371b38c3 | ||
|
|
587f11138a | ||
|
|
aa936c279e | ||
|
|
5b11d351b2 | ||
|
|
b45b97d3c6 | ||
|
|
338eb3bdfe | ||
|
|
f059e91efc | ||
|
|
1cdf1c433f | ||
|
|
a7b8bac4c8 | ||
|
|
b7b5df0587 | ||
|
|
4060f6ecbc | ||
|
|
7cb5f21444 | ||
|
|
e5da46cfc3 | ||
|
|
eabb3e38b5 | ||
|
|
46140c8efa | ||
|
|
95d071ba56 | ||
|
|
3c9c3ca3b0 | ||
|
|
e7c4ade57d | ||
|
|
ca524657b6 | ||
|
|
bc02559bc7 | ||
|
|
741172fd98 | ||
|
|
83d0209775 | ||
|
|
6693d1acfb | ||
|
|
a2c43b50a6 | ||
|
|
f7fc06e657 | ||
|
|
b9fe3b9c87 | ||
|
|
06be993afc | ||
|
|
b6ef39fb30 | ||
|
|
0b131c00ed | ||
|
|
b6b8661c36 | ||
|
|
7bf19f8f6f | ||
|
|
c9d9c6513b | ||
|
|
4e7b7ae974 | ||
|
|
dfcabc02a4 | ||
|
|
6f2c5674c9 | ||
|
|
2877b9b505 | ||
|
|
e40bb9e14d | ||
|
|
d456ff9830 | ||
|
|
ffddb3b4ac | ||
|
|
a6113f237b | ||
|
|
093520b686 | ||
|
|
3a8d44b8e9 | ||
|
|
72bff652f7 | ||
|
|
9559bdf817 | ||
|
|
5a88b8c24e | ||
|
|
a9ebac82c7 | ||
|
|
cfd8836083 | ||
|
|
e01e59b188 | ||
|
|
d2fd729961 | ||
|
|
5d4ff2e3b7 | ||
|
|
6e5133f6b8 | ||
|
|
a96d5839b2 | ||
|
|
a827bc306a | ||
|
|
d8b3d7a6e0 | ||
|
|
b8f072909b | ||
|
|
fa48f2b2f0 | ||
|
|
019a1fe24e | ||
|
|
427620d34f | ||
|
|
a5a0c1f6e7 | ||
|
|
affef13037 | ||
|
|
4afbf20c1a | ||
|
|
0ef7b036dd | ||
|
|
17ef7b8b9e | ||
|
|
15eba52fad | ||
|
|
f2d894b036 | ||
|
|
d9da27710e | ||
|
|
981bff70c3 | ||
|
|
bb30d6e02f | ||
|
|
b09ccda54d | ||
|
|
a5de8d79ec | ||
|
|
a092a1e843 | ||
|
|
1c6740feff | ||
|
|
79c6e05e02 | ||
|
|
31e2085c16 | ||
|
|
64fda2f1a0 | ||
|
|
a674719a8b | ||
|
|
2f7ef0620b | ||
|
|
153e98b593 | ||
|
|
d62ea41671 | ||
|
|
8fcd9813d3 | ||
|
|
dcbf8c85dd | ||
|
|
ea0eafdb16 | ||
|
|
eda89a057a | ||
|
|
21e6eef1d3 | ||
|
|
54a27c1840 | ||
|
|
a3be0a1618 | ||
|
|
8e19e44f4c | ||
|
|
e5d93bd114 | ||
|
|
47fe3d5826 | ||
|
|
8409f5fd4a | ||
|
|
634a468ec4 | ||
|
|
7ed0544664 | ||
|
|
3d4a046634 | ||
|
|
96954b4aaa | ||
|
|
d77fc11552 | ||
|
|
5bad0bbde8 | ||
|
|
cd85ac611b | ||
|
|
0bc6d0a211 | ||
|
|
b1cd055342 | ||
|
|
303097b835 | ||
|
|
a438028002 | ||
|
|
4813872bcc | ||
|
|
3b19bfb429 | ||
|
|
a917a7bca6 | ||
|
|
86e64af35c | ||
|
|
bf6f1d8137 | ||
|
|
b1688525db | ||
|
|
2fd14430a2 | ||
|
|
bd3d959944 | ||
|
|
390e4853a5 | ||
|
|
485e603b51 | ||
|
|
3ccd7ad95d | ||
|
|
54d9050483 | ||
|
|
6d58c68e9b | ||
|
|
80019d4dc1 | ||
|
|
031df8fc35 | ||
|
|
62419a8212 | ||
|
|
09d93af853 | ||
|
|
b6ab178de9 | ||
|
|
5a08f27d2c | ||
|
|
fe91d94090 | ||
|
|
56ab3269d2 | ||
|
|
c8243c573f | ||
|
|
0b769a1c86 | ||
|
|
a8189a974d | ||
|
|
322875d241 | ||
|
|
ed8a54a2bc | ||
|
|
5ba9831ed1 | ||
|
|
f9c9fce581 | ||
|
|
bc650a32cd | ||
|
|
c6d3e3fe5b | ||
|
|
73acc62af1 | ||
|
|
0d4491f3a0 | ||
|
|
85248044ab | ||
|
|
c532449102 | ||
|
|
970c7fd8a0 | ||
|
|
4656019898 | ||
|
|
7eceabb2d8 | ||
|
|
eade2c2b68 |
69
.github/workflows/build-image.yml
vendored
Normal file
69
.github/workflows/build-image.yml
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
name: build-image
|
||||
on:
|
||||
push:
|
||||
branches: ['v2']
|
||||
paths:
|
||||
- "build.trigger"
|
||||
|
||||
# schedule:
|
||||
# - # 国际时间 19:17 执行,北京时间3:17 ↙↙↙ 改成你想要每天自动执行的时间
|
||||
# - cron: '17 19 * * *'
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build-certd-image:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: get_certd_version
|
||||
id: get_certd_version
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
result-encoding: string
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const pnpmWorkspace = "./pnpm-workspace.yaml";
|
||||
fs.unlinkSync(pnpmWorkspace)
|
||||
const jsonFilePath = "./packages/ui/certd-server/package.json";
|
||||
const jsonContent = fs.readFileSync(jsonFilePath, 'utf-8');
|
||||
const pkg = JSON.parse(jsonContent)
|
||||
console.log("certd_version:",pkg.version);
|
||||
return pkg.version
|
||||
# - name: Use Node.js
|
||||
# uses: actions/setup-node@v4
|
||||
# with:
|
||||
# node-version: 18
|
||||
# cache: 'npm'
|
||||
# working-directory: ./packages/ui/certd-client
|
||||
- run: |
|
||||
npm install -g pnpm
|
||||
pnpm install
|
||||
npm run build
|
||||
working-directory: ./packages/ui/certd-client
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to aliyun container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: registry.cn-shenzhen.aliyuncs.com
|
||||
username: ${{ secrets.aliyun_cs_username }}
|
||||
password: ${{ secrets.aliyun_cs_password }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6.5.0
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
push: true
|
||||
context: ./packages/ui/
|
||||
tags: |
|
||||
registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest
|
||||
registry.cn-shenzhen.aliyuncs.com/handsfree/certd:${{steps.get_certd_version.outputs.result}}
|
||||
2
.github/workflows/sync-to-gitee.yml
vendored
2
.github/workflows/sync-to-gitee.yml
vendored
@@ -2,8 +2,6 @@ name: sync-to-gitee
|
||||
on:
|
||||
push:
|
||||
branches: ['v2']
|
||||
pull_request:
|
||||
branches: ['v2']
|
||||
# schedule:
|
||||
# - # 国际时间 19:17 执行,北京时间3:17 ↙↙↙ 改成你想要每天自动执行的时间
|
||||
# - cron: '17 19 * * *'
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -34,3 +34,8 @@ gen
|
||||
|
||||
docker/image/workspace
|
||||
/packages/core/lego
|
||||
|
||||
tsconfig.tsbuildinfo
|
||||
test/**/*.js
|
||||
/packages/ui/certd-server/data/db.sqlite
|
||||
/packages/ui/certd-server/data/keys.yaml
|
||||
|
||||
3
.npmrc
3
.npmrc
@@ -1 +1,2 @@
|
||||
link-workspace-packages=deep
|
||||
link-workspace-packages=true
|
||||
prefer-workspace-packages=true
|
||||
|
||||
7
.prettierrc
Normal file
7
.prettierrc
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"printWidth": 160,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
66
CHANGELOG.md
66
CHANGELOG.md
@@ -3,6 +3,72 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.22.5](https://github.com/certd/certd/compare/v1.22.4...v1.22.5) (2024-07-26)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复用户管理无法添加用户的bug ([e7e89b8](https://github.com/certd/certd/commit/e7e89b8de7386e84c0d6b8e217e2034909657d68))
|
||||
|
||||
## [1.22.4](https://github.com/certd/certd/compare/v1.22.3...v1.22.4) (2024-07-26)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 证书申请支持反向代理,letsencrypt无法访问时的备用方案 ([b7b5df0](https://github.com/certd/certd/commit/b7b5df0587e0f7ea288c1b2af6f87211f207395f))
|
||||
* 支持arm64 ([fa14f87](https://github.com/certd/certd/commit/fa14f87a8093ef3addc5e5f3315ce1bfc9982782))
|
||||
|
||||
## [1.22.3](https://github.com/certd/certd/compare/v1.22.2...v1.22.3) (2024-07-25)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* lege 无执行权限问题 ([338eb3b](https://github.com/certd/certd/commit/338eb3bdfeb461e9b3bc7eee97b97a59f5642ffe))
|
||||
|
||||
## [1.22.2](https://github.com/certd/certd/compare/v1.22.1...v1.22.2) (2024-07-23)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复创建流水线时,无法根据dns类型默认正确的dns授权的bug ([a2c43b5](https://github.com/certd/certd/commit/a2c43b50a6069ed48958fd142844a8568c2af452))
|
||||
|
||||
## [1.22.1](https://github.com/certd/certd/compare/v1.22.0...v1.22.1) (2024-07-20)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 创建证书任务可以选择lege插件 ([affef13](https://github.com/certd/certd/commit/affef130378030c517250c58a4e787b0fc85d7d1))
|
||||
* 创建证书任务增加定时任务和邮件通知输入 ([427620d](https://github.com/certd/certd/commit/427620d34f3b8ad6933005faf1878908441a2453))
|
||||
* 支持配置启动后自动触发一次任务 ([a5a0c1f](https://github.com/certd/certd/commit/a5a0c1f6e7a3f05e581005e491d5b102ee854412))
|
||||
|
||||
# [1.22.0](https://github.com/certd/certd/compare/v1.21.2...v1.22.0) (2024-07-19)
|
||||
|
||||
### Features
|
||||
|
||||
* 升级midway,支持esm ([485e603](https://github.com/certd/certd/commit/485e603b5165c28bc08694997726eaf2a585ebe7))
|
||||
* 支持lego,海量DNS提供商 ([0bc6d0a](https://github.com/certd/certd/commit/0bc6d0a211920fb0084d705e1db67ee1e7262c44))
|
||||
* 支持postgresql ([3b19bfb](https://github.com/certd/certd/commit/3b19bfb4291e89064b3b407a80dae092d54747d5))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化一些小细节 ([b168852](https://github.com/certd/certd/commit/b1688525dbbbfd67e0ab1cf5b4ddfbe9d394f370))
|
||||
* 增加备案号设置 ([bd3d959](https://github.com/certd/certd/commit/bd3d959944db63a5690b55ee150e1007133868b9))
|
||||
* 自动生成jwtkey,无需手动配置 ([390e485](https://github.com/certd/certd/commit/390e4853a570390a97df6a3b3882579f9547eeb4))
|
||||
|
||||
## [1.21.2](https://github.com/certd/certd/compare/v1.21.1...v1.21.2) (2024-07-08)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 申请证书时可以选择跳过本地dns校验 ([fe91d94](https://github.com/certd/certd/commit/fe91d94090d22ed0a3ea753ba74dfaa1bf057c17))
|
||||
|
||||
## [1.21.1](https://github.com/certd/certd/compare/v1.21.0...v1.21.1) (2024-07-08)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 上传到主机,支持设置不mkdirs ([5ba9831](https://github.com/certd/certd/commit/5ba9831ed1aa6ec6057df246f1035b36b9c41d2e))
|
||||
* 说明优化,默认值优化 ([970c7fd](https://github.com/certd/certd/commit/970c7fd8a0f557770e973d8462ee5684ef742810))
|
||||
|
||||
# [1.21.0](https://github.com/certd/certd/compare/v1.20.17...v1.21.0) (2024-07-03)
|
||||
|
||||
### Features
|
||||
|
||||
* 支持zero ssl ([eade2c2](https://github.com/certd/certd/commit/eade2c2b681569f03e9cd466e7d5bcd6703ed492))
|
||||
|
||||
## [1.20.17](https://github.com/certd/certd/compare/v1.20.16...v1.20.17) (2024-07-03)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
121
README.md
121
README.md
@@ -1,21 +1,21 @@
|
||||
# CertD
|
||||
|
||||
CertD 是一个免费全自动申请和部署SSL证书的工具。
|
||||
CertD 是一个免费全自动申请和自动部署更新SSL证书的工具。
|
||||
后缀D取自linux守护进程的命名风格,意为证书守护进程。
|
||||
|
||||
关键字:证书自动申请、证书自动更新、证书自动续期、证书自动续签
|
||||
|
||||
## 一、特性
|
||||
本项目不仅支持证书申请过程自动化,还可以自动化部署证书,让你的证书永不过期。
|
||||
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
||||
|
||||
* 全自动申请证书(支持阿里云、腾讯云、华为云、Cloudflare注册的域名)
|
||||
* 全自动部署证书(目前支持服务器上传部署、部署到阿里云、腾讯云等)
|
||||
* 支持通配符域名
|
||||
* 支持多个域名打到一个证书上
|
||||
* 全自动申请证书(支持阿里云、腾讯云、华为云、Cloudflare等各种途径注册的域名)
|
||||
* 全自动部署更新证书(目前支持部署到主机、部署到阿里云、腾讯云等)
|
||||
* 支持通配符域名/泛域名,支持多个域名打到一个证书上
|
||||
* 邮件通知
|
||||
* 证书自动更新
|
||||
* 私有化部署,保障安全
|
||||
* 免费、免费、免费([阿里云单个通配符域名证书最便宜也要1800/年](https://yundun.console.aliyun.com/?p=cas#/certExtend/buy/cn-hangzhou))
|
||||
|
||||
|
||||
|
||||
## 二、在线体验
|
||||
|
||||
官方Demo地址,自助注册后体验
|
||||
@@ -38,7 +38,9 @@ https://certd.handsfree.work/
|
||||
-------> [点我查看详细使用步骤演示](./step.md) <--------
|
||||
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
|
||||
|
||||
## 四、本地docker部署
|
||||
## 四、私有化部署
|
||||
|
||||
由于证书、授权信息等属于高度敏感数据,请务必私有化部署,保障数据安全
|
||||
|
||||
### 1. 安装docker、docker-compose
|
||||
|
||||
@@ -47,80 +49,91 @@ https://certd.handsfree.work/
|
||||
* 【腾讯云】云服务器2核2G,新老用户同享,99元/年,续费同价!【 [立即购买](https://cloud.tencent.com/act/cps/redirect?redirect=6094&cps_key=b3ef73330335d7a6efa4a4bbeeb6b2c9&from=console)】
|
||||
|
||||
|
||||
1.2 安装docker
|
||||
https://docs.docker.com/engine/install/
|
||||
选择对应的操作系统,按照官方文档执行命令即可
|
||||
1.2 安装docker
|
||||
|
||||
https://docs.docker.com/engine/install/
|
||||
选择对应的操作系统,按照官方文档执行命令即可
|
||||
|
||||
### 2. 下载docker-compose.yaml文件
|
||||
### 2. 运行certd
|
||||
|
||||
[docker-compose.yaml下载](https://gitee.com/certd/certd/raw/v2/docker/run/docker-compose.yaml)
|
||||
[docker-compose.yaml 下载](https://gitee.com/certd/certd/raw/v2/docker/run/docker-compose.yaml)
|
||||
|
||||
当前版本号: 
|
||||
|
||||
```bash
|
||||
# 随便创建一个目录
|
||||
mkdir certd
|
||||
# 进入目录
|
||||
cd certd
|
||||
# wget下载docker-compose.yaml文件
|
||||
wget https://raw.githubusercontent.com/certd/certd/v2/docker/run/docker-compose.yaml
|
||||
# 或者使用gitee地址
|
||||
# 下载docker-compose.yaml文件,或者手动下载放到certd目录下
|
||||
wget https://gitee.com/certd/certd/raw/v2/docker/run/docker-compose.yaml
|
||||
|
||||
# 根据需要修改里面的配置
|
||||
# 可以根据需要修改里面的配置
|
||||
# 1.修改镜像版本号【可选】
|
||||
# 2.配置数据保存路径【可选】
|
||||
# 3.配置certd_auth_jwt_secret【必须】
|
||||
vi docker-compose.yaml
|
||||
# 3.修改端口号【可选】
|
||||
vi docker-compose.yaml # 【可选】
|
||||
|
||||
|
||||
```
|
||||
> 镜像版本号与release版本号同步:
|
||||
https://github.com/certd/certd/releases
|
||||
|
||||
|
||||
### 3. 运行
|
||||
```bash
|
||||
# 如果docker compose是插件化安装
|
||||
export CERTD_VERSION=latest
|
||||
# 启动certd
|
||||
docker compose up -d
|
||||
|
||||
```
|
||||
如果提示 没有compose命令,请安装docker-compose
|
||||
https://docs.docker.com/compose/install/linux/
|
||||
> 如果提示 没有compose命令,请安装docker-compose
|
||||
> https://docs.docker.com/compose/install/linux/
|
||||
|
||||
#### 镜像说明:
|
||||
* certd镜像地址:
|
||||
* `registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest`
|
||||
|
||||
* 镜像构建通过`Actions`自动执行,过程公开透明,请放心使用
|
||||
* [点我查看镜像构建日志](https://github.com/certd/certd/actions/workflows/build-image.yml)
|
||||
|
||||

|
||||
|
||||
|
||||
### 3. 访问
|
||||
|
||||
### 4. 访问
|
||||
|
||||
http://your_server_ip:7001
|
||||
默认账号密码:admin/123456
|
||||
记得修改密码
|
||||
http://your_server_ip:7001
|
||||
默认账号密码:admin/123456
|
||||
记得修改密码
|
||||
|
||||
|
||||
### 5. 升级
|
||||
## 五、 升级
|
||||
如果使用固定版本号
|
||||
1. 修改`docker-compose.yaml`中的镜像版本号
|
||||
2. 运行 `docker compose up -d` 即可
|
||||
|
||||
* 修改版本号,重新运行 `docker compose up -d` 即可
|
||||
* 数据存在`/data/certd`目录下,不用担心数据丢失
|
||||
如果使用`latest`版本
|
||||
1. 重新拉取镜像 `docker pull registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest`
|
||||
2. 重新启动容器 `docker compose restart`
|
||||
|
||||
> 数据默认存在`/data/certd`目录下,不用担心数据丢失
|
||||
|
||||
|
||||
更新日志: [CHANGELOG](./CHANGELOG.md)
|
||||
|
||||
## 五、一些说明
|
||||
|
||||
## 六、一些说明
|
||||
* 本项目ssl证书提供商为letencrypt
|
||||
* 申请过程遵循acme协议
|
||||
* 需要验证域名所有权,一般有两种方式(目前本项目仅支持dns-01)
|
||||
* http-01: 在网站根目录下放置一份txt文件
|
||||
* dns-01: 需要给域名添加txt解析记录,通配符域名只能用这种方式
|
||||
* 证书续期:
|
||||
* 实际上acme并没有续期概念。
|
||||
* 我们所说的续期,其实就是按照全套流程重新申请一份新证书。
|
||||
* 实际上没有办法不改变证书文件本身情况下直接续期或者续签。
|
||||
* 我们所说的续期,其实就是按照全套流程重新申请一份新证书,然后重新部署上去。
|
||||
* 免费证书过期时间90天,以后可能还会缩短,所以自动化部署必不可少
|
||||
* 设置每天自动运行,当证书过期前20天,会自动重新申请证书并部署
|
||||
|
||||
## 六、不同平台的设置说明
|
||||
|
||||
## 七、不同平台的设置说明
|
||||
|
||||
* [Cloudflare](./doc/cf/cf.md)
|
||||
* [腾讯云](./doc/tencent/tencent.md)
|
||||
* [windows主机](./doc/host/host.md)
|
||||
|
||||
|
||||
## 七、问题处理
|
||||
## 八、问题处理
|
||||
### 7.1 忘记管理员密码
|
||||
解决方法如下:
|
||||
1. 修改docker-compose.yaml文件,将环境变量`certd_system_resetAdminPassword`改为`true`
|
||||
@@ -141,9 +154,9 @@ docker logs -f --tail 500 certd
|
||||
```shell
|
||||
docker compose up -d
|
||||
```
|
||||
5. 使用admin/123456登录系统,请及时修改管理员密码
|
||||
5. 使用`admin/123456`登录系统,请及时修改管理员密码
|
||||
|
||||
## 八、联系作者
|
||||
## 九、联系作者
|
||||
如有疑问,欢迎加入群聊(请备注certd)
|
||||
* QQ群:141236433
|
||||
* 微信群:
|
||||
@@ -155,7 +168,7 @@ docker compose up -d
|
||||
<img height="230" src="./doc/images/me.png">
|
||||
</p>
|
||||
|
||||
## 九、捐赠
|
||||
## 十、捐赠
|
||||
媳妇儿说:“一天到晚搞开源,也不管管老婆孩子!😡😡😡”
|
||||
拜托各位捐赠支持一下,让媳妇儿开心开心,我也能有更多时间进行开源项目,感谢🙏🙏🙏
|
||||
<p align="center">
|
||||
@@ -163,12 +176,20 @@ docker compose up -d
|
||||
</p>
|
||||
|
||||
|
||||
## 十、贡献代码
|
||||
## 十一、贡献代码
|
||||
|
||||
[贡献插件教程](./plugin.md)
|
||||
|
||||
|
||||
## 十一、我的其他项目
|
||||
## 十二、我的其他项目(求Star)
|
||||
* [袖手GPT](https://ai.handsfree.work/) ChatGPT,国内可用,无需FQ,每日免费额度
|
||||
* [fast-crud](https://gitee.com/fast-crud/fast-crud/) 基于vue3的crud快速开发框架
|
||||
* [dev-sidecar](https://github.com/docmirror/dev-sidecar/) 直连访问github工具,无需FQ,解决github无法访问的问题
|
||||
|
||||
|
||||
|
||||
## 十三、更新日志
|
||||
|
||||
更新日志:[CHANGELOG](./CHANGELOG.md)
|
||||
|
||||
|
||||
|
||||
1
build.trigger
Normal file
1
build.trigger
Normal file
@@ -0,0 +1 @@
|
||||
6
|
||||
12
deploy.js
12
deploy.js
@@ -1,6 +1,5 @@
|
||||
import http from 'axios'
|
||||
import fs from 'fs'
|
||||
|
||||
//读取 packages/core/pipline/package.json的版本号
|
||||
import {default as packageJson} from './packages/core/pipeline/package.json' assert { type: "json" };
|
||||
|
||||
@@ -33,8 +32,9 @@ async function getPackages(directoryPath) {
|
||||
async function getAllPackages() {
|
||||
const base = await getPackages("./packages/core")
|
||||
const plugins = await getPackages("./packages/plugins")
|
||||
const libs = await getPackages("./packages/libs")
|
||||
|
||||
return base.concat(plugins)
|
||||
return base.concat(plugins).concat(libs)
|
||||
}
|
||||
|
||||
async function sync() {
|
||||
@@ -49,7 +49,7 @@ async function sync() {
|
||||
data: {}
|
||||
})
|
||||
console.log(`sync success:${pkg}`)
|
||||
await sleep(100*1000)
|
||||
await sleep(30*1000)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ async function triggerBuild() {
|
||||
}
|
||||
})
|
||||
console.log(`webhook success:${webhook}`)
|
||||
await sleep(10*60*1000)
|
||||
await sleep(30*60*1000)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -87,9 +87,9 @@ async function triggerBuild() {
|
||||
async function start() {
|
||||
// await build()
|
||||
console.log("等待60秒")
|
||||
await sleep(200 * 1000)
|
||||
await sleep(100* 1000)
|
||||
await sync()
|
||||
await sleep(60 * 1000)
|
||||
await sleep(100 * 1000)
|
||||
await triggerBuild()
|
||||
}
|
||||
|
||||
|
||||
BIN
doc/images/action-build.jpg
Normal file
BIN
doc/images/action-build.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 109 KiB |
@@ -1,20 +0,0 @@
|
||||
FROM registry.cn-shenzhen.aliyuncs.com/handsfree/node:18-alpine
|
||||
EXPOSE 7001
|
||||
ENV NODE_ENV production
|
||||
ENV MIDWAY_SERVER_ENV production
|
||||
WORKDIR /app/
|
||||
#RUN npm install -g pnpm
|
||||
#RUN npm install cross-env -g --registry=https://registry.npmmirror.com
|
||||
#RUN npm install pm2 -g --registry=https://registry.npmmirror.com
|
||||
#RUN pm2 install pm2-logrotate
|
||||
ADD ./workspace/certd-server/ /app/
|
||||
RUN sed -i "s/workspace://g" "/app/package.json"
|
||||
RUN yarn install --production --registry=https://registry.npmmirror.com
|
||||
#RUN yarn install --production
|
||||
RUN npm run build
|
||||
#CMD ["pm2-runtime", "start", "./bootstrap.js","--name", "certd","-i","1"]
|
||||
CMD ["npm", "run","start"]
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
echo "请先输入一个版本号:"
|
||||
read version
|
||||
|
||||
echo "您输入的版本号是: $version"
|
||||
echo "登录aliyun镜像仓库"
|
||||
sudo docker login --username=252959493@qq.com registry.cn-shenzhen.aliyuncs.com
|
||||
|
||||
build=$(pwd)
|
||||
cd ../../
|
||||
root=$(pwd)
|
||||
echo "安装依赖"
|
||||
#pnpm install --registry=https://registry.npmmirror.com
|
||||
pnpm install
|
||||
|
||||
echo "client build"
|
||||
cd $root/packages/ui/certd-client
|
||||
pnpm run build
|
||||
echo "client build success"
|
||||
|
||||
echo "server build"
|
||||
cd $root/packages/ui/certd-server
|
||||
pnpm run build
|
||||
echo "server build success"
|
||||
|
||||
echo "rm node_modules"
|
||||
rm ./node_modules -rf
|
||||
|
||||
echo "copy to workspace"
|
||||
mkdir -p $build/workspace/certd-server
|
||||
\cp ./* $build/workspace/certd-server -rf
|
||||
\cp ../certd-client/dist/* $build/workspace/certd-server/public/ -rf
|
||||
|
||||
#export TAG=$version
|
||||
#sudo -E docker compose build
|
||||
#sudo -E docker compose push
|
||||
@@ -1,26 +1,27 @@
|
||||
version: '3.3'
|
||||
services:
|
||||
certd:
|
||||
# 镜像 # ↓↓↓↓↓ --- 1、 修改镜像版本号,或者干脆写成latest, 如果设置了环境变量 export CERTD_VERSION=latest,这里可以不修改
|
||||
image: registry.cn-shenzhen.aliyuncs.com/handsfree/certd:${CERTD_VERSION}
|
||||
# 镜像 # ↓↓↓↓↓ --- 1、 镜像版本号,建议改成固定版本号【可选】
|
||||
image: registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest
|
||||
container_name: certd # 容器名
|
||||
restart: unless-stopped # 自动重启
|
||||
volumes:
|
||||
# ↓↓↓↓↓ ------------------------------------------------------- 2、 修改数据库以及证书存储路径【可选】
|
||||
# ↓↓↓↓↓ ------------------------------------------------------- 2、 数据库以及证书存储路径,默认存在宿主机的/data/certd/目录下【可选】
|
||||
- /data/certd:/app/data
|
||||
ports: # 端口映射
|
||||
# ↓↓↓↓ 如果端口有冲突,可以修改第一个7001为其他不冲突的端口号
|
||||
# ↓↓↓↓ ----------------------------------------------------------3、如果端口有冲突,可以修改第一个7001为其他不冲突的端口号【可选】
|
||||
- "7001:7001"
|
||||
environment: # 环境变量
|
||||
- TZ=Asia/Shanghai
|
||||
- certd_auth_jwt_secret=changeme
|
||||
# ↑↑↑↑↑ ---------------------------------- 3、 修改成你的自定义密钥【必须,安全需要】
|
||||
- certd_system_resetAdminPassword=false
|
||||
# ↑↑↑↑↑ 如果忘记管理员密码,可以设置为true,重启之后,管理员密码将改成123456,然后请及时修改回false
|
||||
# ↑↑↑↑↑---------------------------4、如果忘记管理员密码,可以设置为true,重启之后,管理员密码将改成123456,然后请及时修改回false【可选】
|
||||
- certd_cron_immediateTriggerOnce=false
|
||||
# ↑↑↑↑↑---------------------------5、如果设置为true,启动后所有配置了cron的流水线任务都将被立即触发一次【可选】
|
||||
- VITE_APP_ICP_NO=
|
||||
# ↑↑↑↑↑ -----------------------------------------6、这里可以设置备案号【可选】
|
||||
# 设置环境变量即可自定义certd配置
|
||||
# 服务端配置项见: packages/ui/certd-server/src/config/config.default.ts
|
||||
# 服务端配置规则: certd_ + 配置项, 点号用_代替
|
||||
# 如jwt密钥配置为: auth.jwt.secret,则设置环境变量 certd_auth_jwt_secret=changeme
|
||||
|
||||
# 客户端配置项见: packages/ui/certd-client/.env
|
||||
# 按实际名称配置环境变量即可,如: VITE_APP_API=http://localhost:7001
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
# 判断$CERTD_VERSION 是否存在
|
||||
if [ -n "$CERTD_VERSION" ]; then
|
||||
echo "CERTD_VERSION is set = $CERTD_VERSION"
|
||||
else
|
||||
echo "CERTD_VERSION is not set"
|
||||
echo "请先输入一个版本号(如 1.0.6):"
|
||||
read CERTD_VERSION
|
||||
fi
|
||||
|
||||
echo "您输入的版本号是: $CERTD_VERSION"
|
||||
sudo -E docker compose up -d
|
||||
@@ -9,5 +9,5 @@
|
||||
}
|
||||
},
|
||||
"npmClient": "pnpm",
|
||||
"version": "1.20.17"
|
||||
"version": "1.22.5"
|
||||
}
|
||||
|
||||
14
package.json
14
package.json
@@ -12,15 +12,17 @@
|
||||
"scripts": {
|
||||
"start": "lerna bootstrap --hoist",
|
||||
"i-all": "lerna link && lerna exec npm install ",
|
||||
"publish": "npm run prepublishOnly1 && lerna publish --conventional-commits && npm run afterpublishOnly && npm run deploy1",
|
||||
"afterpublishOnly": "",
|
||||
"prepublishOnly1": "npm run before-build && lerna run build ",
|
||||
"before-build": "cd ./packages/core/acme-client && time /t >build.md && git add ./build.md && git commit -m \"build: prepare to build\"",
|
||||
"deploy1": "node --experimental-json-modules deploy.js "
|
||||
"publish": "npm run prepublishOnly1 && lerna publish --conventional-commits --create-release github && npm run afterpublishOnly",
|
||||
"afterpublishOnly": "time /t >build.trigger && git add ./build.md && git commit -m \"build: trigger build image\" && TIMEOUT /T 10 && git push",
|
||||
"prepublishOnly1": "npm run check && npm run before-build && lerna run build ",
|
||||
"before-build": "cd ./packages/core/pipeline && time /t >build.md && git add ./build.md && git commit -m \"build: prepare to build\"",
|
||||
"deploy1": "node --experimental-json-modules deploy.js ",
|
||||
"check": "node --experimental-json-modules publish-check.js",
|
||||
"init": "lerna run build"
|
||||
},
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"axios": "^1.4.0",
|
||||
"axios": "^1.7.2",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"workspaces": [
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
set -euo pipefail
|
||||
|
||||
# Download and install
|
||||
wget -nv "https://github.com/letsencrypt/pebble/releases/download/v${PEBBLECTS_VERSION}/pebble-challtestsrv_linux-amd64" -O /usr/local/bin/pebble-challtestsrv
|
||||
wget -nv "https://github.com/letsencrypt/pebble/releases/download/v${PEBBLECTS_VERSION}/pebble-challtestsrv-linux-amd64.tar.gz" -O /tmp/pebble-challtestsrv.tar.gz
|
||||
tar zxvf /tmp/pebble-challtestsrv.tar.gz -C /tmp
|
||||
|
||||
mv /tmp/pebble-challtestsrv-linux-amd64/linux/amd64/pebble-challtestsrv /usr/local/bin/pebble-challtestsrv
|
||||
chown root:root /usr/local/bin/pebble-challtestsrv
|
||||
chmod 0755 /usr/local/bin/pebble-challtestsrv
|
||||
|
||||
|
||||
@@ -22,8 +22,10 @@ wget -nv "https://raw.githubusercontent.com/letsencrypt/pebble/v${PEBBLE_VERSION
|
||||
wget -nv "https://raw.githubusercontent.com/letsencrypt/pebble/v${PEBBLE_VERSION}/test/config/${CONFIG_NAME}" -O /etc/pebble/pebble.json
|
||||
|
||||
# Download and install Pebble
|
||||
wget -nv "https://github.com/letsencrypt/pebble/releases/download/v${PEBBLE_VERSION}/pebble_linux-amd64" -O /usr/local/bin/pebble
|
||||
wget -nv "https://github.com/letsencrypt/pebble/releases/download/v${PEBBLE_VERSION}/pebble-linux-amd64.tar.gz" -O /tmp/pebble.tar.gz
|
||||
tar zxvf /tmp/pebble.tar.gz -C /tmp
|
||||
|
||||
mv /tmp/pebble-linux-amd64/linux/amd64/pebble /usr/local/bin/pebble
|
||||
chown root:root /usr/local/bin/pebble
|
||||
chmod 0755 /usr/local/bin/pebble
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node: [16, 18, 20, 22]
|
||||
node: [16, 18, 20]
|
||||
eab: [0, 1]
|
||||
|
||||
#
|
||||
@@ -19,9 +19,9 @@ jobs:
|
||||
FORCE_COLOR: 1
|
||||
NPM_CONFIG_COLOR: always
|
||||
|
||||
PEBBLE_VERSION: 2.3.1
|
||||
PEBBLE_VERSION: 2.6.0
|
||||
PEBBLE_ALTERNATE_ROOTS: 2
|
||||
PEBBLECTS_VERSION: 2.3.1
|
||||
PEBBLECTS_VERSION: 2.6.0
|
||||
PEBBLECTS_DNS_PORT: 8053
|
||||
COREDNS_VERSION: 1.11.1
|
||||
|
||||
|
||||
@@ -3,6 +3,44 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.22.4](https://github.com/publishlab/node-acme-client/compare/v1.22.3...v1.22.4) (2024-07-26)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 证书申请支持反向代理,letsencrypt无法访问时的备用方案 ([b7b5df0](https://github.com/publishlab/node-acme-client/commit/b7b5df0587e0f7ea288c1b2af6f87211f207395f))
|
||||
|
||||
## [1.22.3](https://github.com/publishlab/node-acme-client/compare/v1.22.2...v1.22.3) (2024-07-25)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.22.2](https://github.com/publishlab/node-acme-client/compare/v1.22.1...v1.22.2) (2024-07-23)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.22.1](https://github.com/publishlab/node-acme-client/compare/v1.22.0...v1.22.1) (2024-07-20)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
# [1.22.0](https://github.com/publishlab/node-acme-client/compare/v1.21.2...v1.22.0) (2024-07-19)
|
||||
|
||||
### Features
|
||||
|
||||
* 升级midway,支持esm ([485e603](https://github.com/publishlab/node-acme-client/commit/485e603b5165c28bc08694997726eaf2a585ebe7))
|
||||
|
||||
## [1.21.2](https://github.com/publishlab/node-acme-client/compare/v1.21.1...v1.21.2) (2024-07-08)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.21.1](https://github.com/publishlab/node-acme-client/compare/v1.21.0...v1.21.1) (2024-07-08)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
# [1.21.0](https://github.com/publishlab/node-acme-client/compare/v1.20.17...v1.21.0) (2024-07-03)
|
||||
|
||||
### Features
|
||||
|
||||
* 支持zero ssl ([eade2c2](https://github.com/publishlab/node-acme-client/commit/eade2c2b681569f03e9cd466e7d5bcd6703ed492))
|
||||
|
||||
## [1.20.17](https://github.com/publishlab/node-acme-client/compare/v1.20.16...v1.20.17) (2024-07-03)
|
||||
|
||||
### Performance Improvements
|
||||
@@ -68,6 +106,11 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
||||
|
||||
# Changelog
|
||||
|
||||
## v5.4.0
|
||||
|
||||
* `added` Directory URLs for [Google](https://cloud.google.com/certificate-manager/docs/overview) ACME provider
|
||||
* `fixed` Invalidate ACME directory cache after 24 hours
|
||||
|
||||
## v5.3.1 (2024-05-22)
|
||||
|
||||
* `fixed` Allow `client.auto()` being called with an empty CSR common name
|
||||
|
||||
@@ -59,6 +59,9 @@ const client = new acme.Client({
|
||||
acme.directory.buypass.staging;
|
||||
acme.directory.buypass.production;
|
||||
|
||||
acme.directory.google.staging;
|
||||
acme.directory.google.production;
|
||||
|
||||
acme.directory.letsencrypt.staging;
|
||||
acme.directory.letsencrypt.production;
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
23:43
|
||||
20:55
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "Simple and unopinionated ACME client",
|
||||
"private": false,
|
||||
"author": "nmorsman",
|
||||
"version": "1.20.17",
|
||||
"version": "1.22.4",
|
||||
"main": "src/index.js",
|
||||
"types": "types/index.d.ts",
|
||||
"license": "MIT",
|
||||
@@ -59,5 +59,5 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||
},
|
||||
"gitHead": "a31f1c7f5e71fa946de9bf0283e11d6ce049b3e9"
|
||||
"gitHead": "e5da46cfc31b2e30a4903bcb2251b1851265ef41"
|
||||
}
|
||||
|
||||
@@ -36,6 +36,9 @@ module.exports = async (client, userOpts) => {
|
||||
if (opts.email) {
|
||||
accountPayload.contact = [`mailto:${opts.email}`];
|
||||
}
|
||||
if (opts.externalAccountBinding) {
|
||||
accountPayload.externalAccountBinding = opts.externalAccountBinding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register account
|
||||
|
||||
@@ -100,7 +100,7 @@ class AcmeClient {
|
||||
max: this.opts.backoffMax,
|
||||
};
|
||||
|
||||
this.http = new HttpClient(this.opts.directoryUrl, this.opts.accountKey, this.opts.externalAccountBinding);
|
||||
this.http = new HttpClient(this.opts.directoryUrl, this.opts.accountKey, this.opts.externalAccountBinding, this.opts.urlMapping);
|
||||
this.api = new AcmeApi(this.http, this.opts.accountUrl);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,10 +12,11 @@ const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy;
|
||||
let httpsAgent = null;
|
||||
if (httpsProxy) {
|
||||
httpsAgent = new HttpsProxyAgent(httpsProxy);
|
||||
log(`use https_proxy:${httpsProxy}`);
|
||||
}
|
||||
const axios = axios1.create({
|
||||
proxy: false,
|
||||
httpsAgent
|
||||
httpsAgent,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -30,14 +31,18 @@ const axios = axios1.create({
|
||||
*/
|
||||
|
||||
class HttpClient {
|
||||
constructor(directoryUrl, accountKey, externalAccountBinding = {}) {
|
||||
constructor(directoryUrl, accountKey, externalAccountBinding = {}, urlMapping = {}) {
|
||||
this.directoryUrl = directoryUrl;
|
||||
this.accountKey = accountKey;
|
||||
this.externalAccountBinding = externalAccountBinding;
|
||||
|
||||
this.maxBadNonceRetries = 5;
|
||||
this.directory = null;
|
||||
this.jwk = null;
|
||||
|
||||
this.directoryCache = null;
|
||||
this.directoryMaxAge = 86400;
|
||||
this.directoryTimestamp = 0;
|
||||
this.urlMapping = urlMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,6 +55,16 @@ class HttpClient {
|
||||
*/
|
||||
|
||||
async request(url, method, opts = {}) {
|
||||
if (this.urlMapping && this.urlMapping.enabled === true && this.urlMapping.mappings) {
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const key in this.urlMapping.mappings) {
|
||||
if (url.includes(key)) {
|
||||
const newUrl = url.replace(key, this.urlMapping.mappings[key]);
|
||||
log(`use reverse proxy: ${newUrl}`);
|
||||
url = newUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
opts.url = url;
|
||||
opts.method = method;
|
||||
opts.validateStatus = null;
|
||||
@@ -70,15 +85,17 @@ class HttpClient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure provider directory exists
|
||||
* Get ACME provider directory
|
||||
*
|
||||
* https://datatracker.ietf.org/doc/html/rfc8555#section-7.1.1
|
||||
*
|
||||
* @returns {Promise}
|
||||
* @returns {Promise<object>} ACME directory contents
|
||||
*/
|
||||
|
||||
async getDirectory() {
|
||||
if (!this.directory) {
|
||||
const age = (Math.floor(Date.now() / 1000) - this.directoryTimestamp);
|
||||
|
||||
if (!this.directoryCache || (age > this.directoryMaxAge)) {
|
||||
const resp = await this.request(this.directoryUrl, 'get');
|
||||
|
||||
if (resp.status >= 400) {
|
||||
@@ -89,8 +106,10 @@ class HttpClient {
|
||||
throw new Error('Attempting to read ACME directory returned no data');
|
||||
}
|
||||
|
||||
this.directory = resp.data;
|
||||
this.directoryCache = resp.data;
|
||||
}
|
||||
|
||||
return this.directoryCache;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,13 +153,13 @@ class HttpClient {
|
||||
*/
|
||||
|
||||
async getResourceUrl(resource) {
|
||||
await this.getDirectory();
|
||||
const dir = await this.getDirectory();
|
||||
|
||||
if (!this.directory[resource]) {
|
||||
if (!dir[resource]) {
|
||||
throw new Error(`Unable to locate API resource URL in ACME directory: "${resource}"`);
|
||||
}
|
||||
|
||||
return this.directory[resource];
|
||||
return dir[resource];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,10 +170,10 @@ class HttpClient {
|
||||
*/
|
||||
|
||||
async getMetaField(field) {
|
||||
await this.getDirectory();
|
||||
const dir = await this.getDirectory();
|
||||
|
||||
if (('meta' in this.directory) && (field in this.directory.meta)) {
|
||||
return this.directory.meta[field];
|
||||
if (('meta' in dir) && (field in dir.meta)) {
|
||||
return dir.meta[field];
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -13,11 +13,16 @@ exports.directory = {
|
||||
staging: 'https://api.test4.buypass.no/acme/directory',
|
||||
production: 'https://api.buypass.com/acme/directory',
|
||||
},
|
||||
google: {
|
||||
staging: 'https://dv.acme-v02.test-api.pki.goog/directory',
|
||||
production: 'https://dv.acme-v02.api.pki.goog/directory',
|
||||
},
|
||||
letsencrypt: {
|
||||
staging: 'https://acme-staging-v02.api.letsencrypt.org/directory',
|
||||
production: 'https://acme-v02.api.letsencrypt.org/directory',
|
||||
},
|
||||
zerossl: {
|
||||
staging: 'https://acme.zerossl.com/v2/DV90',
|
||||
production: 'https://acme.zerossl.com/v2/DV90',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -414,7 +414,7 @@ describe('client.auto', () => {
|
||||
const info = acme.crypto.readCertificateInfo(testCertificate);
|
||||
|
||||
spec.crypto.certificateInfo(info);
|
||||
assert.strictEqual(info.domains.commonName, testDomain);
|
||||
assert.isNull(info.domains.commonName);
|
||||
assert.deepStrictEqual(info.domains.altNames, [testDomain]);
|
||||
});
|
||||
|
||||
@@ -422,7 +422,7 @@ describe('client.auto', () => {
|
||||
const info = acme.crypto.readCertificateInfo(testSanCertificate);
|
||||
|
||||
spec.crypto.certificateInfo(info);
|
||||
assert.strictEqual(info.domains.commonName, testSanDomains[0]);
|
||||
assert.isNull(info.domains.commonName);
|
||||
assert.deepStrictEqual(info.domains.altNames, testSanDomains);
|
||||
});
|
||||
|
||||
@@ -430,7 +430,7 @@ describe('client.auto', () => {
|
||||
const info = acme.crypto.readCertificateInfo(testWildcardCertificate);
|
||||
|
||||
spec.crypto.certificateInfo(info);
|
||||
assert.strictEqual(info.domains.commonName, testWildcardDomain);
|
||||
assert.isNull(info.domains.commonName);
|
||||
assert.deepStrictEqual(info.domains.altNames, [testWildcardDomain, `*.${testWildcardDomain}`]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": ["es6"],
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"noEmit": false,
|
||||
"esModuleInterop": true,
|
||||
"baseUrl": ".",
|
||||
"composite": true,
|
||||
"paths": { "acme-client": ["."] }
|
||||
}
|
||||
}
|
||||
|
||||
11
packages/core/acme-client/types/index.d.ts
vendored
11
packages/core/acme-client/types/index.d.ts
vendored
@@ -27,6 +27,11 @@ export interface Authorization extends rfc8555.Authorization {
|
||||
url: string;
|
||||
}
|
||||
|
||||
export type UrlMapping={
|
||||
enabled: boolean
|
||||
mappings: Record<string, string>
|
||||
}
|
||||
|
||||
/**
|
||||
* Client
|
||||
*/
|
||||
@@ -39,6 +44,7 @@ export interface ClientOptions {
|
||||
backoffAttempts?: number;
|
||||
backoffMin?: number;
|
||||
backoffMax?: number;
|
||||
urlMapping?: UrlMapping;
|
||||
}
|
||||
|
||||
export interface ClientExternalAccountBindingOptions {
|
||||
@@ -87,11 +93,16 @@ export const directory: {
|
||||
staging: string,
|
||||
production: string
|
||||
},
|
||||
google: {
|
||||
staging: string,
|
||||
production: string
|
||||
},
|
||||
letsencrypt: {
|
||||
staging: string,
|
||||
production: string
|
||||
},
|
||||
zerossl: {
|
||||
staging: string,
|
||||
production: string
|
||||
}
|
||||
};
|
||||
|
||||
2
packages/core/pipeline/.gitignore
vendored
2
packages/core/pipeline/.gitignore
vendored
@@ -23,4 +23,4 @@ dist-ssr
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
test/user.secret.ts
|
||||
test/user.secret.*
|
||||
|
||||
2
packages/core/pipeline/.npmrc
Normal file
2
packages/core/pipeline/.npmrc
Normal file
@@ -0,0 +1,2 @@
|
||||
link-workspace-packages=true
|
||||
prefer-workspace-packages=true
|
||||
@@ -3,6 +3,44 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.22.5](https://github.com/certd/certd/compare/v1.22.4...v1.22.5) (2024-07-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.22.3](https://github.com/certd/certd/compare/v1.22.2...v1.22.3) (2024-07-25)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.22.2](https://github.com/certd/certd/compare/v1.22.1...v1.22.2) (2024-07-23)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.22.1](https://github.com/certd/certd/compare/v1.22.0...v1.22.1) (2024-07-20)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 创建证书任务可以选择lege插件 ([affef13](https://github.com/certd/certd/commit/affef130378030c517250c58a4e787b0fc85d7d1))
|
||||
|
||||
# [1.22.0](https://github.com/certd/certd/compare/v1.21.2...v1.22.0) (2024-07-19)
|
||||
|
||||
### Features
|
||||
|
||||
* 升级midway,支持esm ([485e603](https://github.com/certd/certd/commit/485e603b5165c28bc08694997726eaf2a585ebe7))
|
||||
* 支持lego,海量DNS提供商 ([0bc6d0a](https://github.com/certd/certd/commit/0bc6d0a211920fb0084d705e1db67ee1e7262c44))
|
||||
* 支持postgresql ([3b19bfb](https://github.com/certd/certd/commit/3b19bfb4291e89064b3b407a80dae092d54747d5))
|
||||
|
||||
## [1.21.2](https://github.com/certd/certd/compare/v1.21.1...v1.21.2) (2024-07-08)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.21.1](https://github.com/certd/certd/compare/v1.21.0...v1.21.1) (2024-07-08)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
# [1.21.0](https://github.com/certd/certd/compare/v1.20.17...v1.21.0) (2024-07-03)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.20.17](https://github.com/certd/certd/compare/v1.20.16...v1.20.17) (2024-07-03)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
1
packages/core/pipeline/build.md
Normal file
1
packages/core/pipeline/build.md
Normal file
@@ -0,0 +1 @@
|
||||
23:14
|
||||
96
packages/core/pipeline/fix-esm-import-paths.js
Normal file
96
packages/core/pipeline/fix-esm-import-paths.js
Normal file
@@ -0,0 +1,96 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
// https://gist.github.com/lovasoa/8691344
|
||||
async function* walk(dir) {
|
||||
for await (const d of await fs.promises.opendir(dir)) {
|
||||
const entry = path.join(dir, d.name);
|
||||
if (d.isDirectory()) {
|
||||
yield* walk(entry);
|
||||
} else if (d.isFile()) {
|
||||
yield entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resolveImportPath(sourceFile, importPath, options) {
|
||||
const sourceFileAbs = path.resolve(process.cwd(), sourceFile);
|
||||
const root = path.dirname(sourceFileAbs);
|
||||
const { moduleFilter = defaultModuleFilter } = options;
|
||||
|
||||
if (moduleFilter(importPath)) {
|
||||
const importPathAbs = path.resolve(root, importPath);
|
||||
let possiblePath = [path.resolve(importPathAbs, "./index.ts"), path.resolve(importPathAbs, "./index.js"), importPathAbs + ".ts", importPathAbs + ".js"];
|
||||
|
||||
if (possiblePath.length) {
|
||||
for (let i = 0; i < possiblePath.length; i++) {
|
||||
let entry = possiblePath[i];
|
||||
if (fs.existsSync(entry)) {
|
||||
const resolved = path.relative(root, entry.replace(/\.ts$/, ".js"));
|
||||
|
||||
if (!resolved.startsWith(".")) {
|
||||
return "./" + resolved;
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function replace(filePath, outFilePath, options) {
|
||||
const code = fs.readFileSync(filePath).toString();
|
||||
const newCode = code.replace(/(import|export) (.+?) from ('[^\n']+'|"[^\n"]+");/gs, function (found, action, imported, from) {
|
||||
const importPath = from.slice(1, -1);
|
||||
let resolvedPath = resolveImportPath(filePath, importPath, options);
|
||||
|
||||
if (resolvedPath) {
|
||||
resolvedPath = resolvedPath.replaceAll("\\", "/");
|
||||
console.log("\t", importPath, resolvedPath);
|
||||
return `${action} ${imported} from "${resolvedPath}";`;
|
||||
}
|
||||
|
||||
return found;
|
||||
});
|
||||
|
||||
if (code !== newCode) {
|
||||
fs.writeFileSync(outFilePath, newCode);
|
||||
}
|
||||
}
|
||||
|
||||
// Then, use it with a simple async for loop
|
||||
async function run(srcDir, options = defaultOptions) {
|
||||
const { sourceFileFilter = defaultSourceFileFilter } = options;
|
||||
|
||||
for await (const entry of walk(srcDir)) {
|
||||
if (sourceFileFilter(entry)) {
|
||||
console.log(entry);
|
||||
replace(entry, entry, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const defaultSourceFileFilter = function (sourceFilePath) {
|
||||
return /\.(js|ts)$/.test(sourceFilePath) && !/node_modules/.test(sourceFilePath);
|
||||
};
|
||||
|
||||
const defaultModuleFilter = function (importedModule) {
|
||||
return !path.isAbsolute(importedModule) && !importedModule.startsWith("@") && !importedModule.endsWith(".js");
|
||||
};
|
||||
|
||||
const defaultOptions = {
|
||||
sourceFileFilter: defaultSourceFileFilter,
|
||||
moduleFilter: defaultModuleFilter,
|
||||
};
|
||||
|
||||
// Switch this to test on one file or directly run on a directory.
|
||||
const DEBUG = false;
|
||||
|
||||
if (DEBUG) {
|
||||
replace("./src/index.ts", "./out.ts", defaultOptions);
|
||||
} else {
|
||||
await run("./src/", defaultOptions);
|
||||
}
|
||||
@@ -1,49 +1,46 @@
|
||||
{
|
||||
"name": "@certd/pipeline",
|
||||
"private": false,
|
||||
"version": "1.20.17",
|
||||
"main": "./src/index.ts",
|
||||
"module": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"publishConfig": {
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.mjs",
|
||||
"types": "./dist/d/index.d.ts"
|
||||
},
|
||||
"version": "1.22.5",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "rollup -c",
|
||||
"build": "tsc --skipLibCheck",
|
||||
"build3": "rollup -c",
|
||||
"build2": "vue-tsc --noEmit && vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.4.0",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"axios": "^1.7.2",
|
||||
"fix-path": "^4.0.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"node-forge": "^1.3.1",
|
||||
"nodemailer": "^6.9.3",
|
||||
"qs": "^6.11.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/acme-client": "workspace:^1.20.17",
|
||||
"@rollup/plugin-commonjs": "^23.0.4",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@rollup/plugin-terser": "^0.4.3",
|
||||
"@rollup/plugin-typescript": "^11.0.0",
|
||||
"@types/chai": "^4.3.5",
|
||||
"@types/lodash": "^4.14.194",
|
||||
"@types/chai": "^4.3.10",
|
||||
"@types/mocha": "^10.0.1",
|
||||
"@types/node-forge": "^1.3.2",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.7",
|
||||
"@typescript-eslint/parser": "^5.59.7",
|
||||
"chai": "^4.3.7",
|
||||
"chai": "4.3.10",
|
||||
"dayjs": "^1.11.7",
|
||||
"eslint": "^8.41.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"lodash": "^4.17.21",
|
||||
"iconv-lite": "^0.6.3",
|
||||
"log4js": "^6.9.1",
|
||||
"mocha": "^10.2.0",
|
||||
"prettier": "^2.8.8",
|
||||
@@ -52,10 +49,11 @@
|
||||
"rollup-plugin-typescript2": "^0.34.1",
|
||||
"rollup-plugin-visualizer": "^5.8.2",
|
||||
"ts-node": "^10.9.1",
|
||||
"tsc-esm-fix": "^3.0.0",
|
||||
"tslib": "^2.5.2",
|
||||
"typescript": "^5.0.4",
|
||||
"vite": "^4.3.8",
|
||||
"vue-tsc": "^1.6.5"
|
||||
},
|
||||
"gitHead": "a31f1c7f5e71fa946de9bf0283e11d6ce049b3e9"
|
||||
"gitHead": "e5da46cfc31b2e30a4903bcb2251b1851265ef41"
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
const resolve = require("@rollup/plugin-node-resolve");
|
||||
const commonjs = require("@rollup/plugin-commonjs");
|
||||
//const Typescript = require("rollup-plugin-typescript2");
|
||||
const Typescript = require("@rollup/plugin-typescript");
|
||||
const json = require("@rollup/plugin-json");
|
||||
const terser = require("@rollup/plugin-terser");
|
||||
module.exports = {
|
||||
input: "src/index.ts",
|
||||
output: {
|
||||
file: "dist/bundle.js",
|
||||
format: "cjs",
|
||||
},
|
||||
plugins: [
|
||||
// 解析第三方依赖
|
||||
resolve(),
|
||||
// 识别 commonjs 模式第三方依赖
|
||||
commonjs(),
|
||||
Typescript({
|
||||
target: "esnext",
|
||||
rootDir: "src",
|
||||
declaration: true,
|
||||
declarationDir: "dist/d",
|
||||
exclude: ["./node_modules/**", "./src/**/*.vue"],
|
||||
allowSyntheticDefaultImports: true,
|
||||
}),
|
||||
json(),
|
||||
terser(),
|
||||
],
|
||||
external: [
|
||||
"vue",
|
||||
"lodash",
|
||||
"dayjs",
|
||||
"@certd/acme-client",
|
||||
"@certd/pipeline",
|
||||
"@certd/plugin-cert",
|
||||
"@certd/plugin-aliyun",
|
||||
"@certd/plugin-tencent",
|
||||
"@certd/plugin-huawei",
|
||||
"@certd/plugin-host",
|
||||
"@certd/plugin-tencent",
|
||||
"@certd/plugin-util",
|
||||
],
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Registrable } from "../registry";
|
||||
import { FormItemProps } from "../d.ts";
|
||||
import { Registrable } from "../registry/index.js";
|
||||
import { FormItemProps } from "../dt/index.js";
|
||||
|
||||
export type AccessInputDefine = FormItemProps & {
|
||||
title: string;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// src/decorator/memoryCache.decorator.ts
|
||||
import { AccessDefine, AccessInputDefine } from "./api";
|
||||
import { Decorator } from "../decorator";
|
||||
import _ from "lodash";
|
||||
import { accessRegistry } from "./registry";
|
||||
import { AccessDefine, AccessInputDefine } from "./api.js";
|
||||
import { Decorator } from "../decorator/index.js";
|
||||
import _ from "lodash-es";
|
||||
import { accessRegistry } from "./registry.js";
|
||||
|
||||
// 提供一个唯一 key
|
||||
export const ACCESS_CLASS_KEY = "pipeline:access";
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export * from "./api";
|
||||
export * from "./registry";
|
||||
export * from "./decorator";
|
||||
export * from "./api.js";
|
||||
export * from "./registry.js";
|
||||
export * from "./decorator.js";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Registry } from "../registry";
|
||||
import { Registry } from "../registry/index.js";
|
||||
|
||||
// @ts-ignore
|
||||
export const accessRegistry = new Registry("access");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AxiosInstance } from "axios";
|
||||
import { IContext } from "../core";
|
||||
import { IContext } from "../core/index.js";
|
||||
|
||||
export type HttpClient = AxiosInstance;
|
||||
export type UserContext = IContext;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { IStorage, MemoryStorage } from "./storage";
|
||||
import { IStorage, MemoryStorage } from "./storage.js";
|
||||
|
||||
const CONTEXT_VERSION_KEY = "contextVersion";
|
||||
export interface IContext {
|
||||
getInt(key: string): Promise<number>;
|
||||
@@ -20,13 +21,11 @@ export class ContextFactory {
|
||||
}
|
||||
|
||||
getContext(scope: string, namespace: string): IContext {
|
||||
const context = new StorageContext(scope, namespace, this.storage);
|
||||
return context;
|
||||
return new StorageContext(scope, namespace, this.storage);
|
||||
}
|
||||
|
||||
getMemoryContext(scope: string, namespace: string): IContext {
|
||||
const context = new StorageContext(scope, namespace, this.memoryStorage);
|
||||
return context;
|
||||
return new StorageContext(scope, namespace, this.memoryStorage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { ConcurrencyStrategy, NotificationWhen, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task } from "../d.ts";
|
||||
import _ from "lodash";
|
||||
import { RunHistory, RunnableCollection } from "./run-history";
|
||||
import { AbstractTaskPlugin, PluginDefine, pluginRegistry, TaskInstanceContext } from "../plugin";
|
||||
import { ContextFactory, IContext } from "./context";
|
||||
import { IStorage } from "./storage";
|
||||
import { logger } from "../utils/util.log";
|
||||
import { ConcurrencyStrategy, NotificationWhen, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task } from "../dt/index.js";
|
||||
import _ from "lodash-es";
|
||||
import { RunHistory, RunnableCollection } from "./run-history.js";
|
||||
import { AbstractTaskPlugin, PluginDefine, pluginRegistry, TaskInstanceContext } from "../plugin/index.js";
|
||||
import { ContextFactory, IContext } from "./context.js";
|
||||
import { IStorage } from "./storage.js";
|
||||
import { logger } from "../utils/util.log.js";
|
||||
import { Logger } from "log4js";
|
||||
import { createAxiosService } from "../utils/util.request";
|
||||
import { IAccessService } from "../access";
|
||||
import { RegistryItem } from "../registry";
|
||||
import { Decorator } from "../decorator";
|
||||
import { IEmailService } from "../service";
|
||||
import { FileStore } from "./file-store";
|
||||
import { TimeoutPromise } from "../utils/util.promise";
|
||||
import { createAxiosService } from "../utils/util.request.js";
|
||||
import { IAccessService } from "../access/index.js";
|
||||
import { RegistryItem } from "../registry/index.js";
|
||||
import { Decorator } from "../decorator/index.js";
|
||||
import { IEmailService } from "../service/index.js";
|
||||
import { FileStore } from "./file-store.js";
|
||||
// import { TimeoutPromise } from "../utils/util.promise.js";
|
||||
|
||||
export type ExecutorOptions = {
|
||||
userId: any;
|
||||
@@ -33,7 +33,7 @@ export class Executor {
|
||||
lastRuntime!: RunHistory;
|
||||
options: ExecutorOptions;
|
||||
canceled = false;
|
||||
onChanged: (history: RunHistory) => void;
|
||||
onChanged: (history: RunHistory) => Promise<void>;
|
||||
constructor(options: ExecutorOptions) {
|
||||
this.options = options;
|
||||
this.pipeline = _.cloneDeep(options.pipeline);
|
||||
@@ -110,12 +110,13 @@ export class Executor {
|
||||
const intervalFlushLogId = setInterval(async () => {
|
||||
await this.onChanged(this.runtime);
|
||||
}, 5000);
|
||||
const timeout = runnable.timeout ?? 20 * 60 * 1000;
|
||||
|
||||
// const timeout = runnable.timeout ?? 20 * 60 * 1000;
|
||||
try {
|
||||
if (this.canceled) {
|
||||
throw new Error("task canceled");
|
||||
return ResultType.canceled;
|
||||
}
|
||||
await TimeoutPromise(run, timeout);
|
||||
await run();
|
||||
this.runtime.success(runnable);
|
||||
return ResultType.success;
|
||||
} catch (e: any) {
|
||||
@@ -142,19 +143,25 @@ export class Executor {
|
||||
async runStage(stage: Stage) {
|
||||
const runnerList = [];
|
||||
for (const task of stage.tasks) {
|
||||
const runner = this.runWithHistory(task, "task", async () => {
|
||||
await this.runTask(task);
|
||||
});
|
||||
const runner = async () => {
|
||||
return this.runWithHistory(task, "task", async () => {
|
||||
await this.runTask(task);
|
||||
});
|
||||
};
|
||||
runnerList.push(runner);
|
||||
}
|
||||
|
||||
let resList: ResultType[] = [];
|
||||
if (stage.concurrency === ConcurrencyStrategy.Parallel) {
|
||||
resList = await Promise.all(runnerList);
|
||||
const pList = [];
|
||||
for (const item of runnerList) {
|
||||
pList.push(item());
|
||||
}
|
||||
resList = await Promise.all(pList);
|
||||
} else {
|
||||
for (let i = 0; i < runnerList.length; i++) {
|
||||
const runner = runnerList[i];
|
||||
resList[i] = await runner;
|
||||
resList[i] = await runner();
|
||||
}
|
||||
}
|
||||
return this.compositionResultType(resList);
|
||||
@@ -239,7 +246,7 @@ export class Executor {
|
||||
this.lastStatusMap.clear();
|
||||
}
|
||||
//输出到output context
|
||||
_.forEach(define.output, (item, key) => {
|
||||
_.forEach(define.output, (item: any, key: any) => {
|
||||
step.status!.output[key] = instance[key];
|
||||
const stepOutputKey = `step.${step.id}.${key}`;
|
||||
this.runtime.context[stepOutputKey] = instance[key];
|
||||
@@ -275,12 +282,16 @@ export class Executor {
|
||||
continue;
|
||||
}
|
||||
if (notification.type === "email") {
|
||||
this.options.emailService?.send({
|
||||
userId: this.pipeline.userId,
|
||||
subject,
|
||||
content,
|
||||
receivers: notification.options.receivers,
|
||||
});
|
||||
try {
|
||||
await this.options.emailService?.send({
|
||||
userId: this.pipeline.userId,
|
||||
subject,
|
||||
content,
|
||||
receivers: notification.options.receivers,
|
||||
});
|
||||
} catch (e) {
|
||||
logger.error("send email error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { fileUtils } from "../utils";
|
||||
import { fileUtils } from "../utils/index.js";
|
||||
import dayjs from "dayjs";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import { logger } from "../utils";
|
||||
import { logger } from "../utils/index.js";
|
||||
|
||||
export type FileStoreOptions = {
|
||||
rootDir?: string;
|
||||
@@ -10,6 +10,12 @@ export type FileStoreOptions = {
|
||||
parent: string;
|
||||
};
|
||||
|
||||
export interface IFileStore {
|
||||
readFile(filePath: string): Buffer | null;
|
||||
writeFile(filename: string, file: Buffer): string;
|
||||
deleteByParent(scope: string, parent: string): void;
|
||||
}
|
||||
|
||||
export class FileStore {
|
||||
rootDir: string;
|
||||
scope: string;
|
||||
@@ -35,7 +41,7 @@ export class FileStore {
|
||||
return localPath;
|
||||
}
|
||||
|
||||
private buildFilePath(filename: string) {
|
||||
protected buildFilePath(filename: string) {
|
||||
const parentDir = path.join(this.rootDir, this.scope + "", this.parent + "", dayjs().format("YYYY-MM-DD"));
|
||||
if (!fs.existsSync(parentDir)) {
|
||||
fs.mkdirSync(parentDir, { recursive: true });
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export * from "./executor";
|
||||
export * from "./run-history";
|
||||
export * from "./context";
|
||||
export * from "./storage";
|
||||
export * from "./file-store";
|
||||
export * from "./executor.js";
|
||||
export * from "./run-history.js";
|
||||
export * from "./context.js";
|
||||
export * from "./storage.js";
|
||||
export * from "./file-store.js";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Context, HistoryResult, Pipeline, ResultType, Runnable, RunnableMap, Stage, Step, Task } from "../d.ts";
|
||||
import _ from "lodash";
|
||||
import { buildLogger } from "../utils/util.log";
|
||||
import { Context, HistoryResult, Pipeline, ResultType, Runnable, RunnableMap, Stage, Step, Task } from "../dt/index.js";
|
||||
import _ from "lodash-es";
|
||||
import { buildLogger } from "../utils/util.log.js";
|
||||
import { Logger } from "log4js";
|
||||
|
||||
export type HistoryStatus = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { fileUtils } from "../utils/util.file";
|
||||
import { fileUtils } from "../utils/util.file.js";
|
||||
|
||||
export interface IStorage {
|
||||
get(scope: string, namespace: string, version: string, key: string): Promise<string | null>;
|
||||
|
||||
@@ -70,6 +70,7 @@ export type Runnable = {
|
||||
default?: {
|
||||
[key: string]: any;
|
||||
};
|
||||
context?: Context;
|
||||
};
|
||||
|
||||
export type EmailOptions = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Decorator } from "./index";
|
||||
import { Decorator } from "./index.js";
|
||||
|
||||
export type AutowireProp = {
|
||||
name?: string;
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from "./utils";
|
||||
export * from "./common";
|
||||
export * from "./utils.js";
|
||||
export * from "./common.js";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _ from "lodash";
|
||||
import _ from "lodash-es";
|
||||
|
||||
const propertyMap: any = {};
|
||||
function attachProperty(target: any, propertyKey: string | symbol) {
|
||||
@@ -11,7 +11,11 @@ function attachProperty(target: any, propertyKey: string | symbol) {
|
||||
}
|
||||
|
||||
function getClassProperties(target: any) {
|
||||
return propertyMap[target] || {};
|
||||
//获取父类
|
||||
const parent = Object.getPrototypeOf(target);
|
||||
const parentMap = propertyMap[parent] || {};
|
||||
const current = propertyMap[target] || {};
|
||||
return _.merge({}, parentMap, current);
|
||||
}
|
||||
|
||||
function target(target: any, propertyKey?: string | symbol) {
|
||||
@@ -25,7 +29,7 @@ function target(target: any, propertyKey?: string | symbol) {
|
||||
}
|
||||
|
||||
function inject(define: any, instance: any, context: any, preHandler?: (item: any, key: string, instance: any, context: any) => void) {
|
||||
_.forEach(define, (item, key) => {
|
||||
_.forEach(define, (item: any, key: any) => {
|
||||
if (preHandler) {
|
||||
preHandler(item, key, instance, context);
|
||||
}
|
||||
|
||||
115
packages/core/pipeline/src/dt/fast-crud.ts
Normal file
115
packages/core/pipeline/src/dt/fast-crud.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* [x]-col的配置
|
||||
*/
|
||||
export type ColProps = {
|
||||
span?: number;
|
||||
[props: string]: any;
|
||||
};
|
||||
|
||||
export type FormItemProps = {
|
||||
/**
|
||||
* 字段label
|
||||
*/
|
||||
title?: string;
|
||||
/**
|
||||
* 表单字段组件配置
|
||||
*/
|
||||
component?: ComponentProps;
|
||||
/**
|
||||
* 表单字段 [a|el|n]-col的配置
|
||||
* 一般用来配置跨列:{span:24} 占满一行
|
||||
*/
|
||||
col?: ColProps;
|
||||
/**
|
||||
* 默认值
|
||||
*/
|
||||
value?: any;
|
||||
/**
|
||||
* 帮助提示配置
|
||||
*/
|
||||
helper?: string | FormItemHelperProps;
|
||||
/**
|
||||
* 排序号
|
||||
*/
|
||||
order?: number;
|
||||
/**
|
||||
* 是否显示此字段
|
||||
*/
|
||||
show?: boolean;
|
||||
/**
|
||||
* 是否是空白占位栏
|
||||
*/
|
||||
blank?: boolean;
|
||||
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
/**
|
||||
* 表单字段帮助说明配置
|
||||
*/
|
||||
export type FormItemHelperProps = {
|
||||
/**
|
||||
* 自定义渲染帮助说明
|
||||
* @param scope
|
||||
*/
|
||||
render?: (scope: any) => any;
|
||||
/**
|
||||
* 帮助文本
|
||||
*/
|
||||
text?: string;
|
||||
/**
|
||||
* 帮助说明所在的位置,[ undefined | label]
|
||||
*/
|
||||
position?: string;
|
||||
/**
|
||||
* [a|el|n]-tooltip配置
|
||||
*/
|
||||
tooltip?: object;
|
||||
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
/**
|
||||
* 组件配置
|
||||
*/
|
||||
export type ComponentProps = {
|
||||
/**
|
||||
* 组件的名称
|
||||
*/
|
||||
name?: string | object;
|
||||
/**
|
||||
* vmodel绑定的目标属性名
|
||||
*/
|
||||
vModel?: string;
|
||||
|
||||
/**
|
||||
* 当原始组件名的参数被以上属性名占用时,可以配置在这里
|
||||
* 例如:原始组件有一个叫name的属性,你想要配置它,则可以按如下配置
|
||||
* ```
|
||||
* component:{
|
||||
* name:"组件的名称"
|
||||
* props:{
|
||||
* name:"组件的name属性" <-----------
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
props?: {
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
/**
|
||||
* 组件事件监听
|
||||
*/
|
||||
on?: {
|
||||
[key: string]: (context?: any) => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* 组件其他参数
|
||||
* 事件:onXxx:(event)=>void 组件原始事件监听
|
||||
* on.onXxx:(context)=>void 组件事件监听(对原始事件包装)
|
||||
* 样式:style、class等
|
||||
*/
|
||||
[key: string]: any;
|
||||
};
|
||||
2
packages/core/pipeline/src/dt/index.ts
Normal file
2
packages/core/pipeline/src/dt/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./pipeline.js";
|
||||
export * from "./fast-crud.js";
|
||||
139
packages/core/pipeline/src/dt/pipeline.ts
Normal file
139
packages/core/pipeline/src/dt/pipeline.ts
Normal file
@@ -0,0 +1,139 @@
|
||||
export enum RunStrategy {
|
||||
AlwaysRun,
|
||||
SkipWhenSucceed,
|
||||
}
|
||||
|
||||
export enum ConcurrencyStrategy {
|
||||
Serial,
|
||||
Parallel,
|
||||
}
|
||||
|
||||
export enum NextStrategy {
|
||||
AllSuccess,
|
||||
OneSuccess,
|
||||
}
|
||||
|
||||
export enum HandlerType {
|
||||
//清空后续任务的状态
|
||||
ClearFollowStatus,
|
||||
SendEmail,
|
||||
}
|
||||
|
||||
export type EventHandler = {
|
||||
type: HandlerType;
|
||||
params: {
|
||||
[key: string]: any;
|
||||
};
|
||||
};
|
||||
|
||||
export type RunnableStrategy = {
|
||||
runStrategy?: RunStrategy;
|
||||
onSuccess?: EventHandler[];
|
||||
onError?: EventHandler[];
|
||||
};
|
||||
|
||||
export type Step = Runnable & {
|
||||
type: string; //插件类型
|
||||
input: {
|
||||
[key: string]: any;
|
||||
};
|
||||
};
|
||||
export type Task = Runnable & {
|
||||
steps: Step[];
|
||||
};
|
||||
|
||||
export type Stage = Runnable & {
|
||||
tasks: Task[];
|
||||
concurrency: ConcurrencyStrategy;
|
||||
next: NextStrategy;
|
||||
};
|
||||
|
||||
export type Trigger = {
|
||||
id: string;
|
||||
title: string;
|
||||
cron: string;
|
||||
type: string;
|
||||
};
|
||||
|
||||
export type FileItem = {
|
||||
id: string;
|
||||
filename: string;
|
||||
path: string;
|
||||
};
|
||||
export type Runnable = {
|
||||
id: string;
|
||||
title: string;
|
||||
strategy?: RunnableStrategy;
|
||||
runnableType?: string; // pipeline, stage, task , step
|
||||
status?: HistoryResult;
|
||||
timeout?: number;
|
||||
default?: {
|
||||
[key: string]: any;
|
||||
};
|
||||
};
|
||||
|
||||
export type EmailOptions = {
|
||||
receivers: string[];
|
||||
};
|
||||
export type NotificationWhen = "error" | "success" | "turnToSuccess" | "start";
|
||||
export type NotificationType = "email" | "url";
|
||||
export type Notification = {
|
||||
type: NotificationType;
|
||||
when: NotificationWhen[];
|
||||
options: EmailOptions;
|
||||
};
|
||||
|
||||
export type Pipeline = Runnable & {
|
||||
version?: number;
|
||||
userId: any;
|
||||
stages: Stage[];
|
||||
triggers: Trigger[];
|
||||
notifications?: Notification[];
|
||||
};
|
||||
|
||||
export type Context = {
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
export type Log = {
|
||||
title: string;
|
||||
time: number;
|
||||
level: string;
|
||||
text: string;
|
||||
};
|
||||
|
||||
export enum ResultType {
|
||||
start = "start",
|
||||
success = "success",
|
||||
error = "error",
|
||||
canceled = "canceled",
|
||||
skip = "skip",
|
||||
none = "none",
|
||||
}
|
||||
|
||||
export type HistoryResultGroup = {
|
||||
[key: string]: {
|
||||
runnable: Runnable;
|
||||
res: HistoryResult;
|
||||
};
|
||||
};
|
||||
export type HistoryResult = {
|
||||
input: any;
|
||||
output: any;
|
||||
files?: FileItem[];
|
||||
/**
|
||||
* 任务状态
|
||||
*/
|
||||
status: ResultType;
|
||||
startTime: number;
|
||||
endTime?: number;
|
||||
/**
|
||||
* 处理结果
|
||||
*/
|
||||
result?: ResultType; //success, error,skip
|
||||
message?: string;
|
||||
};
|
||||
|
||||
export type RunnableMap = {
|
||||
[id: string]: Runnable;
|
||||
};
|
||||
@@ -1,10 +1,10 @@
|
||||
import "util";
|
||||
export * from "./core";
|
||||
export * from "./d.ts";
|
||||
export * from "./access";
|
||||
export * from "./registry";
|
||||
export * from "./plugin";
|
||||
export * from "./utils";
|
||||
export * from "./context";
|
||||
export * from "./decorator";
|
||||
export * from "./service";
|
||||
export * from "./core/index.js";
|
||||
export * from "./dt/index.js";
|
||||
export * from "./access/index.js";
|
||||
export * from "./registry/index.js";
|
||||
export * from "./plugin/index.js";
|
||||
export * from "./utils/index.js";
|
||||
export * from "./context/index.js";
|
||||
export * from "./decorator/index.js";
|
||||
export * from "./service/index.js";
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Registrable } from "../registry";
|
||||
import { FileItem, FormItemProps, Pipeline, Runnable, Step } from "../d.ts";
|
||||
import { FileStore } from "../core/file-store";
|
||||
import { Registrable } from "../registry/index.js";
|
||||
import { FileItem, FormItemProps, Pipeline, Runnable, Step } from "../dt/index.js";
|
||||
import { FileStore } from "../core/file-store.js";
|
||||
import { Logger } from "log4js";
|
||||
import { IAccessService } from "../access";
|
||||
import { IEmailService } from "../service";
|
||||
import { IContext } from "../core";
|
||||
import { IAccessService } from "../access/index.js";
|
||||
import { IEmailService } from "../service/index.js";
|
||||
import { IContext } from "../core/index.js";
|
||||
import { AxiosInstance } from "axios";
|
||||
import { logger } from "../utils";
|
||||
import { logger } from "../utils/index.js";
|
||||
|
||||
export enum ContextScope {
|
||||
global,
|
||||
@@ -23,6 +23,7 @@ export type TaskInputDefine = FormItemProps;
|
||||
|
||||
export type PluginDefine = Registrable & {
|
||||
default?: any;
|
||||
group?: string;
|
||||
input?: {
|
||||
[key: string]: TaskInputDefine;
|
||||
};
|
||||
@@ -83,7 +84,7 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
||||
return Math.random().toString(36).substring(2, 9);
|
||||
}
|
||||
linkFile(file: FileItem) {
|
||||
this._result.files!.push({
|
||||
this._result.files?.push({
|
||||
...file,
|
||||
id: this.randomFileId(),
|
||||
});
|
||||
@@ -91,13 +92,20 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
||||
saveFile(filename: string, file: Buffer) {
|
||||
const filePath = this.ctx.fileStore.writeFile(filename, file);
|
||||
logger.info(`saveFile:${filePath}`);
|
||||
this._result.files!.push({
|
||||
this._result.files?.push({
|
||||
id: this.randomFileId(),
|
||||
filename,
|
||||
path: filePath,
|
||||
});
|
||||
}
|
||||
|
||||
extendsFiles() {
|
||||
if (this._result.files == null) {
|
||||
this._result.files = [];
|
||||
}
|
||||
this._result.files.push(...(this.ctx.lastStatus?.status?.files || []));
|
||||
}
|
||||
|
||||
get pipeline() {
|
||||
return this.ctx.pipeline;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import _ from "lodash";
|
||||
import { pluginRegistry } from "./registry";
|
||||
import { PluginDefine, TaskInputDefine, TaskOutputDefine } from "./api";
|
||||
import { Decorator } from "../decorator";
|
||||
import { AUTOWIRE_KEY } from "../decorator";
|
||||
import _ from "lodash-es";
|
||||
import { pluginRegistry } from "./registry.js";
|
||||
import { PluginDefine, TaskInputDefine, TaskOutputDefine } from "./api.js";
|
||||
import { Decorator } from "../decorator/index.js";
|
||||
import { AUTOWIRE_KEY } from "../decorator/index.js";
|
||||
import "reflect-metadata";
|
||||
// 提供一个唯一 key
|
||||
export const PLUGIN_CLASS_KEY = "pipeline:plugin";
|
||||
@@ -31,7 +31,24 @@ export function IsTaskPlugin(define: PluginDefine): ClassDecorator {
|
||||
outputs[property] = output;
|
||||
}
|
||||
}
|
||||
_.merge(define, { input: inputs, autowire: autowires, output: outputs });
|
||||
|
||||
// inputs 转换为array,根据order排序,然后再转换为map
|
||||
|
||||
let inputArray = [];
|
||||
for (const key in inputs) {
|
||||
const _input = inputs[key];
|
||||
if (_input.order == null) {
|
||||
_input.order = 0;
|
||||
}
|
||||
inputArray.push([key, _input]);
|
||||
}
|
||||
inputArray = _.sortBy(inputArray, (item: any) => item[1].order);
|
||||
const inputMap: any = {};
|
||||
inputArray.forEach((item: any) => {
|
||||
inputMap[item[0]] = item[1];
|
||||
});
|
||||
|
||||
_.merge(define, { input: inputMap, autowire: autowires, output: outputs });
|
||||
|
||||
Reflect.defineMetadata(PLUGIN_CLASS_KEY, define, target);
|
||||
|
||||
|
||||
25
packages/core/pipeline/src/plugin/group.ts
Normal file
25
packages/core/pipeline/src/plugin/group.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { PluginDefine } from "./api";
|
||||
|
||||
export class PluginGroup {
|
||||
key: string;
|
||||
title: string;
|
||||
desc?: string;
|
||||
order: number;
|
||||
plugins: PluginDefine[];
|
||||
constructor(key: string, title: string, order = 0, desc = "") {
|
||||
this.key = key;
|
||||
this.title = title;
|
||||
this.order = order;
|
||||
this.desc = desc;
|
||||
this.plugins = [];
|
||||
}
|
||||
}
|
||||
|
||||
export const pluginGroups = {
|
||||
cert: new PluginGroup("cert", "证书申请", 1),
|
||||
aliyun: new PluginGroup("aliyun", "阿里云", 2),
|
||||
huawei: new PluginGroup("huawei", "华为云", 3),
|
||||
tencent: new PluginGroup("tencent", "腾讯云", 4),
|
||||
host: new PluginGroup("host", "主机", 5),
|
||||
other: new PluginGroup("other", "其他", 7),
|
||||
};
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "./api";
|
||||
export * from "./registry";
|
||||
export * from "./decorator";
|
||||
export * from "./api.js";
|
||||
export * from "./registry.js";
|
||||
export * from "./decorator.js";
|
||||
export * from "./group.js";
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
import { Registry } from "../registry";
|
||||
import { AbstractTaskPlugin } from "./api";
|
||||
import { OnRegisterContext, Registry } from "../registry/index.js";
|
||||
import { AbstractTaskPlugin } from "./api.js";
|
||||
import { pluginGroups } from "./group.js";
|
||||
|
||||
export const pluginRegistry = new Registry<AbstractTaskPlugin>("plugin");
|
||||
const onRegister = ({ key, value }: OnRegisterContext<AbstractTaskPlugin>) => {
|
||||
const group = value?.define?.group as string;
|
||||
if (group) {
|
||||
if (pluginGroups.hasOwnProperty(group)) {
|
||||
// @ts-ignore
|
||||
pluginGroups[group].plugins.push(value.define);
|
||||
} else {
|
||||
pluginGroups.other.plugins.push(value.define);
|
||||
}
|
||||
}
|
||||
};
|
||||
export const pluginRegistry = new Registry<AbstractTaskPlugin>("plugin", onRegister);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ITaskPlugin } from "../api";
|
||||
import { IsTaskPlugin, TaskInput } from "../decorator";
|
||||
import { Autowire } from "../../decorator";
|
||||
import { ITaskPlugin } from "../api.js";
|
||||
import { IsTaskPlugin, TaskInput } from "../decorator.js";
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: "EchoPlugin",
|
||||
|
||||
@@ -1 +1 @@
|
||||
export * from "./registry";
|
||||
export * from "./registry.js";
|
||||
|
||||
@@ -1,23 +1,34 @@
|
||||
import { logger } from "../utils";
|
||||
import { logger } from "../utils/index.js";
|
||||
|
||||
export type Registrable = {
|
||||
name: string;
|
||||
title: string;
|
||||
desc?: string;
|
||||
group?: string;
|
||||
};
|
||||
|
||||
export type RegistryItem<T> = {
|
||||
define: Registrable;
|
||||
target: T;
|
||||
};
|
||||
|
||||
export type OnRegisterContext<T> = {
|
||||
registry: Registry<T>;
|
||||
key: string;
|
||||
value: RegistryItem<T>;
|
||||
};
|
||||
export type OnRegister<T> = (ctx: OnRegisterContext<T>) => void;
|
||||
export class Registry<T> {
|
||||
type = "";
|
||||
storage: {
|
||||
[key: string]: RegistryItem<T>;
|
||||
} = {};
|
||||
|
||||
constructor(type: string) {
|
||||
onRegister?: OnRegister<T>;
|
||||
|
||||
constructor(type: string, onRegister?: OnRegister<T>) {
|
||||
this.type = type;
|
||||
this.onRegister = onRegister;
|
||||
}
|
||||
|
||||
register(key: string, value: RegistryItem<T>) {
|
||||
@@ -25,6 +36,13 @@ export class Registry<T> {
|
||||
return;
|
||||
}
|
||||
this.storage[key] = value;
|
||||
if (this.onRegister) {
|
||||
this.onRegister({
|
||||
registry: this,
|
||||
key,
|
||||
value,
|
||||
});
|
||||
}
|
||||
logger.info(`注册插件:${this.type}:${key}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
export * from "./email";
|
||||
export * from "./email.js";
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import sleep from "./util.sleep";
|
||||
import { request } from "./util.request";
|
||||
export * from "./util.log";
|
||||
export * from "./util.file";
|
||||
import sleep from "./util.sleep.js";
|
||||
import { request } from "./util.request.js";
|
||||
export * from "./util.log.js";
|
||||
export * from "./util.file.js";
|
||||
export * from "./util.sp.js";
|
||||
export * as promises from "./util.promise.js";
|
||||
export const utils = {
|
||||
sleep,
|
||||
http: request,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { logger } from "./util.log.js";
|
||||
|
||||
export function TimeoutPromise(callback: () => Promise<void>, ms = 30 * 1000) {
|
||||
let timeout: any;
|
||||
return Promise.race([
|
||||
@@ -11,3 +13,14 @@ export function TimeoutPromise(callback: () => Promise<void>, ms = 30 * 1000) {
|
||||
clearTimeout(timeout);
|
||||
});
|
||||
}
|
||||
|
||||
export function safePromise<T>(callback: (resolve: (ret: T) => void, reject: (ret: any) => void) => void): Promise<T> {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
callback(resolve, reject);
|
||||
} catch (e) {
|
||||
logger.error(e);
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import axios from "axios";
|
||||
// @ts-ignore
|
||||
import qs from "qs";
|
||||
import { logger } from "./util.log";
|
||||
import { logger } from "./util.log.js";
|
||||
import { Logger } from "log4js";
|
||||
/**
|
||||
* @description 创建请求实例
|
||||
@@ -50,7 +50,7 @@ export function createAxiosService({ logger }: { logger: Logger }) {
|
||||
// case 505: error.message = 'HTTP版本不受支持'; break
|
||||
// default: break
|
||||
// }
|
||||
logger.error(`请求出错:url:${error?.response?.config.url},method:${error.response.config.method},status:${error?.response?.status}`);
|
||||
logger.error(`请求出错:url:${error?.response?.config.url},method:${error?.response?.config?.method},status:${error?.response?.status}`);
|
||||
logger.info("返回数据:", JSON.stringify(error?.response?.data));
|
||||
delete error.config;
|
||||
delete error.response;
|
||||
|
||||
@@ -5,3 +5,4 @@ export default function (timeout: number) {
|
||||
}, timeout);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
110
packages/core/pipeline/src/utils/util.sp.ts
Normal file
110
packages/core/pipeline/src/utils/util.sp.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
//转换为import
|
||||
import childProcess from "child_process";
|
||||
import { safePromise } from "./util.promise.js";
|
||||
import { ILogger, logger } from "./util.log.js";
|
||||
|
||||
export type ExecOption = {
|
||||
cmd: string | string[];
|
||||
env: any;
|
||||
logger?: ILogger;
|
||||
options?: any;
|
||||
};
|
||||
|
||||
async function exec(opts: ExecOption): Promise<string> {
|
||||
let cmd = "";
|
||||
const log = opts.logger || logger;
|
||||
if (opts.cmd instanceof Array) {
|
||||
for (const item of opts.cmd) {
|
||||
if (cmd) {
|
||||
cmd += " && " + item;
|
||||
} else {
|
||||
cmd = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
log.info(`执行命令: ${cmd}`);
|
||||
return safePromise((resolve, reject) => {
|
||||
childProcess.exec(
|
||||
cmd,
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
...opts.env,
|
||||
},
|
||||
...opts.options,
|
||||
},
|
||||
(error, stdout, stderr) => {
|
||||
if (error) {
|
||||
log.error(`exec error: ${error}`);
|
||||
reject(error);
|
||||
} else {
|
||||
const res = stdout.toString("utf-8");
|
||||
log.info(`stdout: ${res}`);
|
||||
resolve(res);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export type SpawnOption = {
|
||||
cmd: string | string[];
|
||||
onStdout?: (data: string) => void;
|
||||
onStderr?: (data: string) => void;
|
||||
env: any;
|
||||
logger?: ILogger;
|
||||
options?: any;
|
||||
};
|
||||
async function spawn(opts: SpawnOption): Promise<string> {
|
||||
let cmd = "";
|
||||
const log = opts.logger || logger;
|
||||
if (opts.cmd instanceof Array) {
|
||||
for (const item of opts.cmd) {
|
||||
if (cmd) {
|
||||
cmd += " && " + item;
|
||||
} else {
|
||||
cmd = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
log.info(`执行命令: ${cmd}`);
|
||||
let stdout = "";
|
||||
let stderr = "";
|
||||
return safePromise((resolve, reject) => {
|
||||
const ls = childProcess.spawn(cmd, {
|
||||
shell: process.platform == "win32",
|
||||
env: {
|
||||
...process.env,
|
||||
...opts.env,
|
||||
},
|
||||
...opts.options,
|
||||
});
|
||||
ls.stdout.on("data", (data) => {
|
||||
log.info(`stdout: ${data}`);
|
||||
stdout += data;
|
||||
});
|
||||
|
||||
ls.stderr.on("data", (data) => {
|
||||
log.error(`stderr: ${data}`);
|
||||
stderr += data;
|
||||
});
|
||||
ls.on("error", (error) => {
|
||||
log.error(`child process error: ${error}`);
|
||||
reject(error);
|
||||
});
|
||||
|
||||
ls.on("close", (code: number) => {
|
||||
if (code !== 0) {
|
||||
log.error(`child process exited with code ${code}`);
|
||||
reject(new Error(stderr));
|
||||
} else {
|
||||
resolve(stdout);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export const sp = {
|
||||
spawn,
|
||||
exec,
|
||||
};
|
||||
@@ -1,23 +1,41 @@
|
||||
{
|
||||
"compileOnSave": true,
|
||||
"compilerOptions": {
|
||||
"importHelpers": false,
|
||||
"target": "ESNext",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Node",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
"sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"skipLibCheck": true,
|
||||
"experimentalDecorators": true,
|
||||
"paths": {
|
||||
"tslib" : ["./node_modules/tslib/tslib.d.ts"]
|
||||
}
|
||||
"emitDecoratorMetadata": true,
|
||||
"inlineSourceMap":true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"stripInternal": true,
|
||||
"skipLibCheck": true,
|
||||
"pretty": true,
|
||||
"declaration": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"typeRoots": [ "./typings", "./node_modules/@types"],
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"composite": true,
|
||||
"useDefineForClassFields": true,
|
||||
"strict": true,
|
||||
// "sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": false,
|
||||
"lib": ["ESNext", "DOM"],
|
||||
},
|
||||
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue","test/**/*.ts","rollup.config.ts"],
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.d.ts",
|
||||
"src/**/*.json"
|
||||
],
|
||||
"exclude": [
|
||||
"*.js",
|
||||
"*.ts",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"test"
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
import { defineConfig } from "vite";
|
||||
import visualizer from "rollup-plugin-visualizer";
|
||||
import typescript from "@rollup/plugin-typescript";
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [],
|
||||
build: {
|
||||
target: "es2015",
|
||||
lib: {
|
||||
entry: "src/index.ts",
|
||||
name: "CertdPipeline",
|
||||
},
|
||||
rollupOptions: {
|
||||
plugins: [
|
||||
visualizer(),
|
||||
typescript({
|
||||
target: "es2015",
|
||||
rootDir: "src",
|
||||
declaration: true,
|
||||
declarationDir: "dist/d",
|
||||
exclude: ["./node_modules/**", "./src/**/*.vue"],
|
||||
allowSyntheticDefaultImports: true,
|
||||
}),
|
||||
],
|
||||
external: [
|
||||
"vue",
|
||||
"lodash",
|
||||
"dayjs",
|
||||
"@certd/acme-client",
|
||||
"@certd/plugin-cert",
|
||||
"@certd/plugin-aliyun",
|
||||
"@certd/plugin-tencent",
|
||||
"@certd/plugin-huawei",
|
||||
"@certd/plugin-host",
|
||||
"@certd/plugin-tencent",
|
||||
"@certd/plugin-util",
|
||||
"log4js",
|
||||
"@midwayjs/core",
|
||||
"@midwayjs/decorator",
|
||||
],
|
||||
output: {
|
||||
globals: {
|
||||
vue: "Vue",
|
||||
lodash: "_",
|
||||
dayjs: "dayjs",
|
||||
"@certd/plugin-cert": "CertdPluginCert",
|
||||
"@certd/acme-client": "CertdAcmeClient",
|
||||
"@certd/plugin-aliyun": "CertdPluginAliyun",
|
||||
"@certd/plugin-host": "CertdPluginHost",
|
||||
"@certd/plugin-huawei": "CertdPluginHuawei",
|
||||
"@certd/plugin-util": "CertdPluginUtil",
|
||||
log4js: "log4js",
|
||||
"@midwayjs/core": "MidwayjsCore",
|
||||
"@midwayjs/decorator": "MidwayjsDecorator",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -23,4 +23,6 @@ dist-ssr
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
test/user.secret.ts
|
||||
test/user.secret.ts
|
||||
|
||||
.rollup.cache
|
||||
3
packages/libs/lib-huawei/.npmignore
Normal file
3
packages/libs/lib-huawei/.npmignore
Normal file
@@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
src
|
||||
.rollup.cache
|
||||
15
packages/libs/lib-huawei/CHANGELOG.md
Normal file
15
packages/libs/lib-huawei/CHANGELOG.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.22.1](https://github.com/certd/certd/compare/v1.22.0...v1.22.1) (2024-07-20)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
# [1.22.0](https://github.com/certd/certd/compare/v1.21.2...v1.22.0) (2024-07-19)
|
||||
|
||||
### Features
|
||||
|
||||
* 升级midway,支持esm ([485e603](https://github.com/certd/certd/commit/485e603b5165c28bc08694997726eaf2a585ebe7))
|
||||
* 支持postgresql ([3b19bfb](https://github.com/certd/certd/commit/3b19bfb4291e89064b3b407a80dae092d54747d5))
|
||||
96
packages/libs/lib-huawei/fix-esm-import-paths.js
Normal file
96
packages/libs/lib-huawei/fix-esm-import-paths.js
Normal file
@@ -0,0 +1,96 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
// https://gist.github.com/lovasoa/8691344
|
||||
async function* walk(dir) {
|
||||
for await (const d of await fs.promises.opendir(dir)) {
|
||||
const entry = path.join(dir, d.name);
|
||||
if (d.isDirectory()) {
|
||||
yield* walk(entry);
|
||||
} else if (d.isFile()) {
|
||||
yield entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resolveImportPath(sourceFile, importPath, options) {
|
||||
const sourceFileAbs = path.resolve(process.cwd(), sourceFile);
|
||||
const root = path.dirname(sourceFileAbs);
|
||||
const { moduleFilter = defaultModuleFilter } = options;
|
||||
|
||||
if (moduleFilter(importPath)) {
|
||||
const importPathAbs = path.resolve(root, importPath);
|
||||
let possiblePath = [path.resolve(importPathAbs, "./index.ts"), path.resolve(importPathAbs, "./index.js"), importPathAbs + ".ts", importPathAbs + ".js"];
|
||||
|
||||
if (possiblePath.length) {
|
||||
for (let i = 0; i < possiblePath.length; i++) {
|
||||
let entry = possiblePath[i];
|
||||
if (fs.existsSync(entry)) {
|
||||
const resolved = path.relative(root, entry.replace(/\.ts$/, ".js"));
|
||||
|
||||
if (!resolved.startsWith(".")) {
|
||||
return "./" + resolved;
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function replace(filePath, outFilePath, options) {
|
||||
const code = fs.readFileSync(filePath).toString();
|
||||
const newCode = code.replace(/(import|export) (.+?) from ('[^\n']+'|"[^\n"]+");/gs, function (found, action, imported, from) {
|
||||
const importPath = from.slice(1, -1);
|
||||
let resolvedPath = resolveImportPath(filePath, importPath, options);
|
||||
|
||||
if (resolvedPath) {
|
||||
resolvedPath = resolvedPath.replaceAll("\\", "/");
|
||||
console.log("\t", importPath, resolvedPath);
|
||||
return `${action} ${imported} from "${resolvedPath}";`;
|
||||
}
|
||||
|
||||
return found;
|
||||
});
|
||||
|
||||
if (code !== newCode) {
|
||||
fs.writeFileSync(outFilePath, newCode);
|
||||
}
|
||||
}
|
||||
|
||||
// Then, use it with a simple async for loop
|
||||
async function run(srcDir, options = defaultOptions) {
|
||||
const { sourceFileFilter = defaultSourceFileFilter } = options;
|
||||
|
||||
for await (const entry of walk(srcDir)) {
|
||||
if (sourceFileFilter(entry)) {
|
||||
console.log(entry);
|
||||
replace(entry, entry, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const defaultSourceFileFilter = function (sourceFilePath) {
|
||||
return /\.(js|ts)$/.test(sourceFilePath) && !/node_modules/.test(sourceFilePath);
|
||||
};
|
||||
|
||||
const defaultModuleFilter = function (importedModule) {
|
||||
return !path.isAbsolute(importedModule) && !importedModule.startsWith("@") && !importedModule.endsWith(".js");
|
||||
};
|
||||
|
||||
const defaultOptions = {
|
||||
sourceFileFilter: defaultSourceFileFilter,
|
||||
moduleFilter: defaultModuleFilter,
|
||||
};
|
||||
|
||||
// Switch this to test on one file or directly run on a directory.
|
||||
const DEBUG = false;
|
||||
|
||||
if (DEBUG) {
|
||||
replace("./src/index.ts", "./out.ts", defaultOptions);
|
||||
} else {
|
||||
await run("./src/", defaultOptions);
|
||||
}
|
||||
20
packages/libs/lib-huawei/package.json
Normal file
20
packages/libs/lib-huawei/package.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "@certd/lib-huawei",
|
||||
"private": false,
|
||||
"version": "1.22.1",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "rollup -c ",
|
||||
"build2": "vue-tsc --noEmit && vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/pipeline": "1.21.0",
|
||||
"axios": "^1.7.2",
|
||||
"rollup": "^3.7.4"
|
||||
},
|
||||
"gitHead": "47fe3d5826661f678d081ab53e67c847a3239d88"
|
||||
}
|
||||
@@ -32,22 +32,5 @@ module.exports = {
|
||||
json(),
|
||||
terser(),
|
||||
],
|
||||
external: [
|
||||
"vue",
|
||||
"lodash",
|
||||
"dayjs",
|
||||
"@certd/acme-client",
|
||||
"@certd/pipeline",
|
||||
"@certd/plugin-cert",
|
||||
"@certd/plugin-aliyun",
|
||||
"@certd/plugin-tencent",
|
||||
"@certd/plugin-huawei",
|
||||
"@certd/plugin-host",
|
||||
"@certd/plugin-tencent",
|
||||
"@certd/plugin-util",
|
||||
"log4js",
|
||||
"@midwayjs/core",
|
||||
"@midwayjs/decorator",
|
||||
"kubernetes-client",
|
||||
],
|
||||
external: ["vue", "lodash-es", "dayjs", "log4js", "@midwayjs/core", "@certd/pipeline", "axios"],
|
||||
};
|
||||
2
packages/libs/lib-huawei/src/index.ts
Normal file
2
packages/libs/lib-huawei/src/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { HuaweiYunClient } from "./lib/client.js";
|
||||
export { ApiRequestOptions } from "./lib/client.js";
|
||||
12
packages/libs/lib-huawei/src/lib/client.d.ts
vendored
Normal file
12
packages/libs/lib-huawei/src/lib/client.d.ts
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import { HuaweiAccess } from "../access/index.js";
|
||||
export type ApiRequestOptions = {
|
||||
method: string;
|
||||
url: string;
|
||||
headers?: any;
|
||||
data?: any;
|
||||
};
|
||||
export declare class HuaweiYunClient {
|
||||
access: HuaweiAccess;
|
||||
constructor(access: HuaweiAccess);
|
||||
request(options: ApiRequestOptions): Promise<any>;
|
||||
}
|
||||
41
packages/libs/lib-huawei/src/lib/client.js
Normal file
41
packages/libs/lib-huawei/src/lib/client.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import { Signer, SigHttpRequest } from "./signer.js";
|
||||
import axios from "axios";
|
||||
export class HuaweiYunClient {
|
||||
access;
|
||||
constructor(access, logger) {
|
||||
this.access = access;
|
||||
}
|
||||
async request(options) {
|
||||
const sig = new Signer(this.access.accessKeyId, this.access.accessKeySecret);
|
||||
//The following example shows how to set the request URL and parameters to query a VPC list.
|
||||
//Specify a request method, such as GET, PUT, POST, DELETE, HEAD, and PATCH.
|
||||
//Set request host.
|
||||
//Set request URI.
|
||||
//Set parameters for the request URL.
|
||||
let body = undefined;
|
||||
if (options.data) {
|
||||
body = JSON.stringify(options.data);
|
||||
}
|
||||
const r = new SigHttpRequest(options.method, options.url, options.headers, body);
|
||||
//Add header parameters, for example, x-domain-id for invoking a global service and x-project-id for invoking a project-level service.
|
||||
r.headers = { "Content-Type": "application/json" };
|
||||
//Add a body if you have specified the PUT or POST method. Special characters, such as the double quotation mark ("), contained in the body must be escaped.
|
||||
// r.body = option;
|
||||
const opt = sig.Sign(r);
|
||||
try {
|
||||
const res = await axios.request({
|
||||
url: options.url,
|
||||
method: options.method,
|
||||
headers: opt.headers,
|
||||
data: body,
|
||||
});
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
this.logger.error("华为云接口请求出错:", e?.response?.data);
|
||||
const error = new Error(e?.response?.data.message);
|
||||
error.code = e?.response?.code;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3BsdWdpbnMvcGx1Z2luLWh1YXdlaS9saWIvY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRXJELE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUMxQixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFRekMsTUFBTSxPQUFPLGVBQWU7SUFDMUIsTUFBTSxDQUFlO0lBQ3JCLFlBQVksTUFBb0I7UUFDOUIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDdkIsQ0FBQztJQUNELEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBMEI7UUFDdEMsTUFBTSxHQUFHLEdBQUcsSUFBSSxNQUFNLENBQ3BCLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUN2QixJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FDNUIsQ0FBQztRQUVGLDRGQUE0RjtRQUM1Riw0RUFBNEU7UUFDNUUsbUJBQW1CO1FBQ25CLGtCQUFrQjtRQUNsQixxQ0FBcUM7UUFDckMsSUFBSSxJQUFJLEdBQUcsU0FBUyxDQUFDO1FBQ3JCLElBQUksT0FBTyxDQUFDLElBQUksRUFBRTtZQUNoQixJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDckM7UUFDRCxNQUFNLENBQUMsR0FBRyxJQUFJLGNBQWMsQ0FDMUIsT0FBTyxDQUFDLE1BQU0sRUFDZCxPQUFPLENBQUMsR0FBRyxFQUNYLE9BQU8sQ0FBQyxPQUFPLEVBQ2YsSUFBSSxDQUNMLENBQUM7UUFDRixzSUFBc0k7UUFDdEksQ0FBQyxDQUFDLE9BQU8sR0FBRyxFQUFFLGNBQWMsRUFBRSxrQkFBa0IsRUFBRSxDQUFDO1FBQ25ELDRKQUE0SjtRQUM1SixtQkFBbUI7UUFDbkIsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4QixJQUFJO1lBQ0YsTUFBTSxHQUFHLEdBQUcsTUFBTSxLQUFLLENBQUMsT0FBTyxDQUFDO2dCQUM5QixHQUFHLEVBQUUsT0FBTyxDQUFDLEdBQUc7Z0JBQ2hCLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTTtnQkFDdEIsT0FBTyxFQUFFLEdBQUcsQ0FBQyxPQUFPO2dCQUNwQixJQUFJLEVBQUUsSUFBSTthQUNYLENBQUMsQ0FBQztZQUNILE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQztTQUNqQjtRQUFDLE9BQU8sQ0FBTSxFQUFFO1lBQ2YsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUM5QyxNQUFNLEtBQUssR0FBUSxJQUFJLEtBQUssQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN4RCxLQUFLLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDO1lBQy9CLE1BQU0sS0FBSyxDQUFDO1NBQ2I7SUFDSCxDQUFDO0NBQ0YifQ==
|
||||
20
packages/libs/lib-huawei/src/lib/signer.d.ts
vendored
Normal file
20
packages/libs/lib-huawei/src/lib/signer.d.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
export declare class SigHttpRequest {
|
||||
method: string;
|
||||
host: string;
|
||||
uri: string;
|
||||
query: any;
|
||||
headers: any;
|
||||
body: string;
|
||||
constructor(method: any, url: any, headers: any, body: any);
|
||||
}
|
||||
export declare class Signer {
|
||||
Key: string;
|
||||
Secret: string;
|
||||
constructor(Key: any, Secret: any);
|
||||
Sign(r: any): {
|
||||
hostname: any;
|
||||
path: string;
|
||||
method: any;
|
||||
headers: any;
|
||||
};
|
||||
}
|
||||
459
packages/libs/lib-huawei/src/lib/signer.js
Normal file
459
packages/libs/lib-huawei/src/lib/signer.js
Normal file
File diff suppressed because one or more lines are too long
41
packages/libs/lib-huawei/tsconfig.json
Normal file
41
packages/libs/lib-huawei/tsconfig.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"compileOnSave": true,
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"inlineSourceMap":true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"stripInternal": true,
|
||||
"skipLibCheck": true,
|
||||
"pretty": true,
|
||||
"declaration": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"typeRoots": [ "./typings", "./node_modules/@types"],
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"composite": true,
|
||||
"useDefineForClassFields": true,
|
||||
"strict": false,
|
||||
"sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": false,
|
||||
"lib": ["ESNext", "DOM"],
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.d.ts",
|
||||
"src/**/*.js",
|
||||
"src/**/*.json"
|
||||
],
|
||||
"exclude": [
|
||||
"*.ts",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"test"
|
||||
],
|
||||
}
|
||||
23
packages/libs/lib-k8s/.eslintrc
Normal file
23
packages/libs/lib-k8s/.eslintrc
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"extends": [
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:prettier/recommended",
|
||||
"prettier"
|
||||
],
|
||||
"env": {
|
||||
"mocha": true
|
||||
},
|
||||
"rules": {
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
// "no-unused-expressions": "off",
|
||||
"max-len": [0, 160, 2, { "ignoreUrls": true }]
|
||||
}
|
||||
}
|
||||
28
packages/libs/lib-k8s/.gitignore
vendored
Normal file
28
packages/libs/lib-k8s/.gitignore
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
src/test/user.secret.ts
|
||||
|
||||
src/**/*.js
|
||||
7
packages/libs/lib-k8s/.prettierrc
Normal file
7
packages/libs/lib-k8s/.prettierrc
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"printWidth": 160,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
27
packages/libs/lib-k8s/CHANGELOG.md
Normal file
27
packages/libs/lib-k8s/CHANGELOG.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.22.5](https://github.com/certd/certd/compare/v1.22.4...v1.22.5) (2024-07-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.22.3](https://github.com/certd/certd/compare/v1.22.2...v1.22.3) (2024-07-25)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.22.2](https://github.com/certd/certd/compare/v1.22.1...v1.22.2) (2024-07-23)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.22.1](https://github.com/certd/certd/compare/v1.22.0...v1.22.1) (2024-07-20)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
# [1.22.0](https://github.com/certd/certd/compare/v1.21.2...v1.22.0) (2024-07-19)
|
||||
|
||||
### Features
|
||||
|
||||
* 升级midway,支持esm ([485e603](https://github.com/certd/certd/commit/485e603b5165c28bc08694997726eaf2a585ebe7))
|
||||
* 支持postgresql ([3b19bfb](https://github.com/certd/certd/commit/3b19bfb4291e89064b3b407a80dae092d54747d5))
|
||||
16
packages/libs/lib-k8s/README.md
Normal file
16
packages/libs/lib-k8s/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Vue 3 + TypeScript + Vite
|
||||
|
||||
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)
|
||||
|
||||
## Type Support For `.vue` Imports in TS
|
||||
|
||||
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's Take Over mode by following these steps:
|
||||
|
||||
1. Run `Extensions: Show Built-in Extensions` from VS Code's command palette, look for `TypeScript and JavaScript Language Features`, then right click and select `Disable (Workspace)`. By default, Take Over mode will enable itself if the default TypeScript extension is disabled.
|
||||
2. Reload the VS Code window by running `Developer: Reload Window` from the command palette.
|
||||
|
||||
You can learn more about Take Over mode [here](https://github.com/johnsoncodehk/volar/discussions/471).
|
||||
96
packages/libs/lib-k8s/fix-esm-import-paths.js
Normal file
96
packages/libs/lib-k8s/fix-esm-import-paths.js
Normal file
@@ -0,0 +1,96 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
// https://gist.github.com/lovasoa/8691344
|
||||
async function* walk(dir) {
|
||||
for await (const d of await fs.promises.opendir(dir)) {
|
||||
const entry = path.join(dir, d.name);
|
||||
if (d.isDirectory()) {
|
||||
yield* walk(entry);
|
||||
} else if (d.isFile()) {
|
||||
yield entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resolveImportPath(sourceFile, importPath, options) {
|
||||
const sourceFileAbs = path.resolve(process.cwd(), sourceFile);
|
||||
const root = path.dirname(sourceFileAbs);
|
||||
const { moduleFilter = defaultModuleFilter } = options;
|
||||
|
||||
if (moduleFilter(importPath)) {
|
||||
const importPathAbs = path.resolve(root, importPath);
|
||||
let possiblePath = [path.resolve(importPathAbs, "./index.ts"), path.resolve(importPathAbs, "./index.js"), importPathAbs + ".ts", importPathAbs + ".js"];
|
||||
|
||||
if (possiblePath.length) {
|
||||
for (let i = 0; i < possiblePath.length; i++) {
|
||||
let entry = possiblePath[i];
|
||||
if (fs.existsSync(entry)) {
|
||||
const resolved = path.relative(root, entry.replace(/\.ts$/, ".js"));
|
||||
|
||||
if (!resolved.startsWith(".")) {
|
||||
return "./" + resolved;
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function replace(filePath, outFilePath, options) {
|
||||
const code = fs.readFileSync(filePath).toString();
|
||||
const newCode = code.replace(/(import|export) (.+?) from ('[^\n']+'|"[^\n"]+");/gs, function (found, action, imported, from) {
|
||||
const importPath = from.slice(1, -1);
|
||||
let resolvedPath = resolveImportPath(filePath, importPath, options);
|
||||
|
||||
if (resolvedPath) {
|
||||
resolvedPath = resolvedPath.replaceAll("\\", "/");
|
||||
console.log("\t", importPath, resolvedPath);
|
||||
return `${action} ${imported} from "${resolvedPath}";`;
|
||||
}
|
||||
|
||||
return found;
|
||||
});
|
||||
|
||||
if (code !== newCode) {
|
||||
fs.writeFileSync(outFilePath, newCode);
|
||||
}
|
||||
}
|
||||
|
||||
// Then, use it with a simple async for loop
|
||||
async function run(srcDir, options = defaultOptions) {
|
||||
const { sourceFileFilter = defaultSourceFileFilter } = options;
|
||||
|
||||
for await (const entry of walk(srcDir)) {
|
||||
if (sourceFileFilter(entry)) {
|
||||
console.log(entry);
|
||||
replace(entry, entry, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const defaultSourceFileFilter = function (sourceFilePath) {
|
||||
return /\.(js|ts)$/.test(sourceFilePath) && !/node_modules/.test(sourceFilePath);
|
||||
};
|
||||
|
||||
const defaultModuleFilter = function (importedModule) {
|
||||
return !path.isAbsolute(importedModule) && !importedModule.startsWith("@") && !importedModule.endsWith(".js");
|
||||
};
|
||||
|
||||
const defaultOptions = {
|
||||
sourceFileFilter: defaultSourceFileFilter,
|
||||
moduleFilter: defaultModuleFilter,
|
||||
};
|
||||
|
||||
// Switch this to test on one file or directly run on a directory.
|
||||
const DEBUG = false;
|
||||
|
||||
if (DEBUG) {
|
||||
replace("./src/index.ts", "./out.ts", defaultOptions);
|
||||
} else {
|
||||
await run("./src/", defaultOptions);
|
||||
}
|
||||
@@ -1,18 +1,14 @@
|
||||
{
|
||||
"name": "@certd/plugin-util",
|
||||
"name": "@certd/lib-k8s",
|
||||
"private": false,
|
||||
"version": "1.20.17",
|
||||
"main": "./src/index.ts",
|
||||
"module": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"publishConfig": {
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.mjs",
|
||||
"types": "./dist/d/index.d.ts"
|
||||
},
|
||||
"version": "1.22.5",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "rollup -c",
|
||||
"build": "tsc --skipLibCheck",
|
||||
"build3": "rollup -c",
|
||||
"build2": "vue-tsc --noEmit && vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
@@ -21,14 +17,13 @@
|
||||
"shelljs": "^0.8.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/pipeline": "workspace:^1.20.17",
|
||||
"@certd/pipeline": "^1.22.5",
|
||||
"@rollup/plugin-commonjs": "^23.0.4",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@rollup/plugin-terser": "^0.4.3",
|
||||
"@rollup/plugin-typescript": "^11.0.0",
|
||||
"@types/chai": "^4.3.3",
|
||||
"@types/lodash": "^4.14.186",
|
||||
"@typescript-eslint/eslint-plugin": "^5.38.1",
|
||||
"@typescript-eslint/parser": "^5.38.1",
|
||||
"eslint": "^8.24.0",
|
||||
@@ -43,5 +38,5 @@
|
||||
"tslib": "^2.5.2",
|
||||
"typescript": "^4.8.4"
|
||||
},
|
||||
"gitHead": "a31f1c7f5e71fa946de9bf0283e11d6ce049b3e9"
|
||||
"gitHead": "e5da46cfc31b2e30a4903bcb2251b1851265ef41"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user