From 11f7ebc95a82c6e8ce0808614300f3924a6175d1 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Mon, 23 Jun 2025 10:53:12 +0800 Subject: [PATCH 01/16] fix: could not deploy to rainyun rcdn --- internal/deployer/providers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/deployer/providers.go b/internal/deployer/providers.go index 19362290..00feace5 100644 --- a/internal/deployer/providers.go +++ b/internal/deployer/providers.go @@ -1011,7 +1011,7 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy } switch options.Provider { - case domain.DeploymentProviderTypeTencentCloudCDN: + case domain.DeploymentProviderTypeRainYunRCDN: deployer, err := pRainYunRCDN.NewSSLDeployerProvider(&pRainYunRCDN.SSLDeployerProviderConfig{ ApiKey: access.ApiKey, InstanceId: xmaps.GetInt32(options.ProviderServiceConfig, "instanceId"), From 902cd83f7924d4f507f873109ed814fdb587b1c4 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Mon, 23 Jun 2025 12:11:12 +0800 Subject: [PATCH 02/16] feat: support configuring endpoint on deployment to tencentcloud --- internal/deployer/providers.go | 11 ++ .../tencentcloud-cdn/tencentcloud_cdn.go | 181 ++++++++---------- .../tencentcloud-clb/tencentcloud_clb.go | 30 ++- .../tencentcloud-cos/tencentcloud_cos.go | 20 +- .../tencentcloud-css/tencentcloud_css.go | 19 +- .../tencentcloud-ecdn/tencentcloud_ecdn.go | 156 ++++++++------- .../tencentcloud-eo/tencentcloud_eo.go | 41 ++-- .../tencentcloud-gaap/tencentcloud_gaap.go | 21 +- .../tencentcloud-scf/tencentcloud_scf.go | 20 +- .../tencentcloud_ssl_deploy.go | 14 +- .../tencentcloud-ssl/tencentcloud_ssl.go | 3 + .../tencentcloud-vod/tencentcloud_vod.go | 20 +- .../tencentcloud-waf/tencentcloud_waf.go | 20 +- .../tencentcloud-ssl/tencentcloud_ssl.go | 14 +- pkg/utils/ifelse/ifelse.go | 34 ++++ pkg/utils/ifelse/ternary.go | 35 ++++ .../workflow/node/DeployNodeConfigForm.tsx | 3 + .../DeployNodeConfigFormAliyunALBConfig.tsx | 26 +-- .../DeployNodeConfigFormAliyunCLBConfig.tsx | 20 +- .../DeployNodeConfigFormAliyunNLBConfig.tsx | 26 +-- ...oyNodeConfigFormBaiduCloudAppBLBConfig.tsx | 26 +-- ...eployNodeConfigFormBaiduCloudBLBConfig.tsx | 26 +-- ...DeployNodeConfigFormCTCCCloudELBConfig.tsx | 24 +-- ...ployNodeConfigFormHuaweiCloudELBConfig.tsx | 26 +-- ...ployNodeConfigFormHuaweiCloudWAFConfig.tsx | 26 +-- .../DeployNodeConfigFormJDCloudALBConfig.tsx | 26 +-- ...loyNodeConfigFormTencentCloudCDNConfig.tsx | 11 ++ ...loyNodeConfigFormTencentCloudCLBConfig.tsx | 31 ++- ...loyNodeConfigFormTencentCloudCSSConfig.tsx | 11 ++ ...oyNodeConfigFormTencentCloudECDNConfig.tsx | 11 ++ ...ployNodeConfigFormTencentCloudEOConfig.tsx | 11 ++ ...oyNodeConfigFormTencentCloudGAAPConfig.tsx | 11 ++ ...loyNodeConfigFormTencentCloudSCFConfig.tsx | 11 ++ ...loyNodeConfigFormTencentCloudSSLConfig.tsx | 61 ++++++ ...eConfigFormTencentCloudSSLDeployConfig.tsx | 11 ++ ...loyNodeConfigFormTencentCloudVODConfig.tsx | 11 ++ ...loyNodeConfigFormTencentCloudWAFConfig.tsx | 11 ++ ...eployNodeConfigFormVolcEngineALBConfig.tsx | 26 +-- ...eployNodeConfigFormVolcEngineCLBConfig.tsx | 26 +-- .../i18n/locales/en/nls.workflow.nodes.json | 105 ++++++---- .../i18n/locales/zh/nls.workflow.nodes.json | 93 ++++++--- 41 files changed, 864 insertions(+), 445 deletions(-) create mode 100644 pkg/utils/ifelse/ifelse.go create mode 100644 pkg/utils/ifelse/ternary.go create mode 100644 ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLConfig.tsx diff --git a/internal/deployer/providers.go b/internal/deployer/providers.go index 00feace5..708dc6d0 100644 --- a/internal/deployer/providers.go +++ b/internal/deployer/providers.go @@ -1130,6 +1130,7 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy deployer, err := pTencentCloudCDN.NewSSLDeployerProvider(&pTencentCloudCDN.SSLDeployerProviderConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, + Endpoint: xmaps.GetString(options.ProviderServiceConfig, "endpoint"), Domain: xmaps.GetString(options.ProviderServiceConfig, "domain"), }) return deployer, err @@ -1138,6 +1139,7 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy deployer, err := pTencentCloudCLB.NewSSLDeployerProvider(&pTencentCloudCLB.SSLDeployerProviderConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, + Endpoint: xmaps.GetString(options.ProviderServiceConfig, "endpoint"), Region: xmaps.GetString(options.ProviderServiceConfig, "region"), ResourceType: pTencentCloudCLB.ResourceType(xmaps.GetString(options.ProviderServiceConfig, "resourceType")), LoadbalancerId: xmaps.GetString(options.ProviderServiceConfig, "loadbalancerId"), @@ -1160,6 +1162,7 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy deployer, err := pTencentCloudCSS.NewSSLDeployerProvider(&pTencentCloudCSS.SSLDeployerProviderConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, + Endpoint: xmaps.GetString(options.ProviderServiceConfig, "endpoint"), Domain: xmaps.GetString(options.ProviderServiceConfig, "domain"), }) return deployer, err @@ -1168,6 +1171,7 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy deployer, err := pTencentCloudECDN.NewSSLDeployerProvider(&pTencentCloudECDN.SSLDeployerProviderConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, + Endpoint: xmaps.GetString(options.ProviderServiceConfig, "endpoint"), Domain: xmaps.GetString(options.ProviderServiceConfig, "domain"), }) return deployer, err @@ -1176,6 +1180,7 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy deployer, err := pTencentCloudEO.NewSSLDeployerProvider(&pTencentCloudEO.SSLDeployerProviderConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, + Endpoint: xmaps.GetString(options.ProviderServiceConfig, "endpoint"), ZoneId: xmaps.GetString(options.ProviderServiceConfig, "zoneId"), Domain: xmaps.GetString(options.ProviderServiceConfig, "domain"), }) @@ -1185,6 +1190,7 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy deployer, err := pTencentCloudGAAP.NewSSLDeployerProvider(&pTencentCloudGAAP.SSLDeployerProviderConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, + Endpoint: xmaps.GetString(options.ProviderServiceConfig, "endpoint"), ResourceType: pTencentCloudGAAP.ResourceType(xmaps.GetString(options.ProviderServiceConfig, "resourceType")), ProxyId: xmaps.GetString(options.ProviderServiceConfig, "proxyId"), ListenerId: xmaps.GetString(options.ProviderServiceConfig, "listenerId"), @@ -1195,6 +1201,7 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy deployer, err := pTencentCloudSCF.NewSSLDeployerProvider(&pTencentCloudSCF.SSLDeployerProviderConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, + Endpoint: xmaps.GetString(options.ProviderServiceConfig, "endpoint"), Region: xmaps.GetString(options.ProviderServiceConfig, "region"), Domain: xmaps.GetString(options.ProviderServiceConfig, "domain"), }) @@ -1204,6 +1211,7 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy deployer, err := pTencentCloudSSL.NewSSLDeployerProvider(&pTencentCloudSSL.SSLDeployerProviderConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, + Endpoint: xmaps.GetString(options.ProviderServiceConfig, "endpoint"), }) return deployer, err @@ -1211,6 +1219,7 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy deployer, err := pTencentCloudSSLDeploy.NewSSLDeployerProvider(&pTencentCloudSSLDeploy.SSLDeployerProviderConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, + Endpoint: xmaps.GetString(options.ProviderServiceConfig, "endpoint"), Region: xmaps.GetString(options.ProviderServiceConfig, "region"), ResourceType: xmaps.GetString(options.ProviderServiceConfig, "resourceType"), ResourceIds: xslices.Filter(strings.Split(xmaps.GetString(options.ProviderServiceConfig, "resourceIds"), ";"), func(s string) bool { return s != "" }), @@ -1221,6 +1230,7 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy deployer, err := pTencentCloudVOD.NewSSLDeployerProvider(&pTencentCloudVOD.SSLDeployerProviderConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, + Endpoint: xmaps.GetString(options.ProviderServiceConfig, "endpoint"), SubAppId: xmaps.GetInt64(options.ProviderServiceConfig, "subAppId"), Domain: xmaps.GetString(options.ProviderServiceConfig, "domain"), }) @@ -1230,6 +1240,7 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy deployer, err := pTencentCloudWAF.NewSSLDeployerProvider(&pTencentCloudWAF.SSLDeployerProviderConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, + Endpoint: xmaps.GetString(options.ProviderServiceConfig, "endpoint"), Domain: xmaps.GetString(options.ProviderServiceConfig, "domain"), DomainId: xmaps.GetString(options.ProviderServiceConfig, "domainId"), InstanceId: xmaps.GetString(options.ProviderServiceConfig, "instanceId"), diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go b/pkg/core/ssl-deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go index 332bf610..73235e07 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go @@ -6,16 +6,15 @@ import ( "fmt" "log/slog" "strings" - "time" tccdn "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn/v20180606" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" tcssl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205" - "golang.org/x/exp/slices" "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/tencentcloud-ssl" + "github.com/certimate-go/certimate/pkg/utils/ifelse" ) type SSLDeployerProviderConfig struct { @@ -23,6 +22,8 @@ type SSLDeployerProviderConfig struct { SecretId string `json:"secretId"` // 腾讯云 SecretKey。 SecretKey string `json:"secretKey"` + // 腾讯云接口端点。 + Endpoint string `json:"endpoint,omitempty"` // 加速域名(支持泛域名)。 Domain string `json:"domain"` } @@ -30,7 +31,7 @@ type SSLDeployerProviderConfig struct { type SSLDeployerProvider struct { config *SSLDeployerProviderConfig logger *slog.Logger - sdkClients *wSDKClients + sdkClient *tccdn.Client sslManager core.SSLManager } @@ -46,7 +47,7 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, errors.New("the configuration of the ssl deployer provider is nil") } - clients, err := createSDKClients(config.SecretId, config.SecretKey) + client, err := createSDKClient(config.SecretId, config.SecretKey, config.Endpoint) if err != nil { return nil, fmt.Errorf("could not create sdk client: %w", err) } @@ -54,6 +55,10 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ SecretId: config.SecretId, SecretKey: config.SecretKey, + Endpoint: ifelse. + If[string](strings.HasSuffix(strings.TrimSpace(config.Endpoint), "intl.tencentcloudapi.com")). + Then("ssl.intl.tencentcloudapi.com"). // 国际站使用独立的接口端点 + Else(""), }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) @@ -62,7 +67,7 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return &SSLDeployerProvider{ config: config, logger: slog.Default(), - sdkClients: clients, + sdkClient: client, sslManager: sslmgr, }, nil } @@ -92,106 +97,51 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke // 获取待部署的 CDN 实例 // 如果是泛域名,根据证书匹配 CDN 实例 - instanceIds := make([]string, 0) + domains := make([]string, 0) if strings.HasPrefix(d.config.Domain, "*.") { - domains, err := d.getDomainsByCertificateId(upres.CertId) + temp, err := d.getDomainsByCertId(ctx, upres.CertId) if err != nil { return nil, err } - instanceIds = domains + domains = temp } else { - instanceIds = append(instanceIds, d.config.Domain) + domains = append(domains, d.config.Domain) } - // 跳过已部署的 CDN 实例 - if len(instanceIds) > 0 { - deployedDomains, err := d.getDeployedDomainsByCertificateId(upres.CertId) - if err != nil { - return nil, err - } - - temp := make([]string, 0) - for _, instanceId := range instanceIds { - if !slices.Contains(deployedDomains, instanceId) { - temp = append(temp, instanceId) - } - } - instanceIds = temp - } - - if len(instanceIds) == 0 { - d.logger.Info("no cdn instances to deploy") + // 遍历更新域名证书 + if len(domains) == 0 { + d.logger.Info("no cdn domains to deploy") } else { - d.logger.Info("found cdn instances to deploy", slog.Any("instanceIds", instanceIds)) + d.logger.Info("found cdn domains to deploy", slog.Any("domains", domains)) + var errs []error - // 证书部署到 CDN 实例 - // REF: https://cloud.tencent.com/document/product/400/91667 - deployCertificateInstanceReq := tcssl.NewDeployCertificateInstanceRequest() - deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId) - deployCertificateInstanceReq.ResourceType = common.StringPtr("cdn") - deployCertificateInstanceReq.Status = common.Int64Ptr(1) - deployCertificateInstanceReq.InstanceIdList = common.StringPtrs(instanceIds) - deployCertificateInstanceResp, err := d.sdkClients.SSL.DeployCertificateInstance(deployCertificateInstanceReq) - d.logger.Debug("sdk request 'ssl.DeployCertificateInstance'", slog.Any("request", deployCertificateInstanceReq), slog.Any("response", deployCertificateInstanceResp)) - if err != nil { - return nil, fmt.Errorf("failed to execute sdk request 'ssl.DeployCertificateInstance': %w", err) - } - - // 循环获取部署任务详情,等待任务状态变更 - // REF: https://cloud.tencent.com/document/api/400/91658 - for { + for _, domain := range domains { select { case <-ctx.Done(): return nil, ctx.Err() default: - } - - describeHostDeployRecordDetailReq := tcssl.NewDescribeHostDeployRecordDetailRequest() - describeHostDeployRecordDetailReq.DeployRecordId = common.StringPtr(fmt.Sprintf("%d", *deployCertificateInstanceResp.Response.DeployRecordId)) - describeHostDeployRecordDetailResp, err := d.sdkClients.SSL.DescribeHostDeployRecordDetail(describeHostDeployRecordDetailReq) - d.logger.Debug("sdk request 'ssl.DescribeHostDeployRecordDetail'", slog.Any("request", describeHostDeployRecordDetailReq), slog.Any("response", describeHostDeployRecordDetailResp)) - if err != nil { - return nil, fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostDeployRecordDetail': %w", err) - } - - var runningCount, succeededCount, failedCount, totalCount int64 - if describeHostDeployRecordDetailResp.Response.TotalCount == nil { - return nil, errors.New("unexpected deployment job status") - } else { - if describeHostDeployRecordDetailResp.Response.RunningTotalCount != nil { - runningCount = *describeHostDeployRecordDetailResp.Response.RunningTotalCount - } - if describeHostDeployRecordDetailResp.Response.SuccessTotalCount != nil { - succeededCount = *describeHostDeployRecordDetailResp.Response.SuccessTotalCount - } - if describeHostDeployRecordDetailResp.Response.FailedTotalCount != nil { - failedCount = *describeHostDeployRecordDetailResp.Response.FailedTotalCount - } - if describeHostDeployRecordDetailResp.Response.TotalCount != nil { - totalCount = *describeHostDeployRecordDetailResp.Response.TotalCount - } - - if succeededCount+failedCount == totalCount { - break + if err := d.updateDomainHttpsServerCert(ctx, domain, upres.CertId); err != nil { + errs = append(errs, err) } } + } - d.logger.Info(fmt.Sprintf("waiting for deployment job completion (running: %d, succeeded: %d, failed: %d, total: %d) ...", runningCount, succeededCount, failedCount, totalCount)) - time.Sleep(time.Second * 5) + if len(errs) > 0 { + return nil, errors.Join(errs...) } } return &core.SSLDeployResult{}, nil } -func (d *SSLDeployerProvider) getDomainsByCertificateId(cloudCertId string) ([]string, error) { +func (d *SSLDeployerProvider) getDomainsByCertId(ctx context.Context, cloudCertId string) ([]string, error) { // 获取证书中的可用域名 // REF: https://cloud.tencent.com/document/product/228/42491 describeCertDomainsReq := tccdn.NewDescribeCertDomainsRequest() describeCertDomainsReq.CertId = common.StringPtr(cloudCertId) describeCertDomainsReq.Product = common.StringPtr("cdn") - describeCertDomainsResp, err := d.sdkClients.CDN.DescribeCertDomains(describeCertDomainsReq) + describeCertDomainsResp, err := d.sdkClient.DescribeCertDomains(describeCertDomainsReq) d.logger.Debug("sdk request 'cdn.DescribeCertDomains'", slog.Any("request", describeCertDomainsReq), slog.Any("response", describeCertDomainsResp)) if err != nil { return nil, fmt.Errorf("failed to execute sdk request 'cdn.DescribeCertDomains': %w", err) @@ -207,45 +157,68 @@ func (d *SSLDeployerProvider) getDomainsByCertificateId(cloudCertId string) ([]s return domains, nil } -func (d *SSLDeployerProvider) getDeployedDomainsByCertificateId(cloudCertId string) ([]string, error) { - // 根据证书查询关联资源 - // REF: https://cloud.tencent.com/document/product/400/62674 - describeDeployedResourcesReq := tcssl.NewDescribeDeployedResourcesRequest() - describeDeployedResourcesReq.CertificateIds = common.StringPtrs([]string{cloudCertId}) - describeDeployedResourcesReq.ResourceType = common.StringPtr("cdn") - describeDeployedResourcesResp, err := d.sdkClients.SSL.DescribeDeployedResources(describeDeployedResourcesReq) - d.logger.Debug("sdk request 'cdn.DescribeDeployedResources'", slog.Any("request", describeDeployedResourcesReq), slog.Any("response", describeDeployedResourcesResp)) +func (d *SSLDeployerProvider) updateDomainHttpsServerCert(ctx context.Context, domain string, cloudCertId string) error { + // 查询域名详细配置 + // REF: https://cloud.tencent.com/document/product/228/41117 + describeDomainsConfigReq := tccdn.NewDescribeDomainsConfigRequest() + describeDomainsConfigReq.Filters = []*tccdn.DomainFilter{ + { + Name: common.StringPtr("domain"), + Value: common.StringPtrs([]string{domain}), + }, + } + describeDomainsConfigReq.Offset = common.Int64Ptr(0) + describeDomainsConfigReq.Limit = common.Int64Ptr(1) + describeDomainsConfigResp, err := d.sdkClient.DescribeDomainsConfig(describeDomainsConfigReq) + d.logger.Debug("sdk request 'cdn.DescribeDomainsConfig'", slog.Any("request", describeDomainsConfigReq), slog.Any("response", describeDomainsConfigResp)) if err != nil { - return nil, fmt.Errorf("failed to execute sdk request 'cdn.DescribeDeployedResources': %w", err) + return fmt.Errorf("failed to execute sdk request 'cdn.DescribeDomainsConfig': %w", err) + } else if len(describeDomainsConfigResp.Response.Domains) == 0 { + return fmt.Errorf("domain %s not found", domain) } - domains := make([]string, 0) - if describeDeployedResourcesResp.Response.DeployedResources != nil { - for _, deployedResource := range describeDeployedResourcesResp.Response.DeployedResources { - for _, resource := range deployedResource.Resources { - domains = append(domains, *resource) - } + domainConfig := describeDomainsConfigResp.Response.Domains[0] + if domainConfig.Https != nil && domainConfig.Https.CertInfo != nil && domainConfig.Https.CertInfo.CertId != nil && *domainConfig.Https.CertInfo.CertId == cloudCertId { + // 已部署过此域名,跳过 + return nil + } + + // 更新加速域名配置 + // REF: https://cloud.tencent.com/document/product/228/41116 + updateDomainConfigReq := tccdn.NewUpdateDomainConfigRequest() + updateDomainConfigReq.Domain = common.StringPtr(domain) + updateDomainConfigReq.Https = domainConfig.Https + if updateDomainConfigReq.Https == nil { + updateDomainConfigReq.Https = &tccdn.Https{ + Switch: common.StringPtr("on"), } + } else { + updateDomainConfigReq.Https.SslStatus = nil + } + updateDomainConfigReq.Https.CertInfo = &tccdn.ServerCert{ + CertId: common.StringPtr(cloudCertId), + } + updateDomainConfigResp, err := d.sdkClient.UpdateDomainConfig(updateDomainConfigReq) + d.logger.Debug("sdk request 'cdn.UpdateDomainConfig'", slog.Any("request", updateDomainConfigReq), slog.Any("response", updateDomainConfigResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request 'cdn.UpdateDomainConfig': %w", err) } - return domains, nil + return nil } -func createSDKClients(secretId, secretKey string) (*wSDKClients, error) { +func createSDKClient(secretId, secretKey, endpoint string) (*tccdn.Client, error) { credential := common.NewCredential(secretId, secretKey) - sslClient, err := tcssl.NewClient(credential, "", profile.NewClientProfile()) + cpf := profile.NewClientProfile() + if endpoint != "" { + cpf.HttpProfile.Endpoint = endpoint + } + + client, err := tccdn.NewClient(credential, "", cpf) if err != nil { return nil, err } - cdnClient, err := tccdn.NewClient(credential, "", profile.NewClientProfile()) - if err != nil { - return nil, err - } - - return &wSDKClients{ - SSL: sslClient, - CDN: cdnClient, - }, nil + return client, nil } diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-clb/tencentcloud_clb.go b/pkg/core/ssl-deployer/providers/tencentcloud-clb/tencentcloud_clb.go index 0c37558d..c8f07d2d 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-clb/tencentcloud_clb.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-clb/tencentcloud_clb.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "log/slog" + "strings" "time" tcclb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317" @@ -14,6 +15,7 @@ import ( "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/tencentcloud-ssl" + "github.com/certimate-go/certimate/pkg/utils/ifelse" ) type SSLDeployerProviderConfig struct { @@ -23,6 +25,8 @@ type SSLDeployerProviderConfig struct { SecretKey string `json:"secretKey"` // 腾讯云地域。 Region string `json:"region"` + // 腾讯云接口端点。 + Endpoint string `json:"endpoint,omitempty"` // 部署资源类型。 ResourceType ResourceType `json:"resourceType"` // 负载均衡器 ID。 @@ -55,7 +59,7 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, errors.New("the configuration of the ssl deployer provider is nil") } - clients, err := createSDKClients(config.SecretId, config.SecretKey, config.Region) + clients, err := createSDKClients(config.SecretId, config.SecretKey, config.Endpoint, config.Region) if err != nil { return nil, fmt.Errorf("could not create sdk client: %w", err) } @@ -63,6 +67,10 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ SecretId: config.SecretId, SecretKey: config.SecretKey, + Endpoint: ifelse. + If[string](strings.HasSuffix(strings.TrimSpace(config.Endpoint), "intl.tencentcloudapi.com")). + Then("ssl.intl.tencentcloudapi.com"). // 国际站使用独立的接口端点 + Else(""), }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) @@ -306,7 +314,7 @@ func (d *SSLDeployerProvider) modifyListenerCertificate(ctx context.Context, clo if err != nil { return fmt.Errorf("failed to execute sdk request 'clb.DescribeListeners': %w", err) } else if len(describeListenersResp.Response.Listeners) == 0 { - return errors.New("listener not found") + return fmt.Errorf("listener %s not found", cloudListenerId) } // 修改监听器属性 @@ -330,16 +338,28 @@ func (d *SSLDeployerProvider) modifyListenerCertificate(ctx context.Context, clo return nil } -func createSDKClients(secretId, secretKey, region string) (*wSDKClients, error) { +func createSDKClients(secretId, secretKey, endpoint, region string) (*wSDKClients, error) { credential := common.NewCredential(secretId, secretKey) + sslCpf := profile.NewClientProfile() + if endpoint != "" { + if strings.HasSuffix(endpoint, "intl.tencentcloudapi.com") { + sslCpf.HttpProfile.Endpoint = "ssl.intl.tencentcloudapi.com" + } + } + // 注意虽然官方文档中地域无需指定,但实际需要部署到 CLB 时必传 - sslClient, err := tcssl.NewClient(credential, region, profile.NewClientProfile()) + sslClient, err := tcssl.NewClient(credential, region, sslCpf) if err != nil { return nil, err } - clbClient, err := tcclb.NewClient(credential, region, profile.NewClientProfile()) + clbCpf := profile.NewClientProfile() + if endpoint != "" { + clbCpf.HttpProfile.Endpoint = endpoint + } + + clbClient, err := tcclb.NewClient(credential, region, clbCpf) if err != nil { return nil, err } diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-cos/tencentcloud_cos.go b/pkg/core/ssl-deployer/providers/tencentcloud-cos/tencentcloud_cos.go index 7f4501d1..6bca08a0 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-cos/tencentcloud_cos.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-cos/tencentcloud_cos.go @@ -31,18 +31,22 @@ type SSLDeployerProviderConfig struct { type SSLDeployerProvider struct { config *SSLDeployerProviderConfig logger *slog.Logger - sdkClient *tcssl.Client + sdkClient *wSDKClients sslManager core.SSLManager } var _ core.SSLDeployer = (*SSLDeployerProvider)(nil) +type wSDKClients struct { + SSL *tcssl.Client +} + func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProvider, error) { if config == nil { return nil, errors.New("the configuration of the ssl deployer provider is nil") } - client, err := createSDKClient(config.SecretId, config.SecretKey, config.Region) + clients, err := createSDKClients(config.SecretId, config.SecretKey, config.Region) if err != nil { return nil, fmt.Errorf("could not create sdk client: %w", err) } @@ -58,7 +62,7 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return &SSLDeployerProvider{ config: config, logger: slog.Default(), - sdkClient: client, + sdkClient: clients, sslManager: sslmgr, }, nil } @@ -96,7 +100,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke deployCertificateInstanceReq.ResourceType = common.StringPtr("cos") deployCertificateInstanceReq.Status = common.Int64Ptr(1) deployCertificateInstanceReq.InstanceIdList = common.StringPtrs([]string{fmt.Sprintf("%s#%s#%s", d.config.Region, d.config.Bucket, d.config.Domain)}) - deployCertificateInstanceResp, err := d.sdkClient.DeployCertificateInstance(deployCertificateInstanceReq) + deployCertificateInstanceResp, err := d.sdkClient.SSL.DeployCertificateInstance(deployCertificateInstanceReq) d.logger.Debug("sdk request 'ssl.DeployCertificateInstance'", slog.Any("request", deployCertificateInstanceReq), slog.Any("response", deployCertificateInstanceResp)) if err != nil { return nil, fmt.Errorf("failed to execute sdk request 'ssl.DeployCertificateInstance': %w", err) @@ -113,7 +117,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke describeHostDeployRecordDetailReq := tcssl.NewDescribeHostDeployRecordDetailRequest() describeHostDeployRecordDetailReq.DeployRecordId = common.StringPtr(fmt.Sprintf("%d", *deployCertificateInstanceResp.Response.DeployRecordId)) - describeHostDeployRecordDetailResp, err := d.sdkClient.DescribeHostDeployRecordDetail(describeHostDeployRecordDetailReq) + describeHostDeployRecordDetailResp, err := d.sdkClient.SSL.DescribeHostDeployRecordDetail(describeHostDeployRecordDetailReq) d.logger.Debug("sdk request 'ssl.DescribeHostDeployRecordDetail'", slog.Any("request", describeHostDeployRecordDetailReq), slog.Any("response", describeHostDeployRecordDetailResp)) if err != nil { return nil, fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostDeployRecordDetail': %w", err) @@ -148,12 +152,14 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke return &core.SSLDeployResult{}, nil } -func createSDKClient(secretId, secretKey, region string) (*tcssl.Client, error) { +func createSDKClients(secretId, secretKey, region string) (*wSDKClients, error) { credential := common.NewCredential(secretId, secretKey) client, err := tcssl.NewClient(credential, region, profile.NewClientProfile()) if err != nil { return nil, err } - return client, nil + return &wSDKClients{ + SSL: client, + }, nil } diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-css/tencentcloud_css.go b/pkg/core/ssl-deployer/providers/tencentcloud-css/tencentcloud_css.go index ab07c62f..f83e602c 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-css/tencentcloud_css.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-css/tencentcloud_css.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "log/slog" + "strings" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" @@ -12,6 +13,7 @@ import ( "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/tencentcloud-ssl" + "github.com/certimate-go/certimate/pkg/utils/ifelse" ) type SSLDeployerProviderConfig struct { @@ -19,6 +21,8 @@ type SSLDeployerProviderConfig struct { SecretId string `json:"secretId"` // 腾讯云 SecretKey。 SecretKey string `json:"secretKey"` + // 腾讯云接口端点。 + Endpoint string `json:"endpoint,omitempty"` // 直播播放域名(不支持泛域名)。 Domain string `json:"domain"` } @@ -37,7 +41,7 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, errors.New("the configuration of the ssl deployer provider is nil") } - client, err := createSDKClient(config.SecretId, config.SecretKey) + client, err := createSDKClient(config.SecretId, config.SecretKey, config.Endpoint) if err != nil { return nil, fmt.Errorf("could not create sdk client: %w", err) } @@ -45,6 +49,10 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ SecretId: config.SecretId, SecretKey: config.SecretKey, + Endpoint: ifelse. + If[string](strings.HasSuffix(strings.TrimSpace(config.Endpoint), "intl.tencentcloudapi.com")). + Then("ssl.intl.tencentcloudapi.com"). // 国际站使用独立的接口端点 + Else(""), }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) @@ -100,10 +108,15 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke return &core.SSLDeployResult{}, nil } -func createSDKClient(secretId, secretKey string) (*tclive.Client, error) { +func createSDKClient(secretId, secretKey, endpoint string) (*tclive.Client, error) { credential := common.NewCredential(secretId, secretKey) - client, err := tclive.NewClient(credential, "", profile.NewClientProfile()) + cpf := profile.NewClientProfile() + if endpoint != "" { + cpf.HttpProfile.Endpoint = endpoint + } + + client, err := tclive.NewClient(credential, "", cpf) if err != nil { return nil, err } diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go b/pkg/core/ssl-deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go index 817a1042..3b054e24 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go @@ -6,7 +6,6 @@ import ( "fmt" "log/slog" "strings" - "time" tccdn "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn/v20180606" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" @@ -15,6 +14,7 @@ import ( "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/tencentcloud-ssl" + "github.com/certimate-go/certimate/pkg/utils/ifelse" ) type SSLDeployerProviderConfig struct { @@ -22,6 +22,8 @@ type SSLDeployerProviderConfig struct { SecretId string `json:"secretId"` // 腾讯云 SecretKey。 SecretKey string `json:"secretKey"` + // 腾讯云接口端点。 + Endpoint string `json:"endpoint,omitempty"` // 加速域名(支持泛域名)。 Domain string `json:"domain"` } @@ -29,7 +31,7 @@ type SSLDeployerProviderConfig struct { type SSLDeployerProvider struct { config *SSLDeployerProviderConfig logger *slog.Logger - sdkClients *wSDKClients + sdkClient *tccdn.Client sslManager core.SSLManager } @@ -45,7 +47,7 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, errors.New("the configuration of the ssl deployer provider is nil") } - clients, err := createSDKClients(config.SecretId, config.SecretKey) + client, err := createSDKClient(config.SecretId, config.SecretKey, config.Endpoint) if err != nil { return nil, fmt.Errorf("could not create sdk client: %w", err) } @@ -53,6 +55,10 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ SecretId: config.SecretId, SecretKey: config.SecretKey, + Endpoint: ifelse. + If[string](strings.HasSuffix(strings.TrimSpace(config.Endpoint), "intl.tencentcloudapi.com")). + Then("ssl.intl.tencentcloudapi.com"). // 国际站使用独立的接口端点 + Else(""), }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) @@ -61,7 +67,7 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return &SSLDeployerProvider{ config: config, logger: slog.Default(), - sdkClients: clients, + sdkClient: client, sslManager: sslmgr, }, nil } @@ -91,90 +97,51 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke // 获取待部署的 CDN 实例 // 如果是泛域名,根据证书匹配 CDN 实例 - instanceIds := make([]string, 0) + domains := make([]string, 0) if strings.HasPrefix(d.config.Domain, "*.") { - domains, err := d.getDomainsByCertificateId(upres.CertId) + temp, err := d.getDomainsByCertId(upres.CertId) if err != nil { return nil, err } - instanceIds = domains + domains = temp } else { - instanceIds = append(instanceIds, d.config.Domain) + domains = append(domains, d.config.Domain) } - if len(instanceIds) == 0 { - d.logger.Info("no ecdn instances to deploy") + // 遍历更新域名证书 + if len(domains) == 0 { + d.logger.Info("no ecdn domains to deploy") } else { - d.logger.Info("found ecdn instances to deploy", slog.Any("instanceIds", instanceIds)) + d.logger.Info("found ecdn domains to deploy", slog.Any("domains", domains)) + var errs []error - // 证书部署到 CDN 实例 - // REF: https://cloud.tencent.com/document/product/400/91667 - deployCertificateInstanceReq := tcssl.NewDeployCertificateInstanceRequest() - deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId) - deployCertificateInstanceReq.ResourceType = common.StringPtr("cdn") - deployCertificateInstanceReq.Status = common.Int64Ptr(1) - deployCertificateInstanceReq.InstanceIdList = common.StringPtrs(instanceIds) - deployCertificateInstanceResp, err := d.sdkClients.SSL.DeployCertificateInstance(deployCertificateInstanceReq) - d.logger.Debug("sdk request 'ssl.DeployCertificateInstance'", slog.Any("request", deployCertificateInstanceReq), slog.Any("response", deployCertificateInstanceResp)) - if err != nil { - return nil, fmt.Errorf("failed to execute sdk request 'ssl.DeployCertificateInstance': %w", err) - } - - // 循环获取部署任务详情,等待任务状态变更 - // REF: https://cloud.tencent.com/document/api/400/91658 - for { + for _, domain := range domains { select { case <-ctx.Done(): return nil, ctx.Err() default: - } - - describeHostDeployRecordDetailReq := tcssl.NewDescribeHostDeployRecordDetailRequest() - describeHostDeployRecordDetailReq.DeployRecordId = common.StringPtr(fmt.Sprintf("%d", *deployCertificateInstanceResp.Response.DeployRecordId)) - describeHostDeployRecordDetailResp, err := d.sdkClients.SSL.DescribeHostDeployRecordDetail(describeHostDeployRecordDetailReq) - d.logger.Debug("sdk request 'ssl.DescribeHostDeployRecordDetail'", slog.Any("request", describeHostDeployRecordDetailReq), slog.Any("response", describeHostDeployRecordDetailResp)) - if err != nil { - return nil, fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostDeployRecordDetail': %w", err) - } - - var runningCount, succeededCount, failedCount, totalCount int64 - if describeHostDeployRecordDetailResp.Response.TotalCount == nil { - return nil, errors.New("unexpected deployment job status") - } else { - if describeHostDeployRecordDetailResp.Response.RunningTotalCount != nil { - runningCount = *describeHostDeployRecordDetailResp.Response.RunningTotalCount - } - if describeHostDeployRecordDetailResp.Response.SuccessTotalCount != nil { - succeededCount = *describeHostDeployRecordDetailResp.Response.SuccessTotalCount - } - if describeHostDeployRecordDetailResp.Response.FailedTotalCount != nil { - failedCount = *describeHostDeployRecordDetailResp.Response.FailedTotalCount - } - if describeHostDeployRecordDetailResp.Response.TotalCount != nil { - totalCount = *describeHostDeployRecordDetailResp.Response.TotalCount - } - - if succeededCount+failedCount == totalCount { - break + if err := d.updateDomainHttpsServerCert(ctx, domain, upres.CertId); err != nil { + errs = append(errs, err) } } + } - d.logger.Info(fmt.Sprintf("waiting for deployment job completion (running: %d, succeeded: %d, failed: %d, total: %d) ...", runningCount, succeededCount, failedCount, totalCount)) - time.Sleep(time.Second * 5) + if len(errs) > 0 { + return nil, errors.Join(errs...) } } return &core.SSLDeployResult{}, nil } -func (d *SSLDeployerProvider) getDomainsByCertificateId(cloudCertId string) ([]string, error) { +func (d *SSLDeployerProvider) getDomainsByCertId(cloudCertId string) ([]string, error) { // 获取证书中的可用域名 // REF: https://cloud.tencent.com/document/product/228/42491 describeCertDomainsReq := tccdn.NewDescribeCertDomainsRequest() describeCertDomainsReq.CertId = common.StringPtr(cloudCertId) describeCertDomainsReq.Product = common.StringPtr("ecdn") - describeCertDomainsResp, err := d.sdkClients.CDN.DescribeCertDomains(describeCertDomainsReq) + describeCertDomainsResp, err := d.sdkClient.DescribeCertDomains(describeCertDomainsReq) d.logger.Debug("sdk request 'cdn.DescribeCertDomains'", slog.Any("request", describeCertDomainsReq), slog.Any("response", describeCertDomainsResp)) if err != nil { return nil, fmt.Errorf("failed to execute sdk request 'cdn.DescribeCertDomains': %w", err) @@ -190,21 +157,68 @@ func (d *SSLDeployerProvider) getDomainsByCertificateId(cloudCertId string) ([]s return domains, nil } -func createSDKClients(secretId, secretKey string) (*wSDKClients, error) { +func (d *SSLDeployerProvider) updateDomainHttpsServerCert(ctx context.Context, domain string, cloudCertId string) error { + // 查询域名详细配置 + // REF: https://cloud.tencent.com/document/product/228/41117 + describeDomainsConfigReq := tccdn.NewDescribeDomainsConfigRequest() + describeDomainsConfigReq.Filters = []*tccdn.DomainFilter{ + { + Name: common.StringPtr("domain"), + Value: common.StringPtrs([]string{domain}), + }, + } + describeDomainsConfigReq.Offset = common.Int64Ptr(0) + describeDomainsConfigReq.Limit = common.Int64Ptr(1) + describeDomainsConfigResp, err := d.sdkClient.DescribeDomainsConfig(describeDomainsConfigReq) + d.logger.Debug("sdk request 'cdn.DescribeDomainsConfig'", slog.Any("request", describeDomainsConfigReq), slog.Any("response", describeDomainsConfigResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request 'cdn.DescribeDomainsConfig': %w", err) + } else if len(describeDomainsConfigResp.Response.Domains) == 0 { + return fmt.Errorf("domain %s not found", domain) + } + + domainConfig := describeDomainsConfigResp.Response.Domains[0] + if domainConfig.Https != nil && domainConfig.Https.CertInfo != nil && domainConfig.Https.CertInfo.CertId != nil && *domainConfig.Https.CertInfo.CertId == cloudCertId { + // 已部署过此域名,跳过 + return nil + } + + // 更新加速域名配置 + // REF: https://cloud.tencent.com/document/product/228/41116 + updateDomainConfigReq := tccdn.NewUpdateDomainConfigRequest() + updateDomainConfigReq.Domain = common.StringPtr(domain) + updateDomainConfigReq.Https = domainConfig.Https + if updateDomainConfigReq.Https == nil { + updateDomainConfigReq.Https = &tccdn.Https{ + Switch: common.StringPtr("on"), + } + } else { + updateDomainConfigReq.Https.SslStatus = nil + } + updateDomainConfigReq.Https.CertInfo = &tccdn.ServerCert{ + CertId: common.StringPtr(cloudCertId), + } + updateDomainConfigResp, err := d.sdkClient.UpdateDomainConfig(updateDomainConfigReq) + d.logger.Debug("sdk request 'cdn.UpdateDomainConfig'", slog.Any("request", updateDomainConfigReq), slog.Any("response", updateDomainConfigResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request 'cdn.UpdateDomainConfig': %w", err) + } + + return nil +} + +func createSDKClient(secretId, secretKey, endpoint string) (*tccdn.Client, error) { credential := common.NewCredential(secretId, secretKey) - sslClient, err := tcssl.NewClient(credential, "", profile.NewClientProfile()) + cpf := profile.NewClientProfile() + if endpoint != "" { + cpf.HttpProfile.Endpoint = endpoint + } + + client, err := tccdn.NewClient(credential, "", cpf) if err != nil { return nil, err } - cdnClient, err := tccdn.NewClient(credential, "", profile.NewClientProfile()) - if err != nil { - return nil, err - } - - return &wSDKClients{ - SSL: sslClient, - CDN: cdnClient, - }, nil + return client, nil } diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-eo/tencentcloud_eo.go b/pkg/core/ssl-deployer/providers/tencentcloud-eo/tencentcloud_eo.go index 2f94f438..c18ced57 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-eo/tencentcloud_eo.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-eo/tencentcloud_eo.go @@ -5,14 +5,15 @@ import ( "errors" "fmt" "log/slog" + "strings" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" - tcssl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205" tcteo "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo/v20220901" "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/tencentcloud-ssl" + "github.com/certimate-go/certimate/pkg/utils/ifelse" ) type SSLDeployerProviderConfig struct { @@ -20,6 +21,8 @@ type SSLDeployerProviderConfig struct { SecretId string `json:"secretId"` // 腾讯云 SecretKey。 SecretKey string `json:"secretKey"` + // 腾讯云接口端点。 + Endpoint string `json:"endpoint,omitempty"` // 站点 ID。 ZoneId string `json:"zoneId"` // 加速域名(支持泛域名)。 @@ -29,23 +32,18 @@ type SSLDeployerProviderConfig struct { type SSLDeployerProvider struct { config *SSLDeployerProviderConfig logger *slog.Logger - sdkClients *wSDKClients + sdkClient *tcteo.Client sslManager core.SSLManager } var _ core.SSLDeployer = (*SSLDeployerProvider)(nil) -type wSDKClients struct { - SSL *tcssl.Client - TEO *tcteo.Client -} - func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProvider, error) { if config == nil { return nil, errors.New("the configuration of the ssl deployer provider is nil") } - clients, err := createSDKClients(config.SecretId, config.SecretKey) + client, err := createSDKClient(config.SecretId, config.SecretKey, config.Endpoint) if err != nil { return nil, fmt.Errorf("could not create sdk client: %w", err) } @@ -53,6 +51,10 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ SecretId: config.SecretId, SecretKey: config.SecretKey, + Endpoint: ifelse. + If[string](strings.HasSuffix(strings.TrimSpace(config.Endpoint), "intl.tencentcloudapi.com")). + Then("ssl.intl.tencentcloudapi.com"). // 国际站使用独立的接口端点 + Else(""), }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) @@ -61,7 +63,7 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return &SSLDeployerProvider{ config: config, logger: slog.Default(), - sdkClients: clients, + sdkClient: client, sslManager: sslmgr, }, nil } @@ -99,7 +101,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke modifyHostsCertificateReq.Mode = common.StringPtr("sslcert") modifyHostsCertificateReq.Hosts = common.StringPtrs([]string{d.config.Domain}) modifyHostsCertificateReq.ServerCertInfo = []*tcteo.ServerCertInfo{{CertId: common.StringPtr(upres.CertId)}} - modifyHostsCertificateResp, err := d.sdkClients.TEO.ModifyHostsCertificate(modifyHostsCertificateReq) + modifyHostsCertificateResp, err := d.sdkClient.ModifyHostsCertificate(modifyHostsCertificateReq) d.logger.Debug("sdk request 'teo.ModifyHostsCertificate'", slog.Any("request", modifyHostsCertificateReq), slog.Any("response", modifyHostsCertificateResp)) if err != nil { return nil, fmt.Errorf("failed to execute sdk request 'teo.ModifyHostsCertificate': %w", err) @@ -108,21 +110,18 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke return &core.SSLDeployResult{}, nil } -func createSDKClients(secretId, secretKey string) (*wSDKClients, error) { +func createSDKClient(secretId, secretKey, endpoint string) (*tcteo.Client, error) { credential := common.NewCredential(secretId, secretKey) - sslClient, err := tcssl.NewClient(credential, "", profile.NewClientProfile()) + cpf := profile.NewClientProfile() + if endpoint != "" { + cpf.HttpProfile.Endpoint = endpoint + } + + client, err := tcteo.NewClient(credential, "", cpf) if err != nil { return nil, err } - teoClient, err := tcteo.NewClient(credential, "", profile.NewClientProfile()) - if err != nil { - return nil, err - } - - return &wSDKClients{ - SSL: sslClient, - TEO: teoClient, - }, nil + return client, nil } diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-gaap/tencentcloud_gaap.go b/pkg/core/ssl-deployer/providers/tencentcloud-gaap/tencentcloud_gaap.go index 64e2d570..09e6da8e 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-gaap/tencentcloud_gaap.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-gaap/tencentcloud_gaap.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "log/slog" + "strings" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" @@ -12,6 +13,7 @@ import ( "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/tencentcloud-ssl" + "github.com/certimate-go/certimate/pkg/utils/ifelse" xtypes "github.com/certimate-go/certimate/pkg/utils/types" ) @@ -20,6 +22,8 @@ type SSLDeployerProviderConfig struct { SecretId string `json:"secretId"` // 腾讯云 SecretKey。 SecretKey string `json:"secretKey"` + // 腾讯云接口端点。 + Endpoint string `json:"endpoint,omitempty"` // 部署资源类型。 ResourceType ResourceType `json:"resourceType"` // 通道 ID。 @@ -44,7 +48,7 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, errors.New("the configuration of the ssl deployer provider is nil") } - client, err := createSDKClients(config.SecretId, config.SecretKey) + client, err := createSDKClients(config.SecretId, config.SecretKey, config.Endpoint) if err != nil { return nil, fmt.Errorf("could not create sdk client: %w", err) } @@ -52,6 +56,10 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ SecretId: config.SecretId, SecretKey: config.SecretKey, + Endpoint: ifelse. + If[string](strings.HasSuffix(strings.TrimSpace(config.Endpoint), "intl.tencentcloudapi.com")). + Then("ssl.intl.tencentcloudapi.com"). // 国际站使用独立的接口端点 + Else(""), }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) @@ -123,7 +131,7 @@ func (d *SSLDeployerProvider) modifyHttpsListenerCertificate(ctx context.Context if err != nil { return fmt.Errorf("failed to execute sdk request 'gaap.DescribeHTTPSListeners': %w", err) } else if len(describeHTTPSListenersResp.Response.ListenerSet) == 0 { - return errors.New("listener not found") + return fmt.Errorf("listener %s not found", cloudListenerId) } // 修改 HTTPS 监听器配置 @@ -141,10 +149,15 @@ func (d *SSLDeployerProvider) modifyHttpsListenerCertificate(ctx context.Context return nil } -func createSDKClients(secretId, secretKey string) (*tcgaap.Client, error) { +func createSDKClients(secretId, secretKey, endpoint string) (*tcgaap.Client, error) { credential := common.NewCredential(secretId, secretKey) - client, err := tcgaap.NewClient(credential, "", profile.NewClientProfile()) + cpf := profile.NewClientProfile() + if endpoint != "" { + cpf.HttpProfile.Endpoint = endpoint + } + + client, err := tcgaap.NewClient(credential, "", cpf) if err != nil { return nil, err } diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-scf/tencentcloud_scf.go b/pkg/core/ssl-deployer/providers/tencentcloud-scf/tencentcloud_scf.go index e8135421..94729516 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-scf/tencentcloud_scf.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-scf/tencentcloud_scf.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "log/slog" + "strings" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" @@ -12,6 +13,7 @@ import ( "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/tencentcloud-ssl" + "github.com/certimate-go/certimate/pkg/utils/ifelse" ) type SSLDeployerProviderConfig struct { @@ -19,6 +21,8 @@ type SSLDeployerProviderConfig struct { SecretId string `json:"secretId"` // 腾讯云 SecretKey。 SecretKey string `json:"secretKey"` + // 腾讯云接口端点。 + Endpoint string `json:"endpoint,omitempty"` // 腾讯云地域。 Region string `json:"region"` // 自定义域名(不支持泛域名)。 @@ -39,7 +43,7 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, errors.New("the configuration of the ssl deployer provider is nil") } - client, err := createSDKClient(config.SecretId, config.SecretKey, config.Region) + client, err := createSDKClient(config.SecretId, config.SecretKey, config.Endpoint, config.Region) if err != nil { return nil, fmt.Errorf("could not create sdk client: %w", err) } @@ -47,6 +51,10 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ SecretId: config.SecretId, SecretKey: config.SecretKey, + Endpoint: ifelse. + If[string](strings.HasSuffix(strings.TrimSpace(config.Endpoint), "intl.tencentcloudapi.com")). + Then("ssl.intl.tencentcloudapi.com"). // 国际站使用独立的接口端点 + Else(""), }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) @@ -110,9 +118,15 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke return &core.SSLDeployResult{}, nil } -func createSDKClient(secretId, secretKey, region string) (*tcscf.Client, error) { +func createSDKClient(secretId, secretKey, endpoint, region string) (*tcscf.Client, error) { credential := common.NewCredential(secretId, secretKey) - client, err := tcscf.NewClient(credential, region, profile.NewClientProfile()) + + cpf := profile.NewClientProfile() + if endpoint != "" { + cpf.HttpProfile.Endpoint = endpoint + } + + client, err := tcscf.NewClient(credential, region, cpf) if err != nil { return nil, err } diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go b/pkg/core/ssl-deployer/providers/tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go index cd07cc88..4c2de86c 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go @@ -20,6 +20,8 @@ type SSLDeployerProviderConfig struct { SecretId string `json:"secretId"` // 腾讯云 SecretKey。 SecretKey string `json:"secretKey"` + // 腾讯云接口端点。 + Endpoint string `json:"endpoint,omitempty"` // 腾讯云地域。 Region string `json:"region"` // 腾讯云云资源类型。 @@ -42,7 +44,7 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, errors.New("the configuration of the ssl deployer provider is nil") } - client, err := createSDKClient(config.SecretId, config.SecretKey, config.Region) + client, err := createSDKClient(config.SecretId, config.SecretKey, config.Endpoint, config.Region) if err != nil { return nil, fmt.Errorf("could not create sdk client: %w", err) } @@ -50,6 +52,7 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ SecretId: config.SecretId, SecretKey: config.SecretKey, + Endpoint: config.Endpoint, }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) @@ -150,10 +153,15 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke return &core.SSLDeployResult{}, nil } -func createSDKClient(secretId, secretKey, region string) (*tcssl.Client, error) { +func createSDKClient(secretId, secretKey, endpoint, region string) (*tcssl.Client, error) { credential := common.NewCredential(secretId, secretKey) - client, err := tcssl.NewClient(credential, region, profile.NewClientProfile()) + cpf := profile.NewClientProfile() + if endpoint != "" { + cpf.HttpProfile.Endpoint = endpoint + } + + client, err := tcssl.NewClient(credential, region, cpf) if err != nil { return nil, err } diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-ssl/tencentcloud_ssl.go b/pkg/core/ssl-deployer/providers/tencentcloud-ssl/tencentcloud_ssl.go index 89f439ac..5879d064 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-ssl/tencentcloud_ssl.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-ssl/tencentcloud_ssl.go @@ -15,6 +15,8 @@ type SSLDeployerProviderConfig struct { SecretId string `json:"secretId"` // 腾讯云 SecretKey。 SecretKey string `json:"secretKey"` + // 腾讯云接口端点。 + Endpoint string `json:"endpoint,omitempty"` } type SSLDeployerProvider struct { @@ -33,6 +35,7 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ SecretId: config.SecretId, SecretKey: config.SecretKey, + Endpoint: config.Endpoint, }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-vod/tencentcloud_vod.go b/pkg/core/ssl-deployer/providers/tencentcloud-vod/tencentcloud_vod.go index afc4ddb6..9a1ece3f 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-vod/tencentcloud_vod.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-vod/tencentcloud_vod.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "log/slog" + "strings" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" @@ -12,6 +13,7 @@ import ( "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/tencentcloud-ssl" + "github.com/certimate-go/certimate/pkg/utils/ifelse" ) type SSLDeployerProviderConfig struct { @@ -19,6 +21,8 @@ type SSLDeployerProviderConfig struct { SecretId string `json:"secretId"` // 腾讯云 SecretKey。 SecretKey string `json:"secretKey"` + // 腾讯云接口端点。 + Endpoint string `json:"endpoint,omitempty"` // 点播应用 ID。 SubAppId int64 `json:"subAppId"` // 点播加速域名(不支持泛域名)。 @@ -39,7 +43,7 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, errors.New("the configuration of the ssl deployer provider is nil") } - client, err := createSDKClient(config.SecretId, config.SecretKey) + client, err := createSDKClient(config.SecretId, config.SecretKey, config.Endpoint) if err != nil { return nil, fmt.Errorf("could not create sdk client: %w", err) } @@ -47,6 +51,10 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ SecretId: config.SecretId, SecretKey: config.SecretKey, + Endpoint: ifelse. + If[string](strings.HasSuffix(strings.TrimSpace(config.Endpoint), "intl.tencentcloudapi.com")). + Then("ssl.intl.tencentcloudapi.com"). // 国际站使用独立的接口端点 + Else(""), }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) @@ -101,9 +109,15 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke return &core.SSLDeployResult{}, nil } -func createSDKClient(secretId, secretKey string) (*tcvod.Client, error) { +func createSDKClient(secretId, secretKey, endpoint string) (*tcvod.Client, error) { credential := common.NewCredential(secretId, secretKey) - client, err := tcvod.NewClient(credential, "", profile.NewClientProfile()) + + cpf := profile.NewClientProfile() + if endpoint != "" { + cpf.HttpProfile.Endpoint = endpoint + } + + client, err := tcvod.NewClient(credential, "", cpf) if err != nil { return nil, err } diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-waf/tencentcloud_waf.go b/pkg/core/ssl-deployer/providers/tencentcloud-waf/tencentcloud_waf.go index 94e42f00..3bad8d41 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-waf/tencentcloud_waf.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-waf/tencentcloud_waf.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "log/slog" + "strings" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" @@ -12,6 +13,7 @@ import ( "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/tencentcloud-ssl" + "github.com/certimate-go/certimate/pkg/utils/ifelse" ) type SSLDeployerProviderConfig struct { @@ -19,6 +21,8 @@ type SSLDeployerProviderConfig struct { SecretId string `json:"secretId"` // 腾讯云 SecretKey。 SecretKey string `json:"secretKey"` + // 腾讯云接口端点。 + Endpoint string `json:"endpoint,omitempty"` // 腾讯云地域。 Region string `json:"region"` // 防护域名(不支持泛域名)。 @@ -43,7 +47,7 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, errors.New("the configuration of the ssl deployer provider is nil") } - client, err := createSDKClient(config.SecretId, config.SecretKey, config.Region) + client, err := createSDKClient(config.SecretId, config.SecretKey, config.Endpoint, config.Region) if err != nil { return nil, fmt.Errorf("could not create sdk client: %w", err) } @@ -51,6 +55,10 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ SecretId: config.SecretId, SecretKey: config.SecretKey, + Endpoint: ifelse. + If[string](strings.HasSuffix(strings.TrimSpace(config.Endpoint), "intl.tencentcloudapi.com")). + Then("ssl.intl.tencentcloudapi.com"). // 国际站使用独立的接口端点 + Else(""), }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) @@ -122,9 +130,15 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke return &core.SSLDeployResult{}, nil } -func createSDKClient(secretId, secretKey, region string) (*tcwaf.Client, error) { +func createSDKClient(secretId, secretKey, endpoint, region string) (*tcwaf.Client, error) { credential := common.NewCredential(secretId, secretKey) - client, err := tcwaf.NewClient(credential, region, profile.NewClientProfile()) + + cpf := profile.NewClientProfile() + if endpoint != "" { + cpf.HttpProfile.Endpoint = endpoint + } + + client, err := tcwaf.NewClient(credential, region, cpf) if err != nil { return nil, err } diff --git a/pkg/core/ssl-manager/providers/tencentcloud-ssl/tencentcloud_ssl.go b/pkg/core/ssl-manager/providers/tencentcloud-ssl/tencentcloud_ssl.go index 11724028..fc062b72 100644 --- a/pkg/core/ssl-manager/providers/tencentcloud-ssl/tencentcloud_ssl.go +++ b/pkg/core/ssl-manager/providers/tencentcloud-ssl/tencentcloud_ssl.go @@ -17,6 +17,8 @@ type SSLManagerProviderConfig struct { SecretId string `json:"secretId"` // 腾讯云 SecretKey。 SecretKey string `json:"secretKey"` + // 腾讯云接口端点。 + Endpoint string `json:"endpoint,omitempty"` } type SSLManagerProvider struct { @@ -32,7 +34,7 @@ func NewSSLManagerProvider(config *SSLManagerProviderConfig) (*SSLManagerProvide return nil, errors.New("the configuration of the ssl manager provider is nil") } - client, err := createSDKClient(config.SecretId, config.SecretKey) + client, err := createSDKClient(config.SecretId, config.SecretKey, config.Endpoint) if err != nil { return nil, fmt.Errorf("could not create sdk client: %w", err) } @@ -70,9 +72,15 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey }, nil } -func createSDKClient(secretId, secretKey string) (*tcssl.Client, error) { +func createSDKClient(secretId, secretKey, endpoint string) (*tcssl.Client, error) { credential := common.NewCredential(secretId, secretKey) - client, err := tcssl.NewClient(credential, "", profile.NewClientProfile()) + + cpf := profile.NewClientProfile() + if endpoint != "" { + cpf.HttpProfile.Endpoint = endpoint + } + + client, err := tcssl.NewClient(credential, "", cpf) if err != nil { return nil, err } diff --git a/pkg/utils/ifelse/ifelse.go b/pkg/utils/ifelse/ifelse.go new file mode 100644 index 00000000..fce28401 --- /dev/null +++ b/pkg/utils/ifelse/ifelse.go @@ -0,0 +1,34 @@ +package ifelse + +type ifExpr[T any] struct { + condition bool +} + +type thenExpr[T any] struct { + condition bool + consequent T +} + +// 示例: +// +// result := ifelse.If[T](condition).Then(consequent).Else(alternative) +func If[T any](condition bool) *ifExpr[T] { + return &ifExpr[T]{ + condition: condition, + } +} + +func (e *ifExpr[T]) Then(consequent T) *thenExpr[T] { + return &thenExpr[T]{ + condition: e.condition, + consequent: consequent, + } +} + +func (e *thenExpr[T]) Else(alternative T) T { + if e.condition { + return e.consequent + } + + return alternative +} diff --git a/pkg/utils/ifelse/ternary.go b/pkg/utils/ifelse/ternary.go new file mode 100644 index 00000000..a2a060f0 --- /dev/null +++ b/pkg/utils/ifelse/ternary.go @@ -0,0 +1,35 @@ +package ifelse + +// 三目条件函数。 +// +// 入参: +// - condition: 条件。 +// - consequent: 条件为真时返回的值。 +// - alternative: 条件为假时返回的值。 +// +// 出参: +// - 若 condition 的为真,将返回 consequent;否则,将返回 alternative。 +func Ternary[T any](condition bool, consequent, alternative T) T { + if condition { + return consequent + } else { + return alternative + } +} + +// 与 [Ternary] 类似,但返回值支持延迟计算函数。 +// +// 入参: +// - condition: 条件。 +// - consequentFunc: 条件为真时返回的计算函数。 +// - alternativeFunc: 条件为假时返回的计算函数。 +// +// 出参: +// - 若 condition 的为真,将返回 consequentFunc 的计算结果;否则,将返回 alternativeFunc 的计算结果。 +func TernaryFunc[T any](condition bool, consequentFunc, alternativeFunc func() T) T { + if condition { + return consequentFunc() + } else { + return alternativeFunc() + } +} diff --git a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx index 15f627a9..318e3c95 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx @@ -85,6 +85,7 @@ import DeployNodeConfigFormTencentCloudECDNConfig from "./DeployNodeConfigFormTe import DeployNodeConfigFormTencentCloudEOConfig from "./DeployNodeConfigFormTencentCloudEOConfig.tsx"; import DeployNodeConfigFormTencentCloudGAAPConfig from "./DeployNodeConfigFormTencentCloudGAAPConfig.tsx"; import DeployNodeConfigFormTencentCloudSCFConfig from "./DeployNodeConfigFormTencentCloudSCFConfig"; +import DeployNodeConfigFormTencentCloudSSLConfig from "./DeployNodeConfigFormTencentCloudSSLConfig"; import DeployNodeConfigFormTencentCloudSSLDeployConfig from "./DeployNodeConfigFormTencentCloudSSLDeployConfig"; import DeployNodeConfigFormTencentCloudVODConfig from "./DeployNodeConfigFormTencentCloudVODConfig"; import DeployNodeConfigFormTencentCloudWAFConfig from "./DeployNodeConfigFormTencentCloudWAFConfig"; @@ -344,6 +345,8 @@ const DeployNodeConfigForm = forwardRef; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SCF: return ; + case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SSL: + return ; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SSL_DEPLOY: return ; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_VOD: diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunALBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunALBConfig.tsx index 570109e5..5203130e 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunALBConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunALBConfig.tsx @@ -7,8 +7,8 @@ import Show from "@/components/Show"; import { validDomainName } from "@/utils/validators"; type DeployNodeConfigFormAliyunALBConfigFieldValues = Nullish<{ - resourceType: string; region: string; + resourceType: string; loadbalancerId?: string; listenerId?: string; domain?: string; @@ -41,12 +41,12 @@ const DeployNodeConfigFormAliyunALBConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - resourceType: z.union([z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { - message: t("workflow_node.deploy.form.aliyun_alb_resource_type.placeholder"), - }), region: z .string({ message: t("workflow_node.deploy.form.aliyun_alb_region.placeholder") }) .nonempty(t("workflow_node.deploy.form.aliyun_alb_region.placeholder")), + resourceType: z.union([z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { + message: t("workflow_node.deploy.form.aliyun_alb_resource_type.placeholder"), + }), loadbalancerId: z .string() .max(64, t("common.errmsg.string_max", { max: 64 })) @@ -82,6 +82,15 @@ const DeployNodeConfigFormAliyunALBConfig = ({ name={formName} onValuesChange={handleFormChange} > + } + > + + + - } - > - - - + } + > + + + - } - > - - - ; @@ -39,12 +39,12 @@ const DeployNodeConfigFormAliyunNLBConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - resourceType: z.union([z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { - message: t("workflow_node.deploy.form.aliyun_nlb_resource_type.placeholder"), - }), region: z .string({ message: t("workflow_node.deploy.form.aliyun_nlb_region.placeholder") }) .nonempty(t("workflow_node.deploy.form.aliyun_nlb_region.placeholder")), + resourceType: z.union([z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { + message: t("workflow_node.deploy.form.aliyun_nlb_resource_type.placeholder"), + }), loadbalancerId: z .string() .max(64, t("common.errmsg.string_max", { max: 64 })) @@ -73,6 +73,15 @@ const DeployNodeConfigFormAliyunNLBConfig = ({ name={formName} onValuesChange={handleFormChange} > + } + > + + + - } - > - - - + } + > + + + - } - > - - - + } + > + + + - } - > - - - + } + > + + + - } - > - - - + } + > + + + - } - > - - - + } + > + + + - } - > - - - + } + > + + + - } - > - - - ; @@ -31,6 +32,7 @@ const DeployNodeConfigFormTencentCloudCDNConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ + endpoint: z.string().nullish(), domain: z .string({ message: t("workflow_node.deploy.form.tencentcloud_cdn_domain.placeholder") }) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), @@ -50,6 +52,15 @@ const DeployNodeConfigFormTencentCloudCDNConfig = ({ name={formName} onValuesChange={handleFormChange} > + } + > + + + + } + > + + + + } + > + + + - } - > - - - ; @@ -31,6 +32,7 @@ const DeployNodeConfigFormTencentCloudCSSConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ + endpoint: z.string().nullish(), domain: z .string({ message: t("workflow_node.deploy.form.tencentcloud_css_domain.placeholder") }) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), @@ -50,6 +52,15 @@ const DeployNodeConfigFormTencentCloudCSSConfig = ({ name={formName} onValuesChange={handleFormChange} > + } + > + + + ; @@ -31,6 +32,7 @@ const DeployNodeConfigFormTencentCloudECDNConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ + endpoint: z.string().nullish(), domain: z .string({ message: t("workflow_node.deploy.form.tencentcloud_ecdn_domain.placeholder") }) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), @@ -50,6 +52,15 @@ const DeployNodeConfigFormTencentCloudECDNConfig = ({ name={formName} onValuesChange={handleFormChange} > + } + > + + + ; @@ -32,6 +33,7 @@ const DeployNodeConfigFormTencentCloudEOConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ + endpoint: z.string().nullish(), zoneId: z .string({ message: t("workflow_node.deploy.form.tencentcloud_eo_zone_id.placeholder") }) .nonempty(t("workflow_node.deploy.form.tencentcloud_eo_zone_id.placeholder")), @@ -54,6 +56,15 @@ const DeployNodeConfigFormTencentCloudEOConfig = ({ name={formName} onValuesChange={handleFormChange} > + } + > + + + + } + > + + + + + ; + +export type DeployNodeConfigFormTencentCloudSSLConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: DeployNodeConfigFormTencentCloudSSLConfigFieldValues; + onValuesChange?: (values: DeployNodeConfigFormTencentCloudSSLConfigFieldValues) => void; +}; + +const initFormModel = (): DeployNodeConfigFormTencentCloudSSLConfigFieldValues => { + return {}; +}; + +const DeployNodeConfigFormTencentCloudSSLConfig = ({ + form: formInst, + formName, + disabled, + initialValues, + onValuesChange, +}: DeployNodeConfigFormTencentCloudSSLConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + endpoint: z.string().nullish(), + }); + const formRule = createSchemaFieldRule(formSchema); + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( +
+ } + > + + +
+ ); +}; + +export default DeployNodeConfigFormTencentCloudSSLConfig; diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLDeployConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLDeployConfig.tsx index a0477fbf..b003876c 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLDeployConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLDeployConfig.tsx @@ -6,6 +6,7 @@ import { z } from "zod"; import MultipleSplitValueInput from "@/components/MultipleSplitValueInput"; type DeployNodeConfigFormTencentCloudSSLDeployConfigFieldValues = Nullish<{ + endpoint?: string; region: string; resourceType: string; resourceIds: string; @@ -35,6 +36,7 @@ const DeployNodeConfigFormTencentCloudSSLDeployConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ + endpoint: z.string().nullish(), region: z .string({ message: t("workflow_node.deploy.form.tencentcloud_ssl_deploy_region.placeholder") }) .nonempty(t("workflow_node.deploy.form.tencentcloud_ssl_deploy_region.placeholder")), @@ -63,6 +65,15 @@ const DeployNodeConfigFormTencentCloudSSLDeployConfig = ({ name={formName} onValuesChange={handleFormChange} > + } + > + + + ; @@ -32,6 +33,7 @@ const DeployNodeConfigFormTencentCloudVODConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ + endpoint: z.string().nullish(), subAppId: z .union([z.string(), z.number()]) .nullish() @@ -58,6 +60,15 @@ const DeployNodeConfigFormTencentCloudVODConfig = ({ name={formName} onValuesChange={handleFormChange} > + } + > + + + + } + > + + + + } + > + + + - } - > - - - ; @@ -39,12 +39,12 @@ const DeployNodeConfigFormVolcEngineCLBConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - resourceType: z.union([z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { - message: t("workflow_node.deploy.form.volcengine_clb_resource_type.placeholder"), - }), region: z .string({ message: t("workflow_node.deploy.form.volcengine_clb_region.placeholder") }) .nonempty(t("workflow_node.deploy.form.volcengine_clb_region.placeholder")), + resourceType: z.union([z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { + message: t("workflow_node.deploy.form.volcengine_clb_resource_type.placeholder"), + }), loadbalancerId: z .string() .max(64, t("common.errmsg.string_max", { max: 64 })) @@ -79,6 +79,15 @@ const DeployNodeConfigFormVolcEngineCLBConfig = ({ name={formName} onValuesChange={handleFormChange} > + } + > + + + - } - > - - - https://www.alibabacloud.com/help/en/slb/application-load-balancer/product-overview/supported-regions-and-zones", "workflow_node.deploy.form.aliyun_alb_resource_type.label": "Resource type", "workflow_node.deploy.form.aliyun_alb_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.aliyun_alb_resource_type.option.loadbalancer.label": "ALB load balancer", "workflow_node.deploy.form.aliyun_alb_resource_type.option.listener.label": "ALB listener", - "workflow_node.deploy.form.aliyun_alb_region.label": "Alibaba Cloud ALB region", - "workflow_node.deploy.form.aliyun_alb_region.placeholder": "Please enter Alibaba Cloud ALB region (e.g. cn-hangzhou)", - "workflow_node.deploy.form.aliyun_alb_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/slb/application-load-balancer/product-overview/supported-regions-and-zones", "workflow_node.deploy.form.aliyun_alb_loadbalancer_id.label": "Alibaba Cloud ALB load balancer ID", "workflow_node.deploy.form.aliyun_alb_loadbalancer_id.placeholder": "Please enter Alibaba Cloud ALB load balancer ID", "workflow_node.deploy.form.aliyun_alb_loadbalancer_id.tooltip": "For more information, see https://slb.console.aliyun.com/alb", @@ -185,13 +185,13 @@ "workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.tooltip": "For more information, see https://www.alibabacloud.com/help/en/ssl-certificate/developer-reference/api-cas-2020-04-07-listcontact

Leave it blank to use the first system contact.", "workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.multiple_input_modal.title": "Change Alibaba Cloud contact IDs", "workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.multiple_input_modal.placeholder": "Please enter Alibaba Cloud contact ID", + "workflow_node.deploy.form.aliyun_clb_region.label": "Alibaba Cloud CLB region", + "workflow_node.deploy.form.aliyun_clb_region.placeholder": "Please enter Alibaba Cloud CLB region (e.g. cn-hangzhou)", + "workflow_node.deploy.form.aliyun_clb_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/slb/classic-load-balancer/product-overview/regions-that-support-clb", "workflow_node.deploy.form.aliyun_clb_resource_type.label": "Resource type", "workflow_node.deploy.form.aliyun_clb_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.aliyun_clb_resource_type.option.loadbalancer.label": "CLB load balancer", "workflow_node.deploy.form.aliyun_clb_resource_type.option.listener.label": "CLB listener", - "workflow_node.deploy.form.aliyun_clb_region.label": "Alibaba Cloud CLB region", - "workflow_node.deploy.form.aliyun_clb_region.placeholder": "Please enter Alibaba Cloud CLB region (e.g. cn-hangzhou)", - "workflow_node.deploy.form.aliyun_clb_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/slb/classic-load-balancer/product-overview/regions-that-support-clb", "workflow_node.deploy.form.aliyun_clb_loadbalancer_id.label": "Alibaba Cloud CLB load balancer ID", "workflow_node.deploy.form.aliyun_clb_loadbalancer_id.placeholder": "Please enter Alibaba Cloud CLB load balancer ID", "workflow_node.deploy.form.aliyun_clb_loadbalancer_id.tooltip": "For more information, see https://slb.console.aliyun.com/clb", @@ -246,13 +246,13 @@ "workflow_node.deploy.form.aliyun_live_domain.label": "Alibaba Cloud live streaming domain", "workflow_node.deploy.form.aliyun_live_domain.placeholder": "Please enter Alibaba Cloud live streaming domain name", "workflow_node.deploy.form.aliyun_live_domain.tooltip": "For more information, see https://live.console.aliyun.com", + "workflow_node.deploy.form.aliyun_nlb_region.label": "Alibaba Cloud NLB region", + "workflow_node.deploy.form.aliyun_nlb_region.placeholder": "Please enter Alibaba Cloud NLB region (e.g. cn-hangzhou)", + "workflow_node.deploy.form.aliyun_nlb_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/slb/network-load-balancer/product-overview/regions-that-support-nlb", "workflow_node.deploy.form.aliyun_nlb_resource_type.label": "Resource type", "workflow_node.deploy.form.aliyun_nlb_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.aliyun_nlb_resource_type.option.loadbalancer.label": "NLB load balancer", "workflow_node.deploy.form.aliyun_nlb_resource_type.option.listener.label": "NLB listener", - "workflow_node.deploy.form.aliyun_nlb_region.label": "Alibaba Cloud NLB region", - "workflow_node.deploy.form.aliyun_nlb_region.placeholder": "Please enter Alibaba Cloud NLB region (e.g. cn-hangzhou)", - "workflow_node.deploy.form.aliyun_nlb_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/slb/network-load-balancer/product-overview/regions-that-support-nlb", "workflow_node.deploy.form.aliyun_nlb_loadbalancer_id.label": "Alibaba Cloud NLB load balancer ID", "workflow_node.deploy.form.aliyun_nlb_loadbalancer_id.placeholder": "Please enter Alibaba Cloud NLB load balancer ID", "workflow_node.deploy.form.aliyun_nlb_loadbalancer_id.tooltip": "For more information, see https://slb.console.aliyun.com/nlb", @@ -319,13 +319,13 @@ "workflow_node.deploy.form.azure_keyvault_certificate_name.placeholder": "Please enter Azure KeyVault certificate name", "workflow_node.deploy.form.azure_keyvault_certificate_name.tooltip": "Leave it blank to use a default name generated by Certimate.", "workflow_node.deploy.form.azure_keyvault_certificate_name.errmsg.invalid": "Certificate name can only contain letters, numbers, and hyphens (-), with a length limit of 1 to 127 characters", + "workflow_node.deploy.form.baiducloud_appblb_region.label": "Baidu Cloud BLB region", + "workflow_node.deploy.form.baiducloud_appblb_region.placeholder": "Please enter Baidu Cloud BLB region (e.g. bj)", + "workflow_node.deploy.form.baiducloud_appblb_region.tooltip": "For more information, see https://cloud.baidu.com/doc/BLB/s/cjwvxnzix", "workflow_node.deploy.form.baiducloud_appblb_resource_type.label": "Resource type", "workflow_node.deploy.form.baiducloud_appblb_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.baiducloud_appblb_resource_type.option.loadbalancer.label": "BLB load balancer", "workflow_node.deploy.form.baiducloud_appblb_resource_type.option.listener.label": "BLB listener", - "workflow_node.deploy.form.baiducloud_appblb_region.label": "Baidu Cloud BLB region", - "workflow_node.deploy.form.baiducloud_appblb_region.placeholder": "Please enter Baidu Cloud BLB region (e.g. bj)", - "workflow_node.deploy.form.baiducloud_appblb_region.tooltip": "For more information, see https://cloud.baidu.com/doc/BLB/s/cjwvxnzix", "workflow_node.deploy.form.baiducloud_appblb_loadbalancer_id.label": "Baidu Cloud BLB load balancer ID", "workflow_node.deploy.form.baiducloud_appblb_loadbalancer_id.placeholder": "Please enter Baidu Cloud BLB load balancer ID", "workflow_node.deploy.form.baiducloud_appblb_loadbalancer_id.tooltip": "For more information, see https://console.bce.baidu.com/blb/#/appblb/list", @@ -335,13 +335,13 @@ "workflow_node.deploy.form.baiducloud_appblb_snidomain.label": "Baidu Cloud BLB SNI domain (Optional)", "workflow_node.deploy.form.baiducloud_appblb_snidomain.placeholder": "Please enter Baidu Cloud BLB SNI domain name", "workflow_node.deploy.form.baiducloud_appblb_snidomain.tooltip": "For more information, see https://console.bce.baidu.com/blb/#/appblb/list", + "workflow_node.deploy.form.baiducloud_blb_region.label": "Baidu Cloud BLB region", + "workflow_node.deploy.form.baiducloud_blb_region.placeholder": "Please enter Baidu Cloud BLB region (e.g. bj)", + "workflow_node.deploy.form.baiducloud_blb_region.tooltip": "For more information, see https://cloud.baidu.com/doc/BLB/s/cjwvxnzix", "workflow_node.deploy.form.baiducloud_blb_resource_type.label": "Resource type", "workflow_node.deploy.form.baiducloud_blb_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.baiducloud_blb_resource_type.option.loadbalancer.label": "BLB load balancer", "workflow_node.deploy.form.baiducloud_blb_resource_type.option.listener.label": "BLB listener", - "workflow_node.deploy.form.baiducloud_blb_region.label": "Baidu Cloud BLB region", - "workflow_node.deploy.form.baiducloud_blb_region.placeholder": "Please enter Baidu Cloud BLB region (e.g. bj)", - "workflow_node.deploy.form.baiducloud_blb_region.tooltip": "For more information, see https://cloud.baidu.com/doc/BLB/s/cjwvxnzix", "workflow_node.deploy.form.baiducloud_blb_loadbalancer_id.label": "Baidu Cloud BLB load balancer ID", "workflow_node.deploy.form.baiducloud_blb_loadbalancer_id.placeholder": "Please enter Baidu Cloud BLB load balancer ID", "workflow_node.deploy.form.baiducloud_blb_loadbalancer_id.tooltip": "For more information, see https://console.bce.baidu.com/blb/#/blb/list", @@ -404,14 +404,14 @@ "workflow_node.deploy.form.ctcccloud_cdn_domain.label": "CTCC StateCloud CDN domain", "workflow_node.deploy.form.ctcccloud_cdn_domain.placeholder": "Please enter CTCC StateCloud CDN domain name", "workflow_node.deploy.form.ctcccloud_cdn_domain.tooltip": "For more information, see https://cdn-console.ctyun.cn", + "workflow_node.deploy.form.ctcccloud_elb_region_id.label": "CTCC StateCloud ELB region ID", + "workflow_node.deploy.form.ctcccloud_elb_region_id.placeholder": "Please enter CTCC StateCloud ELB region ID", + "workflow_node.deploy.form.ctcccloud_elb_region_id.tooltip": "For more information, see https://www.ctyun.cn/document/10026755/10196575", "workflow_node.deploy.form.ctcccloud_elb_resource_type.label": "Resource type", "workflow_node.deploy.form.ctcccloud_elb_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.ctcccloud_elb_resource_type.option.certificate.label": "ELB certificate", "workflow_node.deploy.form.ctcccloud_elb_resource_type.option.loadbalancer.label": "ELB load balancer", "workflow_node.deploy.form.ctcccloud_elb_resource_type.option.listener.label": "ELB listener", - "workflow_node.deploy.form.ctcccloud_elb_region_id.label": "CTCC StateCloud ELB region ID", - "workflow_node.deploy.form.ctcccloud_elb_region_id.placeholder": "Please enter CTCC StateCloud ELB region ID", - "workflow_node.deploy.form.ctcccloud_elb_region_id.tooltip": "For more information, see https://www.ctyun.cn/document/10026755/10196575", "workflow_node.deploy.form.ctcccloud_elb_loadbalancer_id.label": "CTCC StateCloud ELB load balancer ID", "workflow_node.deploy.form.ctcccloud_elb_loadbalancer_id.placeholder": "Please enter CTCC StateCloud ELB load balancer ID", "workflow_node.deploy.form.ctcccloud_elb_loadbalancer_id.tooltip": "For more information, see https://console.ctyun.cn/network/index/#/elb/elbList", @@ -454,14 +454,14 @@ "workflow_node.deploy.form.huaweicloud_cdn_domain.label": "Huawei Cloud CDN domain", "workflow_node.deploy.form.huaweicloud_cdn_domain.placeholder": "Please enter Huawei Cloud CDN domain name", "workflow_node.deploy.form.huaweicloud_cdn_domain.tooltip": "For more information, see https://console-intl.huaweicloud.com/cdn", + "workflow_node.deploy.form.huaweicloud_elb_region.label": "Huawei Cloud ELB region", + "workflow_node.deploy.form.huaweicloud_elb_region.placeholder": "Please enter Huawei Cloud ELB region (e.g. cn-north-1)", + "workflow_node.deploy.form.huaweicloud_elb_region.tooltip": "For more information, see https://console-intl.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_elb_resource_type.label": "Resource type", "workflow_node.deploy.form.huaweicloud_elb_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.huaweicloud_elb_resource_type.option.certificate.label": "ELB certificate", "workflow_node.deploy.form.huaweicloud_elb_resource_type.option.loadbalancer.label": "ELB load balancer", "workflow_node.deploy.form.huaweicloud_elb_resource_type.option.listener.label": "ELB listener", - "workflow_node.deploy.form.huaweicloud_elb_region.label": "Huawei Cloud ELB region", - "workflow_node.deploy.form.huaweicloud_elb_region.placeholder": "Please enter Huawei Cloud ELB region (e.g. cn-north-1)", - "workflow_node.deploy.form.huaweicloud_elb_region.tooltip": "For more information, see https://console-intl.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_elb_certificate_id.label": "Huawei Cloud ELB certificate ID", "workflow_node.deploy.form.huaweicloud_elb_certificate_id.placeholder": "Please enter Huawei Cloud ELB certificate ID", "workflow_node.deploy.form.huaweicloud_elb_certificate_id.tooltip": "For more information, see https://console-intl.huaweicloud.com/vpc/#/elb/elbCert", @@ -471,27 +471,27 @@ "workflow_node.deploy.form.huaweicloud_elb_listener_id.label": "Huawei Cloud ELB listener ID", "workflow_node.deploy.form.huaweicloud_elb_listener_id.placeholder": "Please enter Huawei Cloud ELB listener ID", "workflow_node.deploy.form.huaweicloud_elb_listener_id.tooltip": "For more information, see https://console-intl.huaweicloud.com/vpc/#/elb/list/grid", + "workflow_node.deploy.form.huaweicloud_waf_region.label": "Huawei Cloud WAF region", + "workflow_node.deploy.form.huaweicloud_waf_region.placeholder": "Please enter Huawei Cloud WAF region (e.g. cn-north-1)", + "workflow_node.deploy.form.huaweicloud_waf_region.tooltip": "For more information, see https://console-intl.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_waf_resource_type.label": "Resource type", "workflow_node.deploy.form.huaweicloud_waf_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.huaweicloud_waf_resource_type.option.certificate.label": "WAF certificate", "workflow_node.deploy.form.huaweicloud_waf_resource_type.option.cloudserver.label": "WAF cloud server", "workflow_node.deploy.form.huaweicloud_waf_resource_type.option.premiumhost.label": "WAF premium host", - "workflow_node.deploy.form.huaweicloud_waf_region.label": "Huawei Cloud WAF region", - "workflow_node.deploy.form.huaweicloud_waf_region.placeholder": "Please enter Huawei Cloud WAF region (e.g. cn-north-1)", - "workflow_node.deploy.form.huaweicloud_waf_region.tooltip": "For more information, see https://console-intl.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_waf_certificate_id.label": "Huawei Cloud WAF certificate ID", "workflow_node.deploy.form.huaweicloud_waf_certificate_id.placeholder": "Please enter Huawei Cloud WAF certificate ID", "workflow_node.deploy.form.huaweicloud_waf_certificate_id.tooltip": "For more information, see https://console-intl.huaweicloud.com/console/#/waf/certificateManagement", "workflow_node.deploy.form.huaweicloud_waf_domain.label": "Huawei Cloud WAF domain", "workflow_node.deploy.form.huaweicloud_waf_domain.placeholder": "Please enter Huawei Cloud WAF domain name", "workflow_node.deploy.form.huaweicloud_waf_domain.tooltip": "For more information, see https://console-intl.huaweicloud.com/console/#/waf/domain/list", + "workflow_node.deploy.form.jdcloud_alb_region_id.label": "JD Cloud ALB region ID", + "workflow_node.deploy.form.jdcloud_alb_region_id.placeholder": "Please enter JD Cloud ALB region ID (e.g. cn-north-1)", + "workflow_node.deploy.form.jdcloud_alb_region_id.tooltip": "For more information, see https://docs.jdcloud.com/en/common-declaration/api/introduction", "workflow_node.deploy.form.jdcloud_alb_resource_type.label": "Resource type", "workflow_node.deploy.form.jdcloud_alb_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.jdcloud_alb_resource_type.option.loadbalancer.label": "ALB load balancer", "workflow_node.deploy.form.jdcloud_alb_resource_type.option.listener.label": "ALB listener", - "workflow_node.deploy.form.jdcloud_alb_region_id.label": "JD Cloud ALB region ID", - "workflow_node.deploy.form.jdcloud_alb_region_id.placeholder": "Please enter JD Cloud ALB region ID (e.g. cn-north-1)", - "workflow_node.deploy.form.jdcloud_alb_region_id.tooltip": "For more information, see https://docs.jdcloud.com/en/common-declaration/api/introduction", "workflow_node.deploy.form.jdcloud_alb_loadbalancer_id.label": "JD Cloud ALB load balancer ID", "workflow_node.deploy.form.jdcloud_alb_loadbalancer_id.placeholder": "Please enter JD Cloud ALB load balancer ID", "workflow_node.deploy.form.jdcloud_alb_loadbalancer_id.tooltip": "For more information, see https://cns-console.jdcloud.com/host/loadBalance/list", @@ -658,18 +658,24 @@ "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_rdp.label": "PowerShell - Binding RDP", "workflow_node.deploy.form.ssh_use_scp.label": "Fallback to use SCP", "workflow_node.deploy.form.ssh_use_scp.tooltip": "If the remote server does not support SFTP, please enable this option to fallback to SCP.", + "workflow_node.deploy.form.tencentcloud_cdn_endpoint.label": "Tencent Cloud CDN API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_cdn_endpoint.placeholder": "Please enter Tencent Cloud CDN API endpoint (e.g. cdn.intl.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_cdn_endpoint.tooltip": "
  • cdn.intl.tencentcloudapi.com for Tencent Cloud International
  • cdn.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_cdn_domain.label": "Tencent Cloud CDN domain", "workflow_node.deploy.form.tencentcloud_cdn_domain.placeholder": "Please enter Tencent Cloud CDN domain name", "workflow_node.deploy.form.tencentcloud_cdn_domain.tooltip": "For more information, see https://console.tencentcloud.com/cdn", + "workflow_node.deploy.form.tencentcloud_clb_endpoint.label": "Tencent Cloud CLB API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_clb_endpoint.placeholder": "Please enter Tencent Cloud CLB API endpoint (e.g. clb.intl.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_clb_endpoint.tooltip": "
  • clb.intl.tencentcloudapi.com for Tencent Cloud International
  • clb.tencentcloudapi.com for Tencent Cloud in China
", + "workflow_node.deploy.form.tencentcloud_clb_region.label": "Tencent Cloud CLB region", + "workflow_node.deploy.form.tencentcloud_clb_region.placeholder": "Please enter Tencent Cloud CLB region (e.g. ap-guangzhou)", + "workflow_node.deploy.form.tencentcloud_clb_region.tooltip": "For more information, see https://www.tencentcloud.com/document/product/214/13629", "workflow_node.deploy.form.tencentcloud_clb_resource_type.label": "Resource type", "workflow_node.deploy.form.tencentcloud_clb_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.tencentcloud_clb_resource_type.option.ssl_deploy.label": "Via SSL deploy", "workflow_node.deploy.form.tencentcloud_clb_resource_type.option.loadbalancer.label": "CLB instance", "workflow_node.deploy.form.tencentcloud_clb_resource_type.option.listener.label": "CLB listener", "workflow_node.deploy.form.tencentcloud_clb_resource_type.option.ruledomain.label": "CLB rule domain", - "workflow_node.deploy.form.tencentcloud_clb_region.label": "Tencent Cloud CLB region", - "workflow_node.deploy.form.tencentcloud_clb_region.placeholder": "Please enter Tencent Cloud CLB region (e.g. ap-guangzhou)", - "workflow_node.deploy.form.tencentcloud_clb_region.tooltip": "For more information, see https://www.tencentcloud.com/document/product/214/13629", "workflow_node.deploy.form.tencentcloud_clb_loadbalancer_id.label": "Tencent Cloud CLB instance ID", "workflow_node.deploy.form.tencentcloud_clb_loadbalancer_id.placeholder": "Please enter Tencent Cloud CLB instance ID", "workflow_node.deploy.form.tencentcloud_clb_loadbalancer_id.tooltip": "For more information, see https://console.tencentcloud.com/clb", @@ -691,18 +697,30 @@ "workflow_node.deploy.form.tencentcloud_cos_domain.label": "Tencent Cloud COS domain", "workflow_node.deploy.form.tencentcloud_cos_domain.placeholder": "Please enter Tencent Cloud COS domain name", "workflow_node.deploy.form.tencentcloud_cos_domain.tooltip": "For more information, see https://console.tencentcloud.com/cos", + "workflow_node.deploy.form.tencentcloud_css_endpoint.label": "Tencent Cloud CSS API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_css_endpoint.placeholder": "Please enter Tencent Cloud CSS API endpoint (e.g. live.intl.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_css_endpoint.tooltip": "
  • live.intl.tencentcloudapi.com for Tencent Cloud International
  • live.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_css_domain.label": "Tencent Cloud CSS play domain", "workflow_node.deploy.form.tencentcloud_css_domain.placeholder": "Please enter Tencent Cloud CSS play domain name", "workflow_node.deploy.form.tencentcloud_css_domain.tooltip": "For more information, see https://console.tencentcloud.com/live", + "workflow_node.deploy.form.tencentcloud_ecdn_endpoint.label": "Tencent Cloud ECDN API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_ecdn_endpoint.placeholder": "Please enter Tencent Cloud ECDN API endpoint (e.g. cdn.intl.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_ecdn_endpoint.tooltip": "
  • cdn.intl.tencentcloudapi.com for Tencent Cloud International
  • cdn.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_ecdn_domain.label": "Tencent Cloud ECDN domain", "workflow_node.deploy.form.tencentcloud_ecdn_domain.placeholder": "Please enter Tencent Cloud ECDN domain name", "workflow_node.deploy.form.tencentcloud_ecdn_domain.tooltip": "For more information, see https://console.tencentcloud.com/cdn", + "workflow_node.deploy.form.tencentcloud_eo_endpoint.label": "Tencent Cloud EdgeOne API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_eo_endpoint.placeholder": "Please enter Tencent Cloud EdgeOne API endpoint (e.g. teo.intl.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_eo_endpoint.tooltip": "
  • cdn.intl.tencentcloudapi.com for Tencent Cloud International
  • teo.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_eo_zone_id.label": "Tencent Cloud EdgeOne zone ID", "workflow_node.deploy.form.tencentcloud_eo_zone_id.placeholder": "Please enter Tencent Cloud EdgeOne zone ID", "workflow_node.deploy.form.tencentcloud_eo_zone_id.tooltip": "For more information, see https://console.tencentcloud.com/edgeone", "workflow_node.deploy.form.tencentcloud_eo_domain.label": "Tencent Cloud EdgeOne domain", "workflow_node.deploy.form.tencentcloud_eo_domain.placeholder": "Please enter Tencent Cloud EdgeOne domain name", "workflow_node.deploy.form.tencentcloud_eo_domain.tooltip": "For more information, see https://console.tencentcloud.com/edgeone", + "workflow_node.deploy.form.tencentcloud_gaap_endpoint.label": "Tencent Cloud GAAP API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_gaap_endpoint.placeholder": "Please enter Tencent Cloud GAAP API endpoint (e.g. gaap.intl.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_gaap_endpoint.tooltip": "
  • gaap.intl.tencentcloudapi.com for Tencent Cloud International
  • gaap.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_gaap_resource_type.label": "Resource type", "workflow_node.deploy.form.tencentcloud_gaap_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.tencentcloud_gaap_resource_type.option.listener.label": "GAAP listener", @@ -712,13 +730,22 @@ "workflow_node.deploy.form.tencentcloud_gaap_listener_id.label": "Tencent Cloud GAAP listener ID", "workflow_node.deploy.form.tencentcloud_gaap_listener_id.placeholder": "Please enter Tencent Cloud GAAP listener ID", "workflow_node.deploy.form.tencentcloud_gaap_listener_id.tooltip": "For more information, see https://console.tencentcloud.com/gaap", + "workflow_node.deploy.form.tencentcloud_scf_endpoint.label": "Tencent Cloud SCF API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_scf_endpoint.placeholder": "Please enter Tencent Cloud SCF API endpoint (e.g. scf.intl.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_scf_endpoint.tooltip": "
  • scf.intl.tencentcloudapi.com for Tencent Cloud International
  • scf.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_scf_region.label": "Tencent Cloud SCF region", "workflow_node.deploy.form.tencentcloud_scf_region.placeholder": "Please enter Tencent Cloud SCF region (e.g. ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_scf_region.tooltip": "For more information, see https://www.tencentcloud.com/document/product/583/17299", "workflow_node.deploy.form.tencentcloud_scf_domain.label": "Tencent Cloud SCF domain", "workflow_node.deploy.form.tencentcloud_scf_domain.placeholder": "Please enter Tencent Cloud SCF domain name", "workflow_node.deploy.form.tencentcloud_scf_domain.tooltip": "For more information, see https://console.tencentcloud.com/scf", + "workflow_node.deploy.form.tencentcloud_ssl_endpoint.label": "Tencent Cloud SSL API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_ssl_endpoint.placeholder": "Please enter Tencent Cloud SSL API endpoint (e.g. ssl.intl.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_ssl_endpoint.tooltip": "
  • ssl.intl.tencentcloudapi.com for Tencent Cloud International
  • ssl.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_ssl_deploy.guide": "TIPS: You need to go to the Tencent Cloud console to check the actual deployment results by yourself, because Tencent Cloud deployment tasks are running asynchronously.", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_endpoint.label": "Tencent Cloud SSL API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_endpoint.placeholder": "Please enter Tencent Cloud SSL API endpoint (e.g. ssl.intl.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_endpoint.tooltip": "
  • ssl.intl.tencentcloudapi.com for Tencent Cloud International
  • ssl.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_ssl_deploy_region.label": "Tencent Cloud service region", "workflow_node.deploy.form.tencentcloud_ssl_deploy_region.placeholder": "Please enter Tencent Cloud service region (e.g. ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_ssl_deploy_region.tooltip": "For more information, see https://www.tencentcloud.com/document/product/1007/36573", @@ -731,12 +758,18 @@ "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.tooltip": "For more information, see https://cloud.tencent.com/document/product/400/91667", "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.title": "Change Tencent Cloud resource IDs", "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.placeholder": "Please enter Tencent Cloud resouce ID", + "workflow_node.deploy.form.tencentcloud_vod_endpoint.label": "Tencent Cloud VOD API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_vod_endpoint.placeholder": "Please enter Tencent Cloud VOD API endpoint (e.g. vod.intl.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_vod_endpoint.tooltip": "
  • vod.intl.tencentcloudapi.com for Tencent Cloud International
  • vod.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_vod_sub_app_id.label": "Tencent Cloud VOD App ID", "workflow_node.deploy.form.tencentcloud_vod_sub_app_id.placeholder": "Please enter Tencent Cloud VOD App ID", "workflow_node.deploy.form.tencentcloud_vod_sub_app_id.tooltip": "For more information, see https://console.tencentcloud.com/vod", "workflow_node.deploy.form.tencentcloud_vod_domain.label": "Tencent Cloud VOD domain", "workflow_node.deploy.form.tencentcloud_vod_domain.placeholder": "Please enter Tencent Cloud VOD domain name", "workflow_node.deploy.form.tencentcloud_vod_domain.tooltip": "For more information, see https://console.tencentcloud.com/vod", + "workflow_node.deploy.form.tencentcloud_waf_endpoint.label": "Tencent Cloud WAF API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_waf_endpoint.placeholder": "Please enter Tencent Cloud WAF API endpoint (e.g. waf.intl.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_waf_endpoint.tooltip": "
  • waf.intl.tencentcloudapi.com for Tencent Cloud International
  • waf.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_waf_region.label": "Tencent Cloud WAF region", "workflow_node.deploy.form.tencentcloud_waf_region.placeholder": "Please enter Tencent Cloud WAF region (e.g. ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_waf_region.tooltip": "For more information, see https://www.tencentcloud.com/document/product/627/38085", @@ -779,13 +812,13 @@ "workflow_node.deploy.form.upyun_file_domain.label": "UPYUN bucket domain", "workflow_node.deploy.form.upyun_file_domain.placeholder": "Please enter UPYUN bucket domain name", "workflow_node.deploy.form.upyun_file_domain.tooltip": "For more information, see https://console.upyun.com/services/file/", + "workflow_node.deploy.form.volcengine_alb_region.label": "VolcEngine ALB region", + "workflow_node.deploy.form.volcengine_alb_region.placeholder": "Please enter VolcEngine ALB region (e.g. cn-beijing)", + "workflow_node.deploy.form.volcengine_alb_region.tooltip": "For more information, see https://www.volcengine.com/docs/6767/127501", "workflow_node.deploy.form.volcengine_alb_resource_type.label": "Resource type", "workflow_node.deploy.form.volcengine_alb_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.volcengine_alb_resource_type.option.loadbalancer.label": "ALB load balancer", "workflow_node.deploy.form.volcengine_alb_resource_type.option.listener.label": "ALB listener", - "workflow_node.deploy.form.volcengine_alb_region.label": "VolcEngine ALB region", - "workflow_node.deploy.form.volcengine_alb_region.placeholder": "Please enter VolcEngine ALB region (e.g. cn-beijing)", - "workflow_node.deploy.form.volcengine_alb_region.tooltip": "For more information, see https://www.volcengine.com/docs/6767/127501", "workflow_node.deploy.form.volcengine_alb_loadbalancer_id.label": "VolcEngine ALB load balancer ID", "workflow_node.deploy.form.volcengine_alb_loadbalancer_id.placeholder": "Please enter VolcEngine ALB load balancer ID", "workflow_node.deploy.form.volcengine_alb_loadbalancer_id.tooltip": "For more information, see https://console.volcengine.com/alb", @@ -800,13 +833,13 @@ "workflow_node.deploy.form.volcengine_cdn_domain.tooltip": "For more information, see https://console.volcengine.com/cdn/homepage", "workflow_node.deploy.form.volcengine_certcenter_region.label": "VolcEngine Certificate Center region", "workflow_node.deploy.form.volcengine_certcenter_region.placeholder": "Please enter VolcEngine Certificate Center region (e.g. cn-beijing)", + "workflow_node.deploy.form.volcengine_clb_region.label": "VolcEngine CLB region", + "workflow_node.deploy.form.volcengine_clb_region.placeholder": "Please enter VolcEngine CLB region (e.g. cn-beijing)", + "workflow_node.deploy.form.volcengine_clb_region.tooltip": "For more information, see https://www.volcengine.com/docs/6406/74892", "workflow_node.deploy.form.volcengine_clb_resource_type.label": "Resource type", "workflow_node.deploy.form.volcengine_clb_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.volcengine_clb_resource_type.option.loadbalancer.label": "CLB load balancer", "workflow_node.deploy.form.volcengine_clb_resource_type.option.listener.label": "CLB listener", - "workflow_node.deploy.form.volcengine_clb_region.label": "VolcEngine CLB region", - "workflow_node.deploy.form.volcengine_clb_region.placeholder": "Please enter VolcEngine CLB region (e.g. cn-beijing)", - "workflow_node.deploy.form.volcengine_clb_region.tooltip": "For more information, see https://www.volcengine.com/docs/6406/74892", "workflow_node.deploy.form.volcengine_clb_loadbalancer_id.label": "VolcEngine CLB load balancer ID", "workflow_node.deploy.form.volcengine_clb_loadbalancer_id.placeholder": "Please enter VolcEngine CLB load balancer ID", "workflow_node.deploy.form.volcengine_clb_loadbalancer_id.tooltip": "For more information, see https://console.volcengine.com/clb/LoadBalancer", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index cdb519db..1639339a 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -133,13 +133,13 @@ "workflow_node.deploy.form.1panel_site_certificate_id.label": "1Panel 证书 ID", "workflow_node.deploy.form.1panel_site_certificate_id.placeholder": "请输入 1Panel 证书 ID", "workflow_node.deploy.form.1panel_site_certificate_id.tooltip": "请登录 1Panel 面板查看。", + "workflow_node.deploy.form.aliyun_alb_region.label": "阿里云 ALB 服务地域", + "workflow_node.deploy.form.aliyun_alb_region.placeholder": "请输入阿里云 ALB 服务地域(例如:cn-hangzhou)", + "workflow_node.deploy.form.aliyun_alb_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/slb/application-load-balancer/product-overview/supported-regions-and-zones", "workflow_node.deploy.form.aliyun_alb_resource_type.label": "证书部署方式", "workflow_node.deploy.form.aliyun_alb_resource_type.placeholder": "请选择证书部署方式", "workflow_node.deploy.form.aliyun_alb_resource_type.option.loadbalancer.label": "替换指定负载均衡器下的全部 HTTPS/QUIC 监听的证书", "workflow_node.deploy.form.aliyun_alb_resource_type.option.listener.label": "替换指定负载均衡监听器的证书", - "workflow_node.deploy.form.aliyun_alb_region.label": "阿里云 ALB 服务地域", - "workflow_node.deploy.form.aliyun_alb_region.placeholder": "请输入阿里云 ALB 服务地域(例如:cn-hangzhou)", - "workflow_node.deploy.form.aliyun_alb_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/slb/application-load-balancer/product-overview/supported-regions-and-zones", "workflow_node.deploy.form.aliyun_alb_loadbalancer_id.label": "阿里云 ALB 负载均衡器 ID", "workflow_node.deploy.form.aliyun_alb_loadbalancer_id.placeholder": "请输入阿里云 ALB 负载均衡器 ID", "workflow_node.deploy.form.aliyun_alb_loadbalancer_id.tooltip": "这是什么?请参阅 https://slb.console.aliyun.com/alb", @@ -184,13 +184,13 @@ "workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-listcontact

不填写时,将使用系统联系人列表中的第一个。", "workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.multiple_input_modal.title": "修改阿里云联系人 ID", "workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.multiple_input_modal.placeholder": "请输入阿里云联系人 ID", + "workflow_node.deploy.form.aliyun_clb_region.label": "阿里云 CLB 服务地域", + "workflow_node.deploy.form.aliyun_clb_region.placeholder": "请输入阿里云 CLB 服务地域(例如:cn-hangzhou)", + "workflow_node.deploy.form.aliyun_clb_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/slb/classic-load-balancer/product-overview/regions-that-support-clb", "workflow_node.deploy.form.aliyun_clb_resource_type.label": "证书部署方式", "workflow_node.deploy.form.aliyun_clb_resource_type.placeholder": "请选择证书部署方式", "workflow_node.deploy.form.aliyun_clb_resource_type.option.loadbalancer.label": "替换指定负载均衡器下的全部 HTTPS 监听的证书", "workflow_node.deploy.form.aliyun_clb_resource_type.option.listener.label": "替换指定负载均衡监听的证书", - "workflow_node.deploy.form.aliyun_clb_region.label": "阿里云 CLB 服务地域", - "workflow_node.deploy.form.aliyun_clb_region.placeholder": "请输入阿里云 CLB 服务地域(例如:cn-hangzhou)", - "workflow_node.deploy.form.aliyun_clb_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/slb/classic-load-balancer/product-overview/regions-that-support-clb", "workflow_node.deploy.form.aliyun_clb_loadbalancer_id.label": "阿里云 CLB 负载均衡器 ID", "workflow_node.deploy.form.aliyun_clb_loadbalancer_id.placeholder": "请输入阿里云 CLB 负载均衡器 ID", "workflow_node.deploy.form.aliyun_clb_loadbalancer_id.tooltip": "这是什么?请参阅 https://slb.console.aliyun.com/clb", @@ -245,13 +245,13 @@ "workflow_node.deploy.form.aliyun_live_domain.label": "阿里云视频直播流域名", "workflow_node.deploy.form.aliyun_live_domain.placeholder": "请输入阿里云视频直播流域名(支持泛域名)", "workflow_node.deploy.form.aliyun_live_domain.tooltip": "这是什么?请参阅 https://live.console.aliyun.com", + "workflow_node.deploy.form.aliyun_nlb_region.label": "阿里云 NLB 服务地域", + "workflow_node.deploy.form.aliyun_nlb_region.placeholder": "请输入阿里云 NLB 服务地域(例如:cn-hangzhou)", + "workflow_node.deploy.form.aliyun_nlb_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/slb/network-load-balancer/product-overview/regions-that-support-nlb", "workflow_node.deploy.form.aliyun_nlb_resource_type.label": "证书部署方式", "workflow_node.deploy.form.aliyun_nlb_resource_type.placeholder": "请选择证书部署方式", "workflow_node.deploy.form.aliyun_nlb_resource_type.option.loadbalancer.label": "替换指定负载均衡器下的全部 HTTPS/QUIC 监听的证书", "workflow_node.deploy.form.aliyun_nlb_resource_type.option.listener.label": "替换指定负载均衡监听器的证书", - "workflow_node.deploy.form.aliyun_nlb_region.label": "阿里云 NLB 服务地域", - "workflow_node.deploy.form.aliyun_nlb_region.placeholder": "请输入阿里云 NLB 服务地域(例如:cn-hangzhou)", - "workflow_node.deploy.form.aliyun_nlb_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/slb/network-load-balancer/product-overview/regions-that-support-nlb", "workflow_node.deploy.form.aliyun_nlb_loadbalancer_id.label": "阿里云 NLB 负载均衡器 ID", "workflow_node.deploy.form.aliyun_nlb_loadbalancer_id.placeholder": "请输入阿里云 NLB 负载均衡器 ID", "workflow_node.deploy.form.aliyun_nlb_loadbalancer_id.tooltip": "这是什么?请参阅 https://slb.console.aliyun.com/nlb", @@ -318,13 +318,13 @@ "workflow_node.deploy.form.azure_keyvault_certificate_name.placeholder": "请输入 Azure KeyVault 证书名称", "workflow_node.deploy.form.azure_keyvault_certificate_name.tooltip": "不填写时,将由 Certimate 自动生成证书名称。", "workflow_node.deploy.form.azure_keyvault_certificate_name.errmsg.invalid": "证书名称只能包含字母、数字和连字符(-),长度限制为 1 到 127 个字符", + "workflow_node.deploy.form.baiducloud_appblb_region.label": "百度智能云 BLB 服务地域", + "workflow_node.deploy.form.baiducloud_appblb_region.placeholder": "请输入百度智能云 BLB 服务地域(例如:bj)", + "workflow_node.deploy.form.baiducloud_appblb_region.tooltip": "这是什么?请参阅 https://cloud.baidu.com/doc/BLB/s/cjwvxnzix", "workflow_node.deploy.form.baiducloud_appblb_resource_type.label": "证书部署方式", "workflow_node.deploy.form.baiducloud_appblb_resource_type.placeholder": "请选择证书部署方式", "workflow_node.deploy.form.baiducloud_appblb_resource_type.option.loadbalancer.label": "替换指定负载均衡器下的全部 HTTPS/SSL 监听的证书", "workflow_node.deploy.form.baiducloud_appblb_resource_type.option.listener.label": "替换指定负载均衡监听的证书", - "workflow_node.deploy.form.baiducloud_appblb_region.label": "百度智能云 BLB 服务地域", - "workflow_node.deploy.form.baiducloud_appblb_region.placeholder": "请输入百度智能云 BLB 服务地域(例如:bj)", - "workflow_node.deploy.form.baiducloud_appblb_region.tooltip": "这是什么?请参阅 https://cloud.baidu.com/doc/BLB/s/cjwvxnzix", "workflow_node.deploy.form.baiducloud_appblb_loadbalancer_id.label": "百度智能云 BLB 负载均衡器 ID", "workflow_node.deploy.form.baiducloud_appblb_loadbalancer_id.placeholder": "请输入百度智能云 BLB 负载均衡器 ID", "workflow_node.deploy.form.baiducloud_appblb_loadbalancer_id.tooltip": "这是什么?请参阅 https://console.bce.baidu.com/blb/#/appblb/list", @@ -334,13 +334,13 @@ "workflow_node.deploy.form.baiducloud_appblb_snidomain.label": "百度智能云 BLB 扩展域名(可选)", "workflow_node.deploy.form.baiducloud_appblb_snidomain.placeholder": "请输入百度智能云 BLB 扩展域名(支持泛域名)", "workflow_node.deploy.form.baiducloud_appblb_snidomain.tooltip": "这是什么?请参阅 https://console.bce.baidu.com/blb/#/appblb/list

不填写时,将替换监听器的默认证书;否则,将替换扩展域名证书。", + "workflow_node.deploy.form.baiducloud_blb_region.label": "百度智能云 BLB 服务地域", + "workflow_node.deploy.form.baiducloud_blb_region.placeholder": "请输入百度智能云 BLB 服务地域(例如:bj)", + "workflow_node.deploy.form.baiducloud_blb_region.tooltip": "这是什么?请参阅 https://cloud.baidu.com/doc/BLB/s/cjwvxnzix", "workflow_node.deploy.form.baiducloud_blb_resource_type.label": "证书部署方式", "workflow_node.deploy.form.baiducloud_blb_resource_type.placeholder": "请选择证书部署方式", "workflow_node.deploy.form.baiducloud_blb_resource_type.option.loadbalancer.label": "替换指定负载均衡器下的全部 HTTPS/SSL 监听的证书", "workflow_node.deploy.form.baiducloud_blb_resource_type.option.listener.label": "替换指定负载均衡监听的证书", - "workflow_node.deploy.form.baiducloud_blb_region.label": "百度智能云 BLB 服务地域", - "workflow_node.deploy.form.baiducloud_blb_region.placeholder": "请输入百度智能云 BLB 服务地域(例如:bj)", - "workflow_node.deploy.form.baiducloud_blb_region.tooltip": "这是什么?请参阅 https://cloud.baidu.com/doc/BLB/s/cjwvxnzix", "workflow_node.deploy.form.baiducloud_blb_loadbalancer_id.label": "百度智能云 BLB 负载均衡器 ID", "workflow_node.deploy.form.baiducloud_blb_loadbalancer_id.placeholder": "请输入百度智能云 BLB 负载均衡器 ID", "workflow_node.deploy.form.baiducloud_blb_loadbalancer_id.tooltip": "这是什么?请参阅 https://console.bce.baidu.com/blb/#/blb/list", @@ -403,13 +403,13 @@ "workflow_node.deploy.form.ctcccloud_cdn_domain.label": "天翼云 CDN 加速域名", "workflow_node.deploy.form.ctcccloud_cdn_domain.placeholder": "请输入天翼云 CDN 加速域名(支持泛域名)", "workflow_node.deploy.form.ctcccloud_cdn_domain.tooltip": "这是什么?请参阅 https://cdn-console.ctyun.cn", + "workflow_node.deploy.form.ctcccloud_elb_region_id.label": "天翼云 ELB 资源池 ID", + "workflow_node.deploy.form.ctcccloud_elb_region_id.placeholder": "请输入天翼云 ELB 资源池 ID", + "workflow_node.deploy.form.ctcccloud_elb_region_id.tooltip": "这是什么?请参阅 https://www.ctyun.cn/document/10026755/10196575", "workflow_node.deploy.form.ctcccloud_elb_resource_type.label": "证书部署方式", "workflow_node.deploy.form.ctcccloud_elb_resource_type.placeholder": "请选择证书部署方式", "workflow_node.deploy.form.ctcccloud_elb_resource_type.option.loadbalancer.label": "替换指定负载均衡器下的全部 HTTPS 监听器的证书", "workflow_node.deploy.form.ctcccloud_elb_resource_type.option.listener.label": "替换指定监听器的证书", - "workflow_node.deploy.form.ctcccloud_elb_region_id.label": "天翼云 ELB 资源池 ID", - "workflow_node.deploy.form.ctcccloud_elb_region_id.placeholder": "请输入天翼云 ELB 资源池 ID", - "workflow_node.deploy.form.ctcccloud_elb_region_id.tooltip": "这是什么?请参阅 https://www.ctyun.cn/document/10026755/10196575", "workflow_node.deploy.form.ctcccloud_elb_loadbalancer_id.label": "天翼云 ELB 负载均衡器 ID", "workflow_node.deploy.form.ctcccloud_elb_loadbalancer_id.placeholder": "请输入天翼云 ELB 负载均衡器 ID", "workflow_node.deploy.form.ctcccloud_elb_loadbalancer_id.tooltip": "这是什么?请参阅 https://console.ctyun.cn/network/index/#/elb/elbList", @@ -452,14 +452,14 @@ "workflow_node.deploy.form.huaweicloud_cdn_domain.label": "华为云 CDN 加速域名", "workflow_node.deploy.form.huaweicloud_cdn_domain.placeholder": "请输入华为云 CDN 加速域名", "workflow_node.deploy.form.huaweicloud_cdn_domain.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/cdn", + "workflow_node.deploy.form.huaweicloud_elb_region.label": "华为云 ELB 服务区域", + "workflow_node.deploy.form.huaweicloud_elb_region.placeholder": "请输入华为云 ELB 服务区域(例如:cn-north-1)", + "workflow_node.deploy.form.huaweicloud_elb_region.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_elb_resource_type.label": "证书部署方式", "workflow_node.deploy.form.huaweicloud_elb_resource_type.placeholder": "请选择证书部署方式", "workflow_node.deploy.form.huaweicloud_elb_resource_type.option.certificate.label": "替换指定证书", "workflow_node.deploy.form.huaweicloud_elb_resource_type.option.loadbalancer.label": "替换指定负载均衡器下的全部 HTTPS 监听器的证书", "workflow_node.deploy.form.huaweicloud_elb_resource_type.option.listener.label": "替换指定监听器的证书", - "workflow_node.deploy.form.huaweicloud_elb_region.label": "华为云 ELB 服务区域", - "workflow_node.deploy.form.huaweicloud_elb_region.placeholder": "请输入华为云 ELB 服务区域(例如:cn-north-1)", - "workflow_node.deploy.form.huaweicloud_elb_region.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_elb_certificate_id.label": "华为云 ELB 证书 ID", "workflow_node.deploy.form.huaweicloud_elb_certificate_id.placeholder": "请输入华为云 ELB 证书 ID", "workflow_node.deploy.form.huaweicloud_elb_certificate_id.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/vpc/#/elb/elbCert", @@ -469,27 +469,27 @@ "workflow_node.deploy.form.huaweicloud_elb_listener_id.label": "华为云 ELB 监听器 ID", "workflow_node.deploy.form.huaweicloud_elb_listener_id.placeholder": "请输入华为云 ELB 监听器 ID", "workflow_node.deploy.form.huaweicloud_elb_listener_id.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/vpc/#/elb/list/grid", + "workflow_node.deploy.form.huaweicloud_waf_region.label": "华为云 WAF 服务区域", + "workflow_node.deploy.form.huaweicloud_waf_region.placeholder": "请输入华为云 WAF 服务区域(例如:cn-north-1)", + "workflow_node.deploy.form.huaweicloud_waf_region.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_waf_resource_type.label": "证书部署方式", "workflow_node.deploy.form.huaweicloud_waf_resource_type.placeholder": "请选择证书部署方式", "workflow_node.deploy.form.huaweicloud_waf_resource_type.option.certificate.label": "替换指定证书", "workflow_node.deploy.form.huaweicloud_waf_resource_type.option.cloudserver.label": "替换指定云模式防护网站的证书", "workflow_node.deploy.form.huaweicloud_waf_resource_type.option.premiumhost.label": "替换指定独享模式防护网站的证书", - "workflow_node.deploy.form.huaweicloud_waf_region.label": "华为云 WAF 服务区域", - "workflow_node.deploy.form.huaweicloud_waf_region.placeholder": "请输入华为云 WAF 服务区域(例如:cn-north-1)", - "workflow_node.deploy.form.huaweicloud_waf_region.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_waf_certificate_id.label": "华为云 WAF 证书 ID", "workflow_node.deploy.form.huaweicloud_waf_certificate_id.placeholder": "请输入华为云 WAF 证书 ID", "workflow_node.deploy.form.huaweicloud_waf_certificate_id.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/console/#/waf/certificateManagement", "workflow_node.deploy.form.huaweicloud_waf_domain.label": "华为云 WAF 防护域名", "workflow_node.deploy.form.huaweicloud_waf_domain.placeholder": "请输入华为云 WAF 防护域名(支持泛域名)", "workflow_node.deploy.form.huaweicloud_waf_domain.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/console/#/waf/domain/list", + "workflow_node.deploy.form.jdcloud_alb_region_id.label": "京东云 ALB 服务地域 ID", + "workflow_node.deploy.form.jdcloud_alb_region_id.placeholder": "请输入京东云 ALB 服务地域 ID(例如:cn-north-1", + "workflow_node.deploy.form.jdcloud_alb_region_id.tooltip": "这是什么?请参阅 https://docs.jdcloud.com/cn/common-declaration/api/introduction", "workflow_node.deploy.form.jdcloud_alb_resource_type.label": "证书部署方式", "workflow_node.deploy.form.jdcloud_alb_resource_type.placeholder": "请选择证书部署方式", "workflow_node.deploy.form.jdcloud_alb_resource_type.option.loadbalancer.label": "替换指定负载均衡器下的全部 HTTPS/TLS 监听的证书", "workflow_node.deploy.form.jdcloud_alb_resource_type.option.listener.label": "替换指定负载均衡监听器的证书", - "workflow_node.deploy.form.jdcloud_alb_region_id.label": "京东云 ALB 服务地域 ID", - "workflow_node.deploy.form.jdcloud_alb_region_id.placeholder": "请输入京东云 ALB 服务地域 ID(例如:cn-north-1", - "workflow_node.deploy.form.jdcloud_alb_region_id.tooltip": "这是什么?请参阅 https://docs.jdcloud.com/cn/common-declaration/api/introduction", "workflow_node.deploy.form.jdcloud_alb_loadbalancer_id.label": "京东云 ALB 负载均衡器 ID", "workflow_node.deploy.form.jdcloud_alb_loadbalancer_id.placeholder": "请输入京东云 ALB 负载均衡器 ID", "workflow_node.deploy.form.jdcloud_alb_loadbalancer_id.tooltip": "这是什么?请参阅 https://cns-console.jdcloud.com/host/loadBalance/list", @@ -656,18 +656,24 @@ "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_rdp.label": "PowerShell - 导入并绑定到 RDP", "workflow_node.deploy.form.ssh_use_scp.label": "回退使用 SCP", "workflow_node.deploy.form.ssh_use_scp.tooltip": "如果你的远程服务器不支持 SFTP,请开启此选项回退为 SCP。", + "workflow_node.deploy.form.tencentcloud_cdn_endpoint.label": "腾讯云 CDN 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_cdn_endpoint.placeholder": "请输入腾讯云 CDN 接口端点(例如:cdn.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_cdn_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/228/30976", "workflow_node.deploy.form.tencentcloud_cdn_domain.label": "腾讯云 CDN 加速域名", "workflow_node.deploy.form.tencentcloud_cdn_domain.placeholder": "请输入腾讯云 CDN 加速域名(支持泛域名)", "workflow_node.deploy.form.tencentcloud_cdn_domain.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/cdn", + "workflow_node.deploy.form.tencentcloud_clb_endpoint.label": "腾讯云 CLB 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_clb_endpoint.placeholder": "请输入腾讯云 CLB 接口端点(例如:clb.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_clb_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/214/30669", + "workflow_node.deploy.form.tencentcloud_clb_region.label": "腾讯云 CLB 产品地域", + "workflow_node.deploy.form.tencentcloud_clb_region.placeholder": "请输入腾讯云 CLB 服务地域(例如:ap-guangzhou)", + "workflow_node.deploy.form.tencentcloud_clb_region.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/214/33415", "workflow_node.deploy.form.tencentcloud_clb_resource_type.label": "证书部署方式", "workflow_node.deploy.form.tencentcloud_clb_resource_type.placeholder": "请选择证书部署方式", "workflow_node.deploy.form.tencentcloud_clb_resource_type.option.ssl_deploy.label": "通过 SSL 服务部署到云资源实例", "workflow_node.deploy.form.tencentcloud_clb_resource_type.option.loadbalancer.label": "替换指定实例下的全部 HTTPS/TCPSSL/QUIC 监听器的证书", "workflow_node.deploy.form.tencentcloud_clb_resource_type.option.listener.label": "替换指定监听器的证书", "workflow_node.deploy.form.tencentcloud_clb_resource_type.option.ruledomain.label": "替换指定七层监听转发规则域名的证书", - "workflow_node.deploy.form.tencentcloud_clb_region.label": "腾讯云 CLB 产品地域", - "workflow_node.deploy.form.tencentcloud_clb_region.placeholder": "请输入腾讯云 CLB 服务地域(例如:ap-guangzhou)", - "workflow_node.deploy.form.tencentcloud_clb_region.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/214/33415", "workflow_node.deploy.form.tencentcloud_clb_loadbalancer_id.label": "腾讯云 CLB 实例 ID", "workflow_node.deploy.form.tencentcloud_clb_loadbalancer_id.placeholder": "请输入腾讯云 CLB 实例 ID", "workflow_node.deploy.form.tencentcloud_clb_loadbalancer_id.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/clb", @@ -689,18 +695,30 @@ "workflow_node.deploy.form.tencentcloud_cos_domain.label": "腾讯云 COS 自定义域名", "workflow_node.deploy.form.tencentcloud_cos_domain.placeholder": "请输入腾讯云 COS 自定义域名", "workflow_node.deploy.form.tencentcloud_cos_domain.tooltip": "这是什么?请参阅 see https://console.cloud.tencent.com/cos", + "workflow_node.deploy.form.tencentcloud_css_endpoint.label": "腾讯云云直播接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_css_endpoint.placeholder": "请输入腾讯云云直播接口端点(例如:live.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_css_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/267/20458", "workflow_node.deploy.form.tencentcloud_css_domain.label": "腾讯云云直播播放域名", "workflow_node.deploy.form.tencentcloud_css_domain.placeholder": "请输入腾讯云云直播播放域名", "workflow_node.deploy.form.tencentcloud_css_domain.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/live", + "workflow_node.deploy.form.tencentcloud_ecdn_endpoint.label": "腾讯云 ECDN 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_ecdn_endpoint.placeholder": "请输入腾讯云 ECDN 接口端点(例如:cdn.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_ecdn_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/214/30669", "workflow_node.deploy.form.tencentcloud_ecdn_domain.label": "腾讯云 ECDN 加速域名", "workflow_node.deploy.form.tencentcloud_ecdn_domain.placeholder": "请输入腾讯云 ECDN 加速域名(支持泛域名)", "workflow_node.deploy.form.tencentcloud_ecdn_domain.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/cdn", + "workflow_node.deploy.form.tencentcloud_eo_endpoint.label": "腾讯云 EdgeOne 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_eo_endpoint.placeholder": "请输入腾讯云 EdgeOne 接口端点(例如:teo.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_eo_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/1552/80723", "workflow_node.deploy.form.tencentcloud_eo_zone_id.label": "腾讯云 EdgeOne 站点 ID", "workflow_node.deploy.form.tencentcloud_eo_zone_id.placeholder": "请输入腾讯云 EdgeOne 站点 ID", "workflow_node.deploy.form.tencentcloud_eo_zone_id.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/edgeone", "workflow_node.deploy.form.tencentcloud_eo_domain.label": "腾讯云 EdgeOne 加速域名", "workflow_node.deploy.form.tencentcloud_eo_domain.placeholder": "请输入腾讯云 EdgeOne 加速域名(支持泛域名)", "workflow_node.deploy.form.tencentcloud_eo_domain.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/edgeone", + "workflow_node.deploy.form.tencentcloud_gaap_endpoint.label": "腾讯云 GAAP 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_gaap_endpoint.placeholder": "请输入腾讯云 GAAP 接口端点(例如:gaap.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_gaap_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/608/36934", "workflow_node.deploy.form.tencentcloud_gaap_resource_type.label": "证书部署方式", "workflow_node.deploy.form.tencentcloud_gaap_resource_type.placeholder": "请选择证书部署方式", "workflow_node.deploy.form.tencentcloud_gaap_resource_type.option.listener.label": "替换指定监听器的证书", @@ -710,13 +728,22 @@ "workflow_node.deploy.form.tencentcloud_gaap_listener_id.label": "腾讯云 GAAP 监听器 ID", "workflow_node.deploy.form.tencentcloud_gaap_listener_id.placeholder": "请输入腾讯云 GAAP 监听器 ID", "workflow_node.deploy.form.tencentcloud_gaap_listener_id.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/gaap", + "workflow_node.deploy.form.tencentcloud_scf_endpoint.label": "腾讯云 SCF 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_scf_endpoint.placeholder": "请输入腾讯云 SCF 接口端点(例如:scf.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_scf_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/583/17237", "workflow_node.deploy.form.tencentcloud_scf_region.label": "腾讯云 SCF 产品地域", "workflow_node.deploy.form.tencentcloud_scf_region.placeholder": "输入腾讯云 SCF 产品地域(例如:ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_scf_region.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/583/17299", "workflow_node.deploy.form.tencentcloud_scf_domain.label": "腾讯云 SCF 自定义域名", "workflow_node.deploy.form.tencentcloud_scf_domain.placeholder": "输入腾讯云 SCF 自定义域名", "workflow_node.deploy.form.tencentcloud_scf_domain.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/scf", + "workflow_node.deploy.form.tencentcloud_ssl_endpoint.label": "腾讯云 SSL 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_ssl_endpoint.placeholder": "请输入腾讯云 SSL 接口端点(例如:ssl.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_ssl_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/41659", "workflow_node.deploy.form.tencentcloud_ssl_deploy.guide": "小贴士:由于腾讯云证书部署任务是异步的,此节点若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往腾讯云控制台查询。", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_endpoint.label": "腾讯云 SSL 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_endpoint.placeholder": "请输入腾讯云 SSL 接口端点(例如:ssl.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/41659", "workflow_node.deploy.form.tencentcloud_ssl_deploy_region.label": "腾讯云云产品地域", "workflow_node.deploy.form.tencentcloud_ssl_deploy_region.placeholder": "请输入腾讯云云产品地域(例如:ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_ssl_deploy_region.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/41659", @@ -729,12 +756,18 @@ "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/91667

注意与各产品本身的实例 ID 区分。", "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.title": "修改腾讯云云产品资源 ID", "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.placeholder": "请输入腾讯云云产品资源 ID", + "workflow_node.deploy.form.tencentcloud_vod_endpoint.label": "腾讯云云点播接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_vod_endpoint.placeholder": "请输入腾讯云云点播接口端点(例如:vod.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_vod_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/266/31755", "workflow_node.deploy.form.tencentcloud_vod_sub_app_id.label": "腾讯云云点播应用 ID", "workflow_node.deploy.form.tencentcloud_vod_sub_app_id.placeholder": "请输入腾讯云云点播应用 ID", "workflow_node.deploy.form.tencentcloud_vod_sub_app_id.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/vod", "workflow_node.deploy.form.tencentcloud_vod_domain.label": "腾讯云云点播加速域名", "workflow_node.deploy.form.tencentcloud_vod_domain.placeholder": "请输入腾讯云云点播加速域名", "workflow_node.deploy.form.tencentcloud_vod_domain.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/vod", + "workflow_node.deploy.form.tencentcloud_waf_endpoint.label": "腾讯云 WAF 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_waf_endpoint.placeholder": "请输入腾讯云 WAF 接口端点(例如:waf.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_waf_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/627/53611", "workflow_node.deploy.form.tencentcloud_waf_region.label": "腾讯云 WAF 产品地域", "workflow_node.deploy.form.tencentcloud_waf_region.placeholder": "请输入腾讯云 WAF 产品地域(例如:ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_waf_region.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/627/47525", From 2829ac89ca78d50c5d0549fee3eb12b817234359 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Mon, 23 Jun 2025 12:11:20 +0800 Subject: [PATCH 03/16] refactor: clean code --- .../providers/aliyun-alb/aliyun_alb.go | 33 ++++-------- .../providers/aliyun-apigw/aliyun_apigw.go | 51 ++++++++++--------- .../aliyun-cas-deploy/aliyun_cas_deploy.go | 29 +++-------- .../providers/aliyun-clb/aliyun_clb.go | 22 ++++---- .../providers/aliyun-ddos/aliyun_ddos.go | 43 +++++++--------- .../providers/aliyun-esa/aliyun_esa.go | 43 +++++++--------- .../providers/aliyun-fc/aliyun_fc.go | 14 +++-- .../providers/aliyun-ga/aliyun_ga.go | 17 +++---- .../providers/aliyun-nlb/aliyun_nlb.go | 42 +++++++-------- .../providers/aliyun-vod/aliyun_vod.go | 10 +++- .../providers/aliyun-waf/aliyun_waf.go | 42 +++++++-------- .../providers/baishan-cdn/baishan_cdn.go | 2 +- .../providers/ucloud-ucdn/ucloud_ucdn.go | 2 +- 13 files changed, 154 insertions(+), 196 deletions(-) diff --git a/pkg/core/ssl-deployer/providers/aliyun-alb/aliyun_alb.go b/pkg/core/ssl-deployer/providers/aliyun-alb/aliyun_alb.go index ac7bc70e..391f4b55 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-alb/aliyun_alb.go +++ b/pkg/core/ssl-deployer/providers/aliyun-alb/aliyun_alb.go @@ -17,6 +17,7 @@ import ( "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/aliyun-cas" + "github.com/certimate-go/certimate/pkg/utils/ifelse" ) type SSLDeployerProviderConfig struct { @@ -65,7 +66,15 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, fmt.Errorf("could not create sdk client: %w", err) } - sslmgr, err := createSSLManager(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region) + sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ + AccessKeyId: config.AccessKeyId, + AccessKeySecret: config.AccessKeySecret, + ResourceGroupId: config.ResourceGroupId, + Region: ifelse. + If[string](config.Region == "" || strings.HasPrefix(config.Region, "cn-")). + Then("cn-hangzhou"). + Else("ap-southeast-1"), + }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) } @@ -463,25 +472,3 @@ func createSDKClients(accessKeyId, accessKeySecret, region string) (*wSDKClients CAS: casClient, }, nil } - -func createSSLManager(accessKeyId, accessKeySecret, resourceGroupId, region string) (core.SSLManager, error) { - casRegion := region - if casRegion != "" { - // 阿里云 CAS 服务接入点是独立于 ALB 服务的 - // 国内版固定接入点:华东一杭州 - // 国际版固定接入点:亚太东南一新加坡 - if !strings.HasPrefix(casRegion, "cn-") { - casRegion = "ap-southeast-1" - } else { - casRegion = "cn-hangzhou" - } - } - - sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ - AccessKeyId: accessKeyId, - AccessKeySecret: accessKeySecret, - ResourceGroupId: resourceGroupId, - Region: casRegion, - }) - return sslmgr, err -} diff --git a/pkg/core/ssl-deployer/providers/aliyun-apigw/aliyun_apigw.go b/pkg/core/ssl-deployer/providers/aliyun-apigw/aliyun_apigw.go index c9a2b61f..41116146 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-apigw/aliyun_apigw.go +++ b/pkg/core/ssl-deployer/providers/aliyun-apigw/aliyun_apigw.go @@ -15,6 +15,7 @@ import ( "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/aliyun-cas" + "github.com/certimate-go/certimate/pkg/utils/ifelse" xtypes "github.com/certimate-go/certimate/pkg/utils/types" ) @@ -63,7 +64,15 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, fmt.Errorf("could not create sdk client: %w", err) } - sslmgr, err := createSSLManager(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region) + sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ + AccessKeyId: config.AccessKeyId, + AccessKeySecret: config.AccessKeySecret, + ResourceGroupId: config.ResourceGroupId, + Region: ifelse. + If[string](config.Region == "" || strings.HasPrefix(config.Region, "cn-")). + Then("cn-hangzhou"). + Else("ap-southeast-1"), + }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) } @@ -225,7 +234,14 @@ func (d *SSLDeployerProvider) deployToCloudNative(ctx context.Context, certPEM s func createSDKClients(accessKeyId, accessKeySecret, region string) (*wSDKClients, error) { // 接入点一览 https://api.aliyun.com/product/APIG - cloudNativeAPIGEndpoint := strings.ReplaceAll(fmt.Sprintf("apig.%s.aliyuncs.com", region), "..", ".") + var cloudNativeAPIGEndpoint string + switch region { + case "": + cloudNativeAPIGEndpoint = "apig.cn-hangzhou.aliyuncs.com" + default: + cloudNativeAPIGEndpoint = fmt.Sprintf("apig.%s.aliyuncs.com", region) + } + cloudNativeAPIGConfig := &aliopen.Config{ AccessKeyId: tea.String(accessKeyId), AccessKeySecret: tea.String(accessKeySecret), @@ -237,7 +253,14 @@ func createSDKClients(accessKeyId, accessKeySecret, region string) (*wSDKClients } // 接入点一览 https://api.aliyun.com/product/CloudAPI - traditionalAPIGEndpoint := strings.ReplaceAll(fmt.Sprintf("apigateway.%s.aliyuncs.com", region), "..", ".") + var traditionalAPIGEndpoint string + switch region { + case "": + traditionalAPIGEndpoint = "apigateway.cn-hangzhou.aliyuncs.com" + default: + traditionalAPIGEndpoint = fmt.Sprintf("apigateway.%s.aliyuncs.com", region) + } + traditionalAPIGConfig := &aliopen.Config{ AccessKeyId: tea.String(accessKeyId), AccessKeySecret: tea.String(accessKeySecret), @@ -253,25 +276,3 @@ func createSDKClients(accessKeyId, accessKeySecret, region string) (*wSDKClients TraditionalAPIGateway: traditionalAPIGClient, }, nil } - -func createSSLManager(accessKeyId, accessKeySecret, resourceGroupId, region string) (core.SSLManager, error) { - casRegion := region - if casRegion != "" { - // 阿里云 CAS 服务接入点是独立于 APIGateway 服务的 - // 国内版固定接入点:华东一杭州 - // 国际版固定接入点:亚太东南一新加坡 - if !strings.HasPrefix(casRegion, "cn-") { - casRegion = "ap-southeast-1" - } else { - casRegion = "cn-hangzhou" - } - } - - sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ - AccessKeyId: accessKeyId, - AccessKeySecret: accessKeySecret, - ResourceGroupId: resourceGroupId, - Region: casRegion, - }) - return sslmgr, err -} diff --git a/pkg/core/ssl-deployer/providers/aliyun-cas-deploy/aliyun_cas_deploy.go b/pkg/core/ssl-deployer/providers/aliyun-cas-deploy/aliyun_cas_deploy.go index 6fa587bc..0d410d28 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-cas-deploy/aliyun_cas_deploy.go +++ b/pkg/core/ssl-deployer/providers/aliyun-cas-deploy/aliyun_cas_deploy.go @@ -51,7 +51,12 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, fmt.Errorf("could not create sdk client: %w", err) } - sslmgr, err := createSSLManager(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region) + sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ + AccessKeyId: config.AccessKeyId, + AccessKeySecret: config.AccessKeySecret, + ResourceGroupId: config.ResourceGroupId, + Region: config.Region, + }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) } @@ -177,25 +182,3 @@ func createSDKClient(accessKeyId, accessKeySecret, region string) (*alicas.Clien return client, nil } - -func createSSLManager(accessKeyId, accessKeySecret, resourceGroupId, region string) (core.SSLManager, error) { - casRegion := region - if casRegion != "" { - // 阿里云 CAS 服务接入点是独立于其他服务的 - // 国内版固定接入点:华东一杭州 - // 国际版固定接入点:亚太东南一新加坡 - if !strings.HasPrefix(casRegion, "cn-") { - casRegion = "ap-southeast-1" - } else { - casRegion = "cn-hangzhou" - } - } - - sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ - AccessKeyId: accessKeyId, - AccessKeySecret: accessKeySecret, - ResourceGroupId: resourceGroupId, - Region: casRegion, - }) - return sslmgr, err -} diff --git a/pkg/core/ssl-deployer/providers/aliyun-clb/aliyun_clb.go b/pkg/core/ssl-deployer/providers/aliyun-clb/aliyun_clb.go index b0abdcaf..dd6f4664 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-clb/aliyun_clb.go +++ b/pkg/core/ssl-deployer/providers/aliyun-clb/aliyun_clb.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "log/slog" + "strings" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client" alislb "github.com/alibabacloud-go/slb-20140515/v4/client" @@ -12,6 +13,7 @@ import ( "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/aliyun-slb" + "github.com/certimate-go/certimate/pkg/utils/ifelse" ) type SSLDeployerProviderConfig struct { @@ -55,7 +57,15 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, fmt.Errorf("could not create sdk client: %w", err) } - sslmgr, err := createSSLManager(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region) + sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ + AccessKeyId: config.AccessKeyId, + AccessKeySecret: config.AccessKeySecret, + ResourceGroupId: config.ResourceGroupId, + Region: ifelse. + If[string](config.Region == "" || strings.HasPrefix(config.Region, "cn-")). + Then("cn-hangzhou"). + Else("ap-southeast-1"), + }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) } @@ -307,13 +317,3 @@ func createSDKClient(accessKeyId, accessKeySecret, region string) (*alislb.Clien return client, nil } - -func createSSLManager(accessKeyId, accessKeySecret, resourceGroupId, region string) (core.SSLManager, error) { - sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ - AccessKeyId: accessKeyId, - AccessKeySecret: accessKeySecret, - ResourceGroupId: resourceGroupId, - Region: region, - }) - return sslmgr, err -} diff --git a/pkg/core/ssl-deployer/providers/aliyun-ddos/aliyun_ddos.go b/pkg/core/ssl-deployer/providers/aliyun-ddos/aliyun_ddos.go index 1e5ed9ab..184d978c 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-ddos/aliyun_ddos.go +++ b/pkg/core/ssl-deployer/providers/aliyun-ddos/aliyun_ddos.go @@ -14,6 +14,7 @@ import ( "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/aliyun-slb" + "github.com/certimate-go/certimate/pkg/utils/ifelse" ) type SSLDeployerProviderConfig struct { @@ -48,7 +49,15 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, fmt.Errorf("could not create sdk client: %w", err) } - sslmgr, err := createSSLManager(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region) + sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ + AccessKeyId: config.AccessKeyId, + AccessKeySecret: config.AccessKeySecret, + ResourceGroupId: config.ResourceGroupId, + Region: ifelse. + If[string](config.Region == "" || strings.HasPrefix(config.Region, "cn-")). + Then("cn-hangzhou"). + Else("ap-southeast-1"), + }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) } @@ -102,10 +111,18 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func createSDKClient(accessKeyId, accessKeySecret, region string) (*aliddos.Client, error) { // 接入点一览 https://api.aliyun.com/product/ddoscoo + var endpoint string + switch region { + case "": + endpoint = "ddoscoo.cn-hangzhou.aliyuncs.com" + default: + endpoint = fmt.Sprintf("ddoscoo.%s.aliyuncs.com", region) + } + config := &aliopen.Config{ AccessKeyId: tea.String(accessKeyId), AccessKeySecret: tea.String(accessKeySecret), - Endpoint: tea.String(strings.ReplaceAll(fmt.Sprintf("ddoscoo.%s.aliyuncs.com", region), "..", ".")), + Endpoint: tea.String(endpoint), } client, err := aliddos.NewClient(config) @@ -115,25 +132,3 @@ func createSDKClient(accessKeyId, accessKeySecret, region string) (*aliddos.Clie return client, nil } - -func createSSLManager(accessKeyId, accessKeySecret, resourceGroupId, region string) (core.SSLManager, error) { - casRegion := region - if casRegion != "" { - // 阿里云 CAS 服务接入点是独立于 Anti-DDoS 服务的 - // 国内版固定接入点:华东一杭州 - // 国际版固定接入点:亚太东南一新加坡 - if !strings.HasPrefix(casRegion, "cn-") { - casRegion = "ap-southeast-1" - } else { - casRegion = "cn-hangzhou" - } - } - - sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ - AccessKeyId: accessKeyId, - AccessKeySecret: accessKeySecret, - ResourceGroupId: resourceGroupId, - Region: casRegion, - }) - return sslmgr, err -} diff --git a/pkg/core/ssl-deployer/providers/aliyun-esa/aliyun_esa.go b/pkg/core/ssl-deployer/providers/aliyun-esa/aliyun_esa.go index e3bb0374..bcaae6ca 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-esa/aliyun_esa.go +++ b/pkg/core/ssl-deployer/providers/aliyun-esa/aliyun_esa.go @@ -14,6 +14,7 @@ import ( "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/aliyun-cas" + "github.com/certimate-go/certimate/pkg/utils/ifelse" ) type SSLDeployerProviderConfig struct { @@ -48,7 +49,15 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, fmt.Errorf("could not create sdk client: %w", err) } - sslmgr, err := createSSLManager(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region) + sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ + AccessKeyId: config.AccessKeyId, + AccessKeySecret: config.AccessKeySecret, + ResourceGroupId: config.ResourceGroupId, + Region: ifelse. + If[string](config.Region == "" || strings.HasPrefix(config.Region, "cn-")). + Then("cn-hangzhou"). + Else("ap-southeast-1"), + }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) } @@ -103,10 +112,18 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func createSDKClient(accessKeyId, accessKeySecret, region string) (*aliesa.Client, error) { // 接入点一览 https://api.aliyun.com/product/ESA + var endpoint string + switch region { + case "": + endpoint = "esa.cn-hangzhou.aliyuncs.com" + default: + endpoint = fmt.Sprintf("esa.%s.aliyuncs.com", region) + } + config := &aliopen.Config{ AccessKeyId: tea.String(accessKeyId), AccessKeySecret: tea.String(accessKeySecret), - Endpoint: tea.String(strings.ReplaceAll(fmt.Sprintf("esa.%s.aliyuncs.com", region), "..", ".")), + Endpoint: tea.String(endpoint), } client, err := aliesa.NewClient(config) @@ -116,25 +133,3 @@ func createSDKClient(accessKeyId, accessKeySecret, region string) (*aliesa.Clien return client, nil } - -func createSSLManager(accessKeyId, accessKeySecret, resourceGroupId, region string) (core.SSLManager, error) { - casRegion := region - if casRegion != "" { - // 阿里云 CAS 服务接入点是独立于 ESA 服务的 - // 国内版固定接入点:华东一杭州 - // 国际版固定接入点:亚太东南一新加坡 - if !strings.HasPrefix(casRegion, "cn-") { - casRegion = "ap-southeast-1" - } else { - casRegion = "cn-hangzhou" - } - } - - sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ - AccessKeyId: accessKeyId, - AccessKeySecret: accessKeySecret, - ResourceGroupId: resourceGroupId, - Region: casRegion, - }) - return sslmgr, err -} diff --git a/pkg/core/ssl-deployer/providers/aliyun-fc/aliyun_fc.go b/pkg/core/ssl-deployer/providers/aliyun-fc/aliyun_fc.go index 4a5d2a16..f21be235 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-fc/aliyun_fc.go +++ b/pkg/core/ssl-deployer/providers/aliyun-fc/aliyun_fc.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "log/slog" - "strings" "time" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client" @@ -184,8 +183,17 @@ func createSDKClients(accessKeyId, accessKeySecret, region string) (*wSDKClients return nil, err } - // 接入点一览 https://api.aliyun.com/product/FC-Open - fc3Endpoint := strings.ReplaceAll(fmt.Sprintf("fcv3.%s.aliyuncs.com", region), "..", ".") + // 接入点一览 https://api.aliyun.com/product/FC + var fc3Endpoint string + switch region { + case "": + fc3Endpoint = "fcv3.cn-hangzhou.aliyuncs.com" + case "me-central-1", "cn-hangzhou-finance", "cn-shanghai-finance-1", "cn-heyuan-acdr-1": + fc3Endpoint = fmt.Sprintf("%s.fc.aliyuncs.com", region) + default: + fc3Endpoint = fmt.Sprintf("fcv3.%s.aliyuncs.com", region) + } + fc3Config := &aliopen.Config{ AccessKeyId: tea.String(accessKeyId), AccessKeySecret: tea.String(accessKeySecret), diff --git a/pkg/core/ssl-deployer/providers/aliyun-ga/aliyun_ga.go b/pkg/core/ssl-deployer/providers/aliyun-ga/aliyun_ga.go index 6307486c..2d1db29f 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-ga/aliyun_ga.go +++ b/pkg/core/ssl-deployer/providers/aliyun-ga/aliyun_ga.go @@ -54,7 +54,12 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, fmt.Errorf("could not create sdk client: %w", err) } - sslmgr, err := createSSLManager(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId) + sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ + AccessKeyId: config.AccessKeyId, + AccessKeySecret: config.AccessKeySecret, + ResourceGroupId: config.ResourceGroupId, + Region: "cn-hangzhou", + }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) } @@ -313,13 +318,3 @@ func createSDKClient(accessKeyId, accessKeySecret string) (*aliga.Client, error) return client, nil } - -func createSSLManager(accessKeyId, accessKeySecret, resourceGroupId string) (core.SSLManager, error) { - sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ - AccessKeyId: accessKeyId, - AccessKeySecret: accessKeySecret, - ResourceGroupId: resourceGroupId, - Region: "cn-hangzhou", - }) - return sslmgr, err -} diff --git a/pkg/core/ssl-deployer/providers/aliyun-nlb/aliyun_nlb.go b/pkg/core/ssl-deployer/providers/aliyun-nlb/aliyun_nlb.go index 6cbe6298..6a6a0411 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-nlb/aliyun_nlb.go +++ b/pkg/core/ssl-deployer/providers/aliyun-nlb/aliyun_nlb.go @@ -13,6 +13,7 @@ import ( "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/aliyun-cas" + "github.com/certimate-go/certimate/pkg/utils/ifelse" ) type SSLDeployerProviderConfig struct { @@ -53,7 +54,15 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, fmt.Errorf("could not create sdk client: %w", err) } - sslmgr, err := createSSLManager(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region) + sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ + AccessKeyId: config.AccessKeyId, + AccessKeySecret: config.AccessKeySecret, + ResourceGroupId: config.ResourceGroupId, + Region: ifelse. + If[string](config.Region == "" || strings.HasPrefix(config.Region, "cn-")). + Then("cn-hangzhou"). + Else("ap-southeast-1"), + }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) } @@ -225,7 +234,14 @@ func (d *SSLDeployerProvider) updateListenerCertificate(ctx context.Context, clo func createSDKClient(accessKeyId, accessKeySecret, region string) (*alinlb.Client, error) { // 接入点一览 https://api.aliyun.com/product/Nlb - endpoint := strings.ReplaceAll(fmt.Sprintf("nlb.%s.aliyuncs.com", region), "..", ".") + var endpoint string + switch region { + case "": + endpoint = "nlb.cn-hangzhou.aliyuncs.com" + default: + endpoint = fmt.Sprintf("nlb.%s.aliyuncs.com", region) + } + config := &aliopen.Config{ AccessKeyId: tea.String(accessKeyId), AccessKeySecret: tea.String(accessKeySecret), @@ -239,25 +255,3 @@ func createSDKClient(accessKeyId, accessKeySecret, region string) (*alinlb.Clien return client, nil } - -func createSSLManager(accessKeyId, accessKeySecret, resourceGroupId, region string) (core.SSLManager, error) { - casRegion := region - if casRegion != "" { - // 阿里云 CAS 服务接入点是独立于 NLB 服务的 - // 国内版固定接入点:华东一杭州 - // 国际版固定接入点:亚太东南一新加坡 - if !strings.HasPrefix(casRegion, "cn-") { - casRegion = "ap-southeast-1" - } else { - casRegion = "cn-hangzhou" - } - } - - sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ - AccessKeyId: accessKeyId, - AccessKeySecret: accessKeySecret, - ResourceGroupId: resourceGroupId, - Region: casRegion, - }) - return sslmgr, err -} diff --git a/pkg/core/ssl-deployer/providers/aliyun-vod/aliyun_vod.go b/pkg/core/ssl-deployer/providers/aliyun-vod/aliyun_vod.go index bf8a5812..08173368 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-vod/aliyun_vod.go +++ b/pkg/core/ssl-deployer/providers/aliyun-vod/aliyun_vod.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "log/slog" - "strings" "time" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client" @@ -86,7 +85,14 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func createSDKClient(accessKeyId, accessKeySecret, region string) (*alivod.Client, error) { // 接入点一览 https://api.aliyun.com/product/vod - endpoint := strings.ReplaceAll(fmt.Sprintf("vod.%s.aliyuncs.com", region), "..", ".") + var endpoint string + switch region { + case "": + endpoint = "vod.cn-hangzhou.aliyuncs.com" + default: + endpoint = fmt.Sprintf("vod.%s.aliyuncs.com", region) + } + config := &aliopen.Config{ AccessKeyId: tea.String(accessKeyId), AccessKeySecret: tea.String(accessKeySecret), diff --git a/pkg/core/ssl-deployer/providers/aliyun-waf/aliyun_waf.go b/pkg/core/ssl-deployer/providers/aliyun-waf/aliyun_waf.go index c215125a..a36b70a6 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-waf/aliyun_waf.go +++ b/pkg/core/ssl-deployer/providers/aliyun-waf/aliyun_waf.go @@ -13,6 +13,7 @@ import ( "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/aliyun-cas" + "github.com/certimate-go/certimate/pkg/utils/ifelse" xslices "github.com/certimate-go/certimate/pkg/utils/slices" xtypes "github.com/certimate-go/certimate/pkg/utils/types" ) @@ -53,7 +54,15 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, fmt.Errorf("could not create sdk client: %w", err) } - sslmgr, err := createSSLManager(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region) + sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ + AccessKeyId: config.AccessKeyId, + AccessKeySecret: config.AccessKeySecret, + ResourceGroupId: config.ResourceGroupId, + Region: ifelse. + If[string](config.Region == "" || strings.HasPrefix(config.Region, "cn-")). + Then("cn-hangzhou"). + Else("ap-southeast-1"), + }) if err != nil { return nil, fmt.Errorf("could not create ssl manager: %w", err) } @@ -176,7 +185,14 @@ func (d *SSLDeployerProvider) deployToWAF3(ctx context.Context, certPEM string, func createSDKClient(accessKeyId, accessKeySecret, region string) (*aliwaf.Client, error) { // 接入点一览:https://api.aliyun.com/product/waf-openapi - endpoint := strings.ReplaceAll(fmt.Sprintf("wafopenapi.%s.aliyuncs.com", region), "..", ".") + var endpoint string + switch region { + case "": + endpoint = "wafopenapi.cn-hangzhou.aliyuncs.com" + default: + endpoint = fmt.Sprintf("wafopenapi.%s.aliyuncs.com", region) + } + config := &aliopen.Config{ AccessKeyId: tea.String(accessKeyId), AccessKeySecret: tea.String(accessKeySecret), @@ -191,28 +207,6 @@ func createSDKClient(accessKeyId, accessKeySecret, region string) (*aliwaf.Clien return client, nil } -func createSSLManager(accessKeyId, accessKeySecret, resourceGroupId, region string) (core.SSLManager, error) { - casRegion := region - if casRegion != "" { - // 阿里云 CAS 服务接入点是独立于 WAF 服务的 - // 国内版固定接入点:华东一杭州 - // 国际版固定接入点:亚太东南一新加坡 - if !strings.HasPrefix(casRegion, "cn-") { - casRegion = "ap-southeast-1" - } else { - casRegion = "cn-hangzhou" - } - } - - sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ - AccessKeyId: accessKeyId, - AccessKeySecret: accessKeySecret, - ResourceGroupId: resourceGroupId, - Region: casRegion, - }) - return sslmgr, err -} - func assign(source *aliwaf.ModifyDomainRequest, target *aliwaf.DescribeDomainDetailResponseBody) *aliwaf.ModifyDomainRequest { // `ModifyDomain` 中不传的字段表示使用默认值、而非保留原值, // 因此这里需要把原配置中的参数重新赋值回去。 diff --git a/pkg/core/ssl-deployer/providers/baishan-cdn/baishan_cdn.go b/pkg/core/ssl-deployer/providers/baishan-cdn/baishan_cdn.go index 18e4f785..a5a5f1c3 100644 --- a/pkg/core/ssl-deployer/providers/baishan-cdn/baishan_cdn.go +++ b/pkg/core/ssl-deployer/providers/baishan-cdn/baishan_cdn.go @@ -102,7 +102,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke if err != nil { return nil, fmt.Errorf("failed to execute sdk request 'baishan.GetDomainConfig': %w", err) } else if len(getDomainConfigResp.Data) == 0 { - return nil, errors.New("domain config not found") + return nil, fmt.Errorf("domain %s not found", d.config.Domain) } // 设置域名配置 diff --git a/pkg/core/ssl-deployer/providers/ucloud-ucdn/ucloud_ucdn.go b/pkg/core/ssl-deployer/providers/ucloud-ucdn/ucloud_ucdn.go index 8b74b47d..eed705d4 100644 --- a/pkg/core/ssl-deployer/providers/ucloud-ucdn/ucloud_ucdn.go +++ b/pkg/core/ssl-deployer/providers/ucloud-ucdn/ucloud_ucdn.go @@ -97,7 +97,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke if err != nil { return nil, fmt.Errorf("failed to execute sdk request 'ucdn.GetUcdnDomainConfig': %w", err) } else if len(getUcdnDomainConfigResp.DomainList) == 0 { - return nil, errors.New("no domain found") + return nil, fmt.Errorf("domain %s not found", d.config.DomainId) } // 更新 HTTPS 加速配置 From 86bf8cd3d01197ffb7d988e2b1ff74467c508a33 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Mon, 23 Jun 2025 13:56:10 +0800 Subject: [PATCH 04/16] refactor: clean code --- .../providers/tencentcloud-cdn/tencentcloud_cdn.go | 6 +++--- .../providers/tencentcloud-clb/tencentcloud_clb.go | 8 ++++---- .../providers/tencentcloud-cos/tencentcloud_cos.go | 2 +- .../providers/tencentcloud-css/tencentcloud_css.go | 2 +- .../providers/tencentcloud-ecdn/tencentcloud_ecdn.go | 6 +++--- .../providers/tencentcloud-eo/tencentcloud_eo.go | 2 +- .../providers/tencentcloud-gaap/tencentcloud_gaap.go | 4 ++-- .../providers/tencentcloud-scf/tencentcloud_scf.go | 4 ++-- .../tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go | 8 ++++---- .../providers/tencentcloud-ssl/tencentcloud_ssl.go | 2 +- 10 files changed, 22 insertions(+), 22 deletions(-) diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go b/pkg/core/ssl-deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go index 73235e07..a605acd2 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go @@ -137,7 +137,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func (d *SSLDeployerProvider) getDomainsByCertId(ctx context.Context, cloudCertId string) ([]string, error) { // 获取证书中的可用域名 - // REF: https://cloud.tencent.com/document/product/228/42491 + // REF: https://cloud.tencent.com/document/api/228/42491 describeCertDomainsReq := tccdn.NewDescribeCertDomainsRequest() describeCertDomainsReq.CertId = common.StringPtr(cloudCertId) describeCertDomainsReq.Product = common.StringPtr("cdn") @@ -159,7 +159,7 @@ func (d *SSLDeployerProvider) getDomainsByCertId(ctx context.Context, cloudCertI func (d *SSLDeployerProvider) updateDomainHttpsServerCert(ctx context.Context, domain string, cloudCertId string) error { // 查询域名详细配置 - // REF: https://cloud.tencent.com/document/product/228/41117 + // REF: https://cloud.tencent.com/document/api/228/41117 describeDomainsConfigReq := tccdn.NewDescribeDomainsConfigRequest() describeDomainsConfigReq.Filters = []*tccdn.DomainFilter{ { @@ -184,7 +184,7 @@ func (d *SSLDeployerProvider) updateDomainHttpsServerCert(ctx context.Context, d } // 更新加速域名配置 - // REF: https://cloud.tencent.com/document/product/228/41116 + // REF: https://cloud.tencent.com/document/api/228/41116 updateDomainConfigReq := tccdn.NewUpdateDomainConfigRequest() updateDomainConfigReq.Domain = common.StringPtr(domain) updateDomainConfigReq.Https = domainConfig.Https diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-clb/tencentcloud_clb.go b/pkg/core/ssl-deployer/providers/tencentcloud-clb/tencentcloud_clb.go index c8f07d2d..dbde4715 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-clb/tencentcloud_clb.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-clb/tencentcloud_clb.go @@ -23,10 +23,10 @@ type SSLDeployerProviderConfig struct { SecretId string `json:"secretId"` // 腾讯云 SecretKey。 SecretKey string `json:"secretKey"` - // 腾讯云地域。 - Region string `json:"region"` // 腾讯云接口端点。 Endpoint string `json:"endpoint,omitempty"` + // 腾讯云地域。 + Region string `json:"region"` // 部署资源类型。 ResourceType ResourceType `json:"resourceType"` // 负载均衡器 ID。 @@ -141,7 +141,7 @@ func (d *SSLDeployerProvider) deployViaSslService(ctx context.Context, cloudCert } // 证书部署到 CLB 实例 - // REF: https://cloud.tencent.com/document/product/400/91667 + // REF: https://cloud.tencent.com/document/api/400/91667 deployCertificateInstanceReq := tcssl.NewDeployCertificateInstanceRequest() deployCertificateInstanceReq.CertificateId = common.StringPtr(cloudCertId) deployCertificateInstanceReq.ResourceType = common.StringPtr("clb") @@ -318,7 +318,7 @@ func (d *SSLDeployerProvider) modifyListenerCertificate(ctx context.Context, clo } // 修改监听器属性 - // REF: https://cloud.tencent.com/document/product/214/30681 + // REF: https://cloud.tencent.com/document/api/214/30681 modifyListenerReq := tcclb.NewModifyListenerRequest() modifyListenerReq.LoadBalancerId = common.StringPtr(cloudLoadbalancerId) modifyListenerReq.ListenerId = common.StringPtr(cloudListenerId) diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-cos/tencentcloud_cos.go b/pkg/core/ssl-deployer/providers/tencentcloud-cos/tencentcloud_cos.go index 6bca08a0..0e5e5f66 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-cos/tencentcloud_cos.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-cos/tencentcloud_cos.go @@ -94,7 +94,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke } // 证书部署到 COS 实例 - // REF: https://cloud.tencent.com/document/product/400/91667 + // REF: https://cloud.tencent.com/document/api/400/91667 deployCertificateInstanceReq := tcssl.NewDeployCertificateInstanceRequest() deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId) deployCertificateInstanceReq.ResourceType = common.StringPtr("cos") diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-css/tencentcloud_css.go b/pkg/core/ssl-deployer/providers/tencentcloud-css/tencentcloud_css.go index f83e602c..cdfbc3d8 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-css/tencentcloud_css.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-css/tencentcloud_css.go @@ -90,7 +90,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke } // 绑定证书对应的播放域名 - // REF: https://cloud.tencent.com/document/product/267/78655 + // REF: https://cloud.tencent.com/document/api/267/78655 modifyLiveDomainCertBindingsReq := tclive.NewModifyLiveDomainCertBindingsRequest() modifyLiveDomainCertBindingsReq.DomainInfos = []*tclive.LiveCertDomainInfo{ { diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go b/pkg/core/ssl-deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go index 3b054e24..4984496e 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go @@ -137,7 +137,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func (d *SSLDeployerProvider) getDomainsByCertId(cloudCertId string) ([]string, error) { // 获取证书中的可用域名 - // REF: https://cloud.tencent.com/document/product/228/42491 + // REF: https://cloud.tencent.com/document/api/228/42491 describeCertDomainsReq := tccdn.NewDescribeCertDomainsRequest() describeCertDomainsReq.CertId = common.StringPtr(cloudCertId) describeCertDomainsReq.Product = common.StringPtr("ecdn") @@ -159,7 +159,7 @@ func (d *SSLDeployerProvider) getDomainsByCertId(cloudCertId string) ([]string, func (d *SSLDeployerProvider) updateDomainHttpsServerCert(ctx context.Context, domain string, cloudCertId string) error { // 查询域名详细配置 - // REF: https://cloud.tencent.com/document/product/228/41117 + // REF: https://cloud.tencent.com/document/api/228/41117 describeDomainsConfigReq := tccdn.NewDescribeDomainsConfigRequest() describeDomainsConfigReq.Filters = []*tccdn.DomainFilter{ { @@ -184,7 +184,7 @@ func (d *SSLDeployerProvider) updateDomainHttpsServerCert(ctx context.Context, d } // 更新加速域名配置 - // REF: https://cloud.tencent.com/document/product/228/41116 + // REF: https://cloud.tencent.com/document/api/228/41116 updateDomainConfigReq := tccdn.NewUpdateDomainConfigRequest() updateDomainConfigReq.Domain = common.StringPtr(domain) updateDomainConfigReq.Https = domainConfig.Https diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-eo/tencentcloud_eo.go b/pkg/core/ssl-deployer/providers/tencentcloud-eo/tencentcloud_eo.go index c18ced57..5540c8c8 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-eo/tencentcloud_eo.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-eo/tencentcloud_eo.go @@ -95,7 +95,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke } // 配置域名证书 - // REF: https://cloud.tencent.com/document/product/1552/80764 + // REF: https://cloud.tencent.com/document/api/1552/80764 modifyHostsCertificateReq := tcteo.NewModifyHostsCertificateRequest() modifyHostsCertificateReq.ZoneId = common.StringPtr(d.config.ZoneId) modifyHostsCertificateReq.Mode = common.StringPtr("sslcert") diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-gaap/tencentcloud_gaap.go b/pkg/core/ssl-deployer/providers/tencentcloud-gaap/tencentcloud_gaap.go index 09e6da8e..c6d32af4 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-gaap/tencentcloud_gaap.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-gaap/tencentcloud_gaap.go @@ -121,7 +121,7 @@ func (d *SSLDeployerProvider) deployToListener(ctx context.Context, cloudCertId func (d *SSLDeployerProvider) modifyHttpsListenerCertificate(ctx context.Context, cloudListenerId, cloudCertId string) error { // 查询 HTTPS 监听器信息 - // REF: https://cloud.tencent.com/document/product/608/37001 + // REF: https://cloud.tencent.com/document/api/608/37001 describeHTTPSListenersReq := tcgaap.NewDescribeHTTPSListenersRequest() describeHTTPSListenersReq.ListenerId = common.StringPtr(cloudListenerId) describeHTTPSListenersReq.Offset = common.Uint64Ptr(0) @@ -135,7 +135,7 @@ func (d *SSLDeployerProvider) modifyHttpsListenerCertificate(ctx context.Context } // 修改 HTTPS 监听器配置 - // REF: https://cloud.tencent.com/document/product/608/36996 + // REF: https://cloud.tencent.com/document/api/608/36996 modifyHTTPSListenerAttributeReq := tcgaap.NewModifyHTTPSListenerAttributeRequest() modifyHTTPSListenerAttributeReq.ProxyId = xtypes.ToPtrOrZeroNil(d.config.ProxyId) modifyHTTPSListenerAttributeReq.ListenerId = common.StringPtr(cloudListenerId) diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-scf/tencentcloud_scf.go b/pkg/core/ssl-deployer/providers/tencentcloud-scf/tencentcloud_scf.go index 94729516..83f1da37 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-scf/tencentcloud_scf.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-scf/tencentcloud_scf.go @@ -84,7 +84,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke } // 查看云函数自定义域名详情 - // REF: https://cloud.tencent.com/document/product/583/111924 + // REF: https://cloud.tencent.com/document/api/583/111924 getCustomDomainReq := tcscf.NewGetCustomDomainRequest() getCustomDomainReq.Domain = common.StringPtr(d.config.Domain) getCustomDomainResp, err := d.sdkClient.GetCustomDomain(getCustomDomainReq) @@ -102,7 +102,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke } // 更新云函数自定义域名 - // REF: https://cloud.tencent.com/document/product/583/111922 + // REF: https://cloud.tencent.com/document/api/583/111922 updateCustomDomainReq := tcscf.NewUpdateCustomDomainRequest() updateCustomDomainReq.Domain = common.StringPtr(d.config.Domain) updateCustomDomainReq.CertConfig = &tcscf.CertConf{ diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go b/pkg/core/ssl-deployer/providers/tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go index 4c2de86c..5f9229f6 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go @@ -24,10 +24,10 @@ type SSLDeployerProviderConfig struct { Endpoint string `json:"endpoint,omitempty"` // 腾讯云地域。 Region string `json:"region"` - // 腾讯云云资源类型。 + // 云资源类型。 ResourceType string `json:"resourceType"` - // 腾讯云云资源 ID 数组。 - ResourceIds []string `json:"resourceIds"` + // 云资源 ID 数组。 + ResourceIds []string `json:"resourceIds,omitempty"` } type SSLDeployerProvider struct { @@ -93,7 +93,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke } // 证书部署到云资源实例列表 - // REF: https://cloud.tencent.com/document/product/400/91667 + // REF: https://cloud.tencent.com/document/api/400/91667 deployCertificateInstanceReq := tcssl.NewDeployCertificateInstanceRequest() deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId) deployCertificateInstanceReq.ResourceType = common.StringPtr(d.config.ResourceType) diff --git a/pkg/core/ssl-manager/providers/tencentcloud-ssl/tencentcloud_ssl.go b/pkg/core/ssl-manager/providers/tencentcloud-ssl/tencentcloud_ssl.go index fc062b72..e504e8d5 100644 --- a/pkg/core/ssl-manager/providers/tencentcloud-ssl/tencentcloud_ssl.go +++ b/pkg/core/ssl-manager/providers/tencentcloud-ssl/tencentcloud_ssl.go @@ -56,7 +56,7 @@ func (m *SSLManagerProvider) SetLogger(logger *slog.Logger) { func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkeyPEM string) (*core.SSLManageUploadResult, error) { // 上传新证书 - // REF: https://cloud.tencent.com/document/product/400/41665 + // REF: https://cloud.tencent.com/document/api/400/41665 uploadCertificateReq := tcssl.NewUploadCertificateRequest() uploadCertificateReq.CertificatePublicKey = common.StringPtr(certPEM) uploadCertificateReq.CertificatePrivateKey = common.StringPtr(privkeyPEM) From d7d18d932a4448892f56b63bc6e62c8d5f6d15b0 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Mon, 23 Jun 2025 16:19:05 +0800 Subject: [PATCH 05/16] chore(deps): upgrade gomod dependencies --- go.mod | 90 +++++++++++++------------- go.sum | 196 ++++++++++++++++++++++++++++----------------------------- 2 files changed, 143 insertions(+), 143 deletions(-) diff --git a/go.mod b/go.mod index 399f6f86..489284dc 100644 --- a/go.mod +++ b/go.mod @@ -6,18 +6,18 @@ toolchain go1.24.3 require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.0 - github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azcertificates v1.3.1 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 + github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azcertificates v1.4.0 github.com/Edgio/edgio-api v0.0.0-workspace github.com/G-Core/gcorelabscdn-go v1.0.31 - github.com/alibabacloud-go/alb-20200616/v2 v2.2.8 + github.com/alibabacloud-go/alb-20200616/v2 v2.2.9 github.com/alibabacloud-go/apig-20240327/v3 v3.2.2 github.com/alibabacloud-go/cas-20200407/v3 v3.0.4 github.com/alibabacloud-go/cdn-20180510/v5 v5.2.2 github.com/alibabacloud-go/cloudapi-20160714/v5 v5.7.4 github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.7 github.com/alibabacloud-go/ddoscoo-20200101/v4 v4.0.0 - github.com/alibabacloud-go/esa-20240910/v2 v2.33.0 + github.com/alibabacloud-go/esa-20240910/v2 v2.34.1 github.com/alibabacloud-go/fc-20230330/v4 v4.3.5 github.com/alibabacloud-go/fc-open-20210406/v2 v2.0.12 github.com/alibabacloud-go/ga-20191120/v3 v3.1.8 @@ -26,19 +26,19 @@ require ( github.com/alibabacloud-go/slb-20140515/v4 v4.0.10 github.com/alibabacloud-go/tea v1.3.9 github.com/alibabacloud-go/vod-20170321/v4 v4.8.4 - github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.1.3 + github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.4.0 github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible - github.com/aws/aws-sdk-go-v2/service/acm v1.32.0 - github.com/aws/aws-sdk-go-v2/service/cloudfront v1.46.1 - github.com/aws/aws-sdk-go-v2/service/iam v1.42.0 - github.com/baidubce/bce-sdk-go v0.9.228 + github.com/aws/aws-sdk-go-v2/service/acm v1.33.0 + github.com/aws/aws-sdk-go-v2/service/cloudfront v1.46.3 + github.com/aws/aws-sdk-go-v2/service/iam v1.42.2 + github.com/baidubce/bce-sdk-go v0.9.231 github.com/blinkbean/dingtalk v1.1.3 - github.com/byteplus-sdk/byteplus-sdk-golang v1.0.46 + github.com/byteplus-sdk/byteplus-sdk-golang v1.0.50 github.com/go-acme/lego/v4 v4.23.1 github.com/go-lark/lark v1.16.0 github.com/go-resty/resty/v2 v2.16.5 - github.com/go-viper/mapstructure/v2 v2.2.1 - github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.150 + github.com/go-viper/mapstructure/v2 v2.3.0 + github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.155 github.com/jdcloud-api/jdcloud-sdk-go v1.64.0 github.com/libdns/dynv6 v1.0.0 github.com/libdns/libdns v0.2.3 @@ -46,30 +46,30 @@ require ( github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0 github.com/pkg/sftp v1.13.9 github.com/pocketbase/dbx v1.11.0 - github.com/pocketbase/pocketbase v0.28.2 + github.com/pocketbase/pocketbase v0.28.4 github.com/povsister/scp v0.0.0-20250504051308-e467f71ea63c - github.com/qiniu/go-sdk/v7 v7.25.3 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1155 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1166 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1173 + github.com/qiniu/go-sdk/v7 v7.25.4 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1187 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1188 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1192 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.0.1163 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1150 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1192 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1172 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1169 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1166 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1164 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1170 - github.com/ucloud/ucloud-sdk-go v0.22.41 - github.com/volcengine/ve-tos-golang-sdk/v2 v2.7.12 - github.com/volcengine/volc-sdk-golang v1.0.208 - github.com/volcengine/volcengine-go-sdk v1.1.8 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1189 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1191 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1183 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1182 + github.com/ucloud/ucloud-sdk-go v0.22.44 + github.com/volcengine/ve-tos-golang-sdk/v2 v2.7.17 + github.com/volcengine/volc-sdk-golang v1.0.212 + github.com/volcengine/volcengine-go-sdk v1.1.18 gitlab.ecloud.com/ecloud/ecloudsdkclouddns v1.0.1 gitlab.ecloud.com/ecloud/ecloudsdkcore v1.0.0 - golang.org/x/crypto v0.38.0 - golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 - k8s.io/api v0.33.1 - k8s.io/apimachinery v0.33.1 - k8s.io/client-go v0.33.1 + golang.org/x/crypto v0.39.0 + golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b + k8s.io/api v0.33.2 + k8s.io/apimachinery v0.33.2 + k8s.io/client-go v0.33.2 software.sslmate.com/src/go-pkcs12 v0.5.0 ) @@ -78,7 +78,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.3.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.9.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect github.com/alibabacloud-go/alibabacloud-gateway-fc-util v0.0.7 // indirect github.com/alibabacloud-go/openplatform-20191219/v2 v2.0.1 // indirect @@ -154,19 +154,19 @@ require ( github.com/aliyun/alibaba-cloud-sdk-go v1.63.100 // indirect github.com/aliyun/credentials-go v1.4.6 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go-v2 v1.36.3 + github.com/aws/aws-sdk-go-v2 v1.36.5 github.com/aws/aws-sdk-go-v2/config v1.29.9 github.com/aws/aws-sdk-go-v2/credentials v1.17.62 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.25.1 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.1 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.33.17 // indirect - github.com/aws/smithy-go v1.22.2 // indirect + github.com/aws/smithy-go v1.22.4 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/clbanning/mxj/v2 v2.7.0 // indirect github.com/cloudflare/cloudflare-go v0.115.0 // indirect @@ -195,28 +195,28 @@ require ( github.com/nrdcg/namesilo v0.2.1 // indirect github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/spf13/cast v1.8.0 // indirect + github.com/spf13/cast v1.9.2 // indirect github.com/spf13/cobra v1.9.1 // indirect github.com/spf13/pflag v1.0.6 // indirect github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1128 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect - golang.org/x/image v0.27.0 // indirect - golang.org/x/mod v0.24.0 // indirect - golang.org/x/net v0.40.0 // indirect + golang.org/x/image v0.28.0 // indirect + golang.org/x/mod v0.25.0 // indirect + golang.org/x/net v0.41.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.14.0 + golang.org/x/sync v0.15.0 golang.org/x/sys v0.33.0 // indirect golang.org/x/term v0.32.0 // indirect - golang.org/x/text v0.25.0 // indirect + golang.org/x/text v0.26.0 // indirect golang.org/x/time v0.11.0 - golang.org/x/tools v0.33.0 // indirect + golang.org/x/tools v0.34.0 // indirect google.golang.org/protobuf v1.36.5 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - modernc.org/libc v1.65.7 // indirect + modernc.org/libc v1.65.10 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect - modernc.org/sqlite v1.37.1 // indirect + modernc.org/sqlite v1.38.0 // indirect ) replace github.com/Edgio/edgio-api v0.0.0-workspace => ./pkg/sdk3rd/edgio/edgio-api@v0.0.0-workspace diff --git a/go.sum b/go.sum index eb4dc407..7da97356 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,8 @@ filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4 github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.0 h1:j8BorDEigD8UFOSZQiSqAMOOleyQOOQPnUAwV+Ls1gA= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.0/go.mod h1:JdM5psgjfBf5fo2uWOZhflPWyDBZ/O/CNAH9CtsuZE4= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 h1:B+blDbyVIG3WaikNxPnhPiJ1MThR03b3vKGtER95TP4= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1/go.mod h1:JdM5psgjfBf5fo2uWOZhflPWyDBZ/O/CNAH9CtsuZE4= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4= @@ -52,10 +52,10 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourceg github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.9.0/go.mod h1:wVEOJfGTj0oPAUGA1JuRAvz/lxXQsWW16axmHPP47Bk= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azcertificates v1.3.1 h1:HUJQzFYTv7t3V1dxPms52eEgl0l9xCNqutDrY45Lvmw= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azcertificates v1.3.1/go.mod h1:ig/8nSkzmfxm5QGeIy5JYIEj8JEFy5JxvY3OB1YNRC4= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 h1:bFWuoEKg+gImo7pvkiQEFAc8ocibADgXeiLAxWhWmkI= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1/go.mod h1:Vih/3yc6yac2JzU4hzpaDupBJP0Flaia9rXXrU8xyww= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azcertificates v1.4.0 h1:mtvR5ZXH5Ew6PSONd5lO5OXovWP1E3oAlgC8fpxor2Q= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azcertificates v1.4.0/go.mod h1:u560+RFVfG0CBPzkXlDW43slESbBAQjgDGi3r6z+wk8= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 h1:nCYfgcSyHZXJI8J0IWE5MsCGlb2xp9fJiXyxWgmOFg4= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0/go.mod h1:ucUjca2JtSZboY8IoUqyQyuuXvwbMBVwFOm0vdQPNhA= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs= @@ -86,8 +86,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alex-ant/gomath v0.0.0-20160516115720-89013a210a82/go.mod h1:nLnM0KdK1CmygvjpDUO6m1TjSsiQtL61juhNsvV/JVI= -github.com/alibabacloud-go/alb-20200616/v2 v2.2.8 h1:/6+1AqIiENG3u6RmEYWEQ/YZv3YgdFZkE6Xd9RZM6n0= -github.com/alibabacloud-go/alb-20200616/v2 v2.2.8/go.mod h1:jU/K+GVb5b0vjiDpkf6E0dH77tsi1jTLGWm4ouCiRxk= +github.com/alibabacloud-go/alb-20200616/v2 v2.2.9 h1:0pEYgxbkQiXOLKhkCBHPnTEl4X1Ahkoo45qMcyElm+U= +github.com/alibabacloud-go/alb-20200616/v2 v2.2.9/go.mod h1:7revp3b2AHMZq+8GhU+WMFCwqbHC2KSvEDPeAzmTdY0= github.com/alibabacloud-go/alibabacloud-gateway-fc-util v0.0.7 h1:RDatRb9RG39HjkevgzTeiVoDDaamoB+12GHNairp3Ag= github.com/alibabacloud-go/alibabacloud-gateway-fc-util v0.0.7/go.mod h1:H0RPHXHP/ICfEQrKzQcCqXI15jcV4zaDPCOAmh3U9O8= github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6 h1:eIf+iGJxdU4U9ypaUfbtOWCsZSbTb8AUHvyPrxu6mAA= @@ -132,8 +132,8 @@ github.com/alibabacloud-go/debug v1.0.1/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/ql github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE= github.com/alibabacloud-go/endpoint-util v1.1.1 h1:ZkBv2/jnghxtU0p+upSU0GGzW1VL9GQdZO3mcSUTUy8= github.com/alibabacloud-go/endpoint-util v1.1.1/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE= -github.com/alibabacloud-go/esa-20240910/v2 v2.33.0 h1:10IWxrMcF1W6/7BUJIJifrofduSG0wRFqDbRfIsR3Zw= -github.com/alibabacloud-go/esa-20240910/v2 v2.33.0/go.mod h1:HZS5PmYJvcmH4vrJYuCvK3AnYzD9hLlO8CT0hgRyDXo= +github.com/alibabacloud-go/esa-20240910/v2 v2.34.1 h1:G8AWEhIGZ6QhZ6Or/bdhAZP0o9qEXCbxT5dkLqdl6gY= +github.com/alibabacloud-go/esa-20240910/v2 v2.34.1/go.mod h1:HZS5PmYJvcmH4vrJYuCvK3AnYzD9hLlO8CT0hgRyDXo= github.com/alibabacloud-go/fc-20230330/v4 v4.3.5 h1:nDNjVzGwkQPbQnAuxAmxvS9x8QGLph8j0ptEdZDPGBA= github.com/alibabacloud-go/fc-20230330/v4 v4.3.5/go.mod h1:vEJimQ6E/e+m2z0/oXdeQWlFw/Pi/Ar6NKcMrSvcILE= github.com/alibabacloud-go/fc-open-20210406/v2 v2.0.12 h1:A3D8Mp6qf8DfR6Dt5MpS8aDVaWfS4N85T5CvGUvgrjM= @@ -190,8 +190,8 @@ github.com/alibabacloud-go/tea-xml v1.1.3 h1:7LYnm+JbOq2B+T/B0fHC4Ies4/FofC4zHzY github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8= github.com/alibabacloud-go/vod-20170321/v4 v4.8.4 h1:MYP2xfrcud8vlWljQ4lhemNgAgi9/AUAa450n8TUXZo= github.com/alibabacloud-go/vod-20170321/v4 v4.8.4/go.mod h1:5ocQ6hIc9tpGixD2iy099aOGwIgpzjT2le4Krd4aLn8= -github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.1.3 h1:25tmcJxIitrk55crBGssPlqRzmFcpGVW5TEFxdUvfg0= -github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.1.3/go.mod h1:9itYSTzipL3NlvhvNYfTjFaapoZzG68nlu/KUdh9SpA= +github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.4.0 h1:eEfAqN1Z9PW9SzQ3YOvT5EADzjVwG9Fg4s3xLGSHJxk= +github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.4.0/go.mod h1:9itYSTzipL3NlvhvNYfTjFaapoZzG68nlu/KUdh9SpA= github.com/aliyun/alibaba-cloud-sdk-go v1.63.100 h1:yUkCbrSM1cWtgBfRVKMQtdt22KhDvKY7g4V+92eG9wA= github.com/aliyun/alibaba-cloud-sdk-go v1.63.100/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ= github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g= @@ -216,27 +216,27 @@ github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHS github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-sdk-go v1.40.45/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= -github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM= -github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg= +github.com/aws/aws-sdk-go-v2 v1.36.5 h1:0OF9RiEMEdDdZEMqF9MRjevyxAQcf6gY+E7vwBILFj0= +github.com/aws/aws-sdk-go-v2 v1.36.5/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= github.com/aws/aws-sdk-go-v2/config v1.29.9 h1:Kg+fAYNaJeGXp1vmjtidss8O2uXIsXwaRqsQJKXVr+0= github.com/aws/aws-sdk-go-v2/config v1.29.9/go.mod h1:oU3jj2O53kgOU4TXq/yipt6ryiooYjlkqqVaZk7gY/U= github.com/aws/aws-sdk-go-v2/credentials v1.17.62 h1:fvtQY3zFzYJ9CfixuAQ96IxDrBajbBWGqjNTCa79ocU= github.com/aws/aws-sdk-go-v2/credentials v1.17.62/go.mod h1:ElETBxIQqcxej++Cs8GyPBbgMys5DgQPTwo7cUPDKt8= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 h1:SsytQyTMHMDPspp+spo7XwXTP44aJZZAC7fBV2C5+5s= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36/go.mod h1:Q1lnJArKRXkenyog6+Y+zr7WDpk4e6XlR6gs20bbeNo= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 h1:i2vNHQiXUvKhs3quBR6aqlgJaiaexz/aNvdCktW/kAM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36/go.mod h1:UdyGa7Q91id/sdyHPwth+043HhmP6yP9MBHgbZM0xo8= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= -github.com/aws/aws-sdk-go-v2/service/acm v1.32.0 h1:Ik/TAn4TBw/t3JhQJKtwjgoOf6kg5nXc190TiGhNrmI= -github.com/aws/aws-sdk-go-v2/service/acm v1.32.0/go.mod h1:3sKYAgRbuBa2QMYGh/WEclwnmfx+QoPhhX25PdSQSQM= -github.com/aws/aws-sdk-go-v2/service/cloudfront v1.46.1 h1:6xZNYtuVwzBs8k+TmraERt0vL68Ppg9aUi+aTQmPaVM= -github.com/aws/aws-sdk-go-v2/service/cloudfront v1.46.1/go.mod h1:FIBJ48TS+qJb+Ne4qJ+0NeIhtPTVXItXooTeNeVI4Po= +github.com/aws/aws-sdk-go-v2/service/acm v1.33.0 h1:Z3MHBWR1KiviwaAiG7MTPB6T5gLYRPhUECuKLgltCwA= +github.com/aws/aws-sdk-go-v2/service/acm v1.33.0/go.mod h1:t3jPqKBnySV3qsU40cj1TWleOYx5vyz1xBeZiplAVcs= +github.com/aws/aws-sdk-go-v2/service/cloudfront v1.46.3 h1:ULVZL6Ro+vqmXFVFgZ5Q92pqWnhJfwOnWlNtibQPnIs= +github.com/aws/aws-sdk-go-v2/service/cloudfront v1.46.3/go.mod h1:vudWcTOLhQf4lzRH0qHUszJh8Gpo+Lp6dqH/HgVR9Xg= github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o= -github.com/aws/aws-sdk-go-v2/service/iam v1.42.0 h1:G6+UzGvubaet9QOh0664E9JeT+b6Zvop3AChozRqkrA= -github.com/aws/aws-sdk-go-v2/service/iam v1.42.0/go.mod h1:mPJkGQzeCoPs82ElNILor2JzZgYENr4UaSKUT8K27+c= +github.com/aws/aws-sdk-go-v2/service/iam v1.42.2 h1:IrauIGCnD90jXDFpAKYzCgrbagk/Yta4L+zxcVLOA58= +github.com/aws/aws-sdk-go-v2/service/iam v1.42.2/go.mod h1:QRtwvoAGc59uxv4vQHPKr75SLzhYCRSoETxAA98r6O4= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM= @@ -250,10 +250,10 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.1/go.mod h1:MlYRNmYu/fGPoxBQV github.com/aws/aws-sdk-go-v2/service/sts v1.33.17 h1:PZV5W8yk4OtH1JAuhV2PXwwO9v5G5Aoj+eMCn4T+1Kc= github.com/aws/aws-sdk-go-v2/service/sts v1.33.17/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4= github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= -github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ= -github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= -github.com/baidubce/bce-sdk-go v0.9.228 h1:XEY3/oAxXcsi7+3atib9fMI6YNE9sL5qo+WMZ+iqmNE= -github.com/baidubce/bce-sdk-go v0.9.228/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg= +github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= +github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/baidubce/bce-sdk-go v0.9.231 h1:inKgFMUkVXy05D3jfdKxEuOFiXxlLk/1A2+dWChu2X4= +github.com/baidubce/bce-sdk-go v0.9.231/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -263,8 +263,8 @@ github.com/blinkbean/dingtalk v1.1.3 h1:MbidFZYom7DTFHD/YIs+eaI7kRy52kmWE/sy0xjo github.com/blinkbean/dingtalk v1.1.3/go.mod h1:9BaLuGSBqY3vT5hstValh48DbsKO7vaHaJnG9pXwbto= github.com/buger/goterm v1.0.4 h1:Z9YvGmOih81P0FbVtEYTFF6YsSgxSUKEhf/f9bTMXbY= github.com/buger/goterm v1.0.4/go.mod h1:HiFWV3xnkolgrBV3mY8m0X0Pumt4zg4QhbdOzQtB8tE= -github.com/byteplus-sdk/byteplus-sdk-golang v1.0.46 h1:Z0TagIjBDaoCZuJANP/P8+z+ef8dStVCBPjMZcI/y8s= -github.com/byteplus-sdk/byteplus-sdk-golang v1.0.46/go.mod h1:CIL/T2dxgbIA79os+wl0Fq0vCbADTZNIddV6PNYB6DY= +github.com/byteplus-sdk/byteplus-sdk-golang v1.0.50 h1:iwaWNNgRxFwJ/ejnj5LXpfqwwsdgF/ByA3QczXOCKbg= +github.com/byteplus-sdk/byteplus-sdk-golang v1.0.50/go.mod h1:CIL/T2dxgbIA79os+wl0Fq0vCbADTZNIddV6PNYB6DY= github.com/casbin/casbin/v2 v2.37.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= @@ -407,8 +407,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= -github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk= +github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= @@ -547,8 +547,8 @@ github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.150 h1:Ih+z79Ko1ClH4dlv7O1lyHRiVCjkb2NZYYk+1cSZbU8= -github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.150/go.mod h1:Y/+YLCFCJtS29i2MbYPTUlNNfwXvkzEsZKR0imY/2aY= +github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.155 h1:R8hjwhuy5qzrYbqpj0D/fwGPDZgmlIyBjT3fzZbM38Q= +github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.155/go.mod h1:Y/+YLCFCJtS29i2MbYPTUlNNfwXvkzEsZKR0imY/2aY= github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -739,8 +739,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pocketbase/dbx v1.11.0 h1:LpZezioMfT3K4tLrqA55wWFw1EtH1pM4tzSVa7kgszU= github.com/pocketbase/dbx v1.11.0/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs= -github.com/pocketbase/pocketbase v0.28.2 h1:b6cfUfr5d4whvUFGFhI8oHRzx/eB76GCUQGftqgv9lM= -github.com/pocketbase/pocketbase v0.28.2/go.mod h1:ElwIYS1b5xS9w0U7AK7tsm6FuC0lzw57H8p/118Cu7g= +github.com/pocketbase/pocketbase v0.28.4 h1:RmhWXDcfKrFM9/W0G0Zrlv4eKBM8/s/v4SQKytjgD20= +github.com/pocketbase/pocketbase v0.28.4/go.mod h1:jSuN93vE/oeJVOz2D2ZxcYyr2bYNmDOMCUkM+JhyJQ0= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/povsister/scp v0.0.0-20250504051308-e467f71ea63c h1:1+j5JHz9mUzYSp0scuF6hzvJP28EDBFe5eBJb0xnGk4= @@ -767,8 +767,8 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/qiniu/dyn v1.3.0 h1:s+xPTeV0H8yikgM4ZMBc7Rrefam8UNI3asBlkaOQg5o= github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdkk= -github.com/qiniu/go-sdk/v7 v7.25.3 h1:eYHh02q4i5MrlEn3qy823w7moieymFzb4dsP38Y43AI= -github.com/qiniu/go-sdk/v7 v7.25.3/go.mod h1:dmKtJ2ahhPWFVi9o1D5GemmWoh/ctuB9peqTowyTO8o= +github.com/qiniu/go-sdk/v7 v7.25.4 h1:ulCKlTEyrZzmNytXweOrnva49+Q4+ASjYBCSXhkRWTo= +github.com/qiniu/go-sdk/v7 v7.25.4/go.mod h1:dmKtJ2ahhPWFVi9o1D5GemmWoh/ctuB9peqTowyTO8o= github.com/qiniu/x v1.10.5 h1:7V/CYWEmo9axJULvrJN6sMYh2FdY+esN5h8jwDkA4b0= github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -801,8 +801,8 @@ github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYl github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/cast v1.8.0 h1:gEN9K4b8Xws4EX0+a0reLmhq8moKn7ntRlQYgjPeCDk= -github.com/spf13/cast v1.8.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE= +github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= @@ -829,37 +829,37 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1155 h1:ildxJtjnqiKZxWDVKHT/ncIknGDijtg60MuFELON8bY= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1155/go.mod h1:iLASpooTdyXtx642E5Ws7cfWENsp4/uZ/78TFoln7OI= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1166 h1:cEoDsBt7vGh7YtfVHVmgXKQURZANBE8UKK/So84QUdU= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1166/go.mod h1:0o5Cfgdh+bAx7kpQ5a5wce/ZUiDvy4Md8NcbrLtk6i8= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1187 h1:x2q6BAFm2f+9YaE7/lGPWXL7HzRkovjoqOMbdtRdpBw= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1187/go.mod h1:GoIHP0ayv0QOWN4c9aUEaKi74lY/tbeJz7h5i8y2gdU= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1188 h1:zzaIE12soTfyAgRvBYhb5bYxFXRCelvYXDEfvtkT5Y4= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1188/go.mod h1:qIWFhWbmMuUaWCCKVSkdJ1BzKEOqkMeo+uKYS6jJimQ= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1128/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1150/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1155/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1163/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1164/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1166/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1169/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1170/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1172/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1173 h1:W5bzEWiJwiwRZR0/P1l78OYWUXYsXLjhBaQ64c+9+fk= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1173/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1182/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1183/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1187/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1188/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1189/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1191/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1192 h1:3K6aJXXkjBLxqFYnBqAqFW5YqxmwMT0HR2F4gxQiNMU= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1192/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1128 h1:mrJ5Fbkd7sZIJ5F6oRfh5zebPQaudPH9Y0+GUmFytYU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1128/go.mod h1:zbsYIBT+VTX4z4ocjTAdLBIWyNYj3z0BRqd0iPdnjsk= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.0.1163 h1:putqrH5n1SVRqFWHOylVqYI5yLQUjRTkHqZPLT2yeVY= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.0.1163/go.mod h1:aEWRXlAvovPUUoS3kVB/LVWEQ19WqzTj2lXGvR1YArY= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1150 h1:RQQYfZOFYlkxKR2+xp8el3+8xs9DhxBy+ajlHtapqtQ= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1150/go.mod h1:zpfr6EBWy7ClASTGUgIy01Gn4R79UXf+2QGQeyR124A= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1192 h1:2430drceaOXASJZyVZ+e7QSzgBfgwSjDEDM5rh4046M= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1192/go.mod h1:JHZLo95Fde/0et2Ag2E5P6VmCZQIq74MClUtanJ4JcY= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1172 h1:6SUO0hTie3zxnUEMxmhnS1iRIXpAukSZV27Nrx4NwIk= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1172/go.mod h1:tmN4zfu70SD0iee3qfpc09NRLel30zGoAuzIs4X0Kfs= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1169 h1:oBymtJEmKDnS2NIR0PDLd+xCGQ+7uMoEt7zEB5Q3x8U= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1169/go.mod h1:K27PNEgRJ602ESXUNnlRnCkf1+XYHI6RVP/ylIe/Aro= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1166 h1:+kIsoG2If/0y15PpZsXfT0QqTuwec9nMgo1JP8KQMkw= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1166/go.mod h1:lGmBMXqe3vBg6Bi9h4mVpWLKd7jQIMRbndr8KNHBqSw= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1164 h1:caaIGWOs/JtWOK5ptVMEiiGgzU7Jf6UpMv+9IbIa4vs= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1164/go.mod h1:SJI2mc77gDC7Tw1QoF/4d5SwLvz8HQFUecWtIXb+r/Q= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1170 h1:kcQCWuI9zOkZgL5CK66HNAJmSWCSJxRrDxXT+j02CeE= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1170/go.mod h1:vTukVfThbBIc4lOf4eq/q51eEk78oZUJd2lAoJBOJwI= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1189 h1:Db7gmkey7On70PAohvrna6RMLZzLHRjbALxPlH5JC3c= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1189/go.mod h1:x+WlMCjbePO7M3R0qzKmrpmieUWrtsRpcKBDpxJNQ5A= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1191 h1:4l1Db+yFh9HgqNynYbG93khxLtXSBwnXZgNmc88jOE0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1191/go.mod h1:y8if4wInFJoO6PU0/741VEYREHPtfxljhJ5HFD2ZkEA= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1183 h1:3fvxkF/R1WaO937Wrx5ZCYoIof1X9sqSDXL218uRfJY= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1183/go.mod h1:d47RTYqj/2xjIk/lmq8bQ9deUwfEQcWhPQxUgqZnz24= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1182 h1:2DaykFM5mXvQBvuhQEU/aOG5amissS31XI1wZh+FeMA= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1182/go.mod h1:pTAgdVcS28xFIARJXhg10hx2+g/Q9FqVkAkal3ARNfc= github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= @@ -868,18 +868,18 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ucloud/ucloud-sdk-go v0.22.41 h1:JndTJhCx7A1wggZfVb4KMm7D0Wfvd/HkmQVfSNjClQA= -github.com/ucloud/ucloud-sdk-go v0.22.41/go.mod h1:dyLmFHmUfgb4RZKYQP9IArlvQ2pxzFthfhwxRzOEPIw= +github.com/ucloud/ucloud-sdk-go v0.22.44 h1:AuWtd6xw2abQ8MAAI6ebWIYsTpoUfE6v2WMY8s5inPY= +github.com/ucloud/ucloud-sdk-go v0.22.44/go.mod h1:dyLmFHmUfgb4RZKYQP9IArlvQ2pxzFthfhwxRzOEPIw= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= -github.com/volcengine/ve-tos-golang-sdk/v2 v2.7.12 h1:u9+32DXQIOFPG8oQ3xrjSAUSyAcaq5bqO4cEBom/6lA= -github.com/volcengine/ve-tos-golang-sdk/v2 v2.7.12/go.mod h1:IrjK84IJJTuOZOTMv/P18Ydjy/x+ow7fF7q11jAxXLM= +github.com/volcengine/ve-tos-golang-sdk/v2 v2.7.17 h1:j3czHCTIG/xwjzQ71bwM57+Wg7R1XTe757o6PeCh+B4= +github.com/volcengine/ve-tos-golang-sdk/v2 v2.7.17/go.mod h1:IrjK84IJJTuOZOTMv/P18Ydjy/x+ow7fF7q11jAxXLM= github.com/volcengine/volc-sdk-golang v1.0.23/go.mod h1:AfG/PZRUkHJ9inETvbjNifTDgut25Wbkm2QoYBTbvyU= -github.com/volcengine/volc-sdk-golang v1.0.208 h1:DyGUPjEKhWS08BkptfqenXTuUq+LKb7+gX/RBAtNl8w= -github.com/volcengine/volc-sdk-golang v1.0.208/go.mod h1:stZX+EPgv1vF4nZwOlEe8iGcriUPRBKX8zA19gXycOQ= -github.com/volcengine/volcengine-go-sdk v1.1.8 h1:/T2p7qeeLWWhGrhtB00b8VNlE32S266LcO+jqFUYwzY= -github.com/volcengine/volcengine-go-sdk v1.1.8/go.mod h1:EyKoi6t6eZxoPNGr2GdFCZti2Skd7MO3eUzx7TtSvNo= +github.com/volcengine/volc-sdk-golang v1.0.212 h1:evyoDoYTPqc1j23cnTnbHO7Vu813O2VERWQ/FVm8z+k= +github.com/volcengine/volc-sdk-golang v1.0.212/go.mod h1:stZX+EPgv1vF4nZwOlEe8iGcriUPRBKX8zA19gXycOQ= +github.com/volcengine/volcengine-go-sdk v1.1.18 h1:tVcp1m6R8fgwZFb/MaltrpZY7b2+vYNbmO1MHlDSXIs= +github.com/volcengine/volcengine-go-sdk v1.1.18/go.mod h1:EyKoi6t6eZxoPNGr2GdFCZti2Skd7MO3eUzx7TtSvNo= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= @@ -947,8 +947,8 @@ golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOM golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= -golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -962,14 +962,14 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= +golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= +golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w= -golang.org/x/image v0.27.0/go.mod h1:xbdrClrAUway1MUTEZDq9mz/UpRwYAkFFNUslZtcB+g= +golang.org/x/image v0.28.0 h1:gdem5JW1OLS4FbkWgLO+7ZeFzYtL3xClb97GaUzYMFE= +golang.org/x/image v0.28.0/go.mod h1:GUJYXtnGKEUgggyzh+Vxt+AviiCcyiwpsl8iQ8MvwGY= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -995,8 +995,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= +golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1052,8 +1052,8 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= +golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= +golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1079,8 +1079,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= -golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= +golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1196,8 +1196,8 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1259,8 +1259,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= -golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= +golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= +golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1400,12 +1400,12 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.33.1 h1:tA6Cf3bHnLIrUK4IqEgb2v++/GYUtqiu9sRVk3iBXyw= -k8s.io/api v0.33.1/go.mod h1:87esjTn9DRSRTD4fWMXamiXxJhpOIREjWOSjsW1kEHw= -k8s.io/apimachinery v0.33.1 h1:mzqXWV8tW9Rw4VeW9rEkqvnxj59k1ezDUl20tFK/oM4= -k8s.io/apimachinery v0.33.1/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= -k8s.io/client-go v0.33.1 h1:ZZV/Ks2g92cyxWkRRnfUDsnhNn28eFpt26aGc8KbXF4= -k8s.io/client-go v0.33.1/go.mod h1:JAsUrl1ArO7uRVFWfcj6kOomSlCv+JpvIsp6usAGefA= +k8s.io/api v0.33.2 h1:YgwIS5jKfA+BZg//OQhkJNIfie/kmRsO0BmNaVSimvY= +k8s.io/api v0.33.2/go.mod h1:fhrbphQJSM2cXzCWgqU29xLDuks4mu7ti9vveEnpSXs= +k8s.io/apimachinery v0.33.2 h1:IHFVhqg59mb8PJWTLi8m1mAoepkUNYmptHsV+Z1m5jY= +k8s.io/apimachinery v0.33.2/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= +k8s.io/client-go v0.33.2 h1:z8CIcc0P581x/J1ZYf4CNzRKxRvQAwoAolYPbtQes+E= +k8s.io/client-go v0.33.2/go.mod h1:9mCgT4wROvL948w6f6ArJNb7yQd7QsvqavDeZHvNmHo= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= @@ -1417,12 +1417,12 @@ modernc.org/cc/v4 v4.26.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU= modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE= modernc.org/fileutil v1.0.0/go.mod h1:JHsWpkrk/CnVV1H/eGlFf85BEpfkrp56ro8nojIq9Q8= -modernc.org/fileutil v1.3.1 h1:8vq5fe7jdtEvoCf3Zf9Nm0Q05sH6kGx0Op2CPx1wTC8= -modernc.org/fileutil v1.3.1/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= +modernc.org/fileutil v1.3.3 h1:3qaU+7f7xxTUmvU1pJTZiDLAIoJVdUSSauJNHg9yXoA= +modernc.org/fileutil v1.3.3/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= -modernc.org/libc v1.65.7 h1:Ia9Z4yzZtWNtUIuiPuQ7Qf7kxYrxP1/jeHZzG8bFu00= -modernc.org/libc v1.65.7/go.mod h1:011EQibzzio/VX3ygj1qGFt5kMjP0lHb0qCW5/D/pQU= +modernc.org/libc v1.65.10 h1:ZwEk8+jhW7qBjHIT+wd0d9VjitRyQef9BnzlzGwMODc= +modernc.org/libc v1.65.10/go.mod h1:StFvYpx7i/mXtBAfVOjaU0PWZOvIRoZSgXhrwXzr8Po= modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= @@ -1431,8 +1431,8 @@ modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= -modernc.org/sqlite v1.37.1 h1:EgHJK/FPoqC+q2YBXg7fUmES37pCHFc97sI7zSayBEs= -modernc.org/sqlite v1.37.1/go.mod h1:XwdRtsE1MpiBcL54+MbKcaDvcuej+IYSMfLN6gSKV8g= +modernc.org/sqlite v1.38.0 h1:+4OrfPQ8pxHKuWG4md1JpR/EYAh3Md7TdejuuzE7EUI= +modernc.org/sqlite v1.38.0/go.mod h1:1Bj+yES4SVvBZ4cBOpVZ6QgesMCKpJZDq0nxYzOpmNE= modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= From cfee0e2b4af351eb03f860010d6557f24f344cb1 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Mon, 23 Jun 2025 17:08:06 +0800 Subject: [PATCH 06/16] chore(deps): upgrade npm dependencies --- ui/package-lock.json | 939 ++++++++++-------- ui/package.json | 46 +- ui/src/components/access/AccessForm.tsx | 4 +- .../access/AccessForm1PanelConfig.tsx | 4 +- .../access/AccessFormACMECAConfig.tsx | 4 +- .../access/AccessFormACMEHttpReqConfig.tsx | 4 +- .../access/AccessFormAPISIXConfig.tsx | 4 +- .../components/access/AccessFormAWSConfig.tsx | 2 +- .../access/AccessFormAliyunConfig.tsx | 2 +- .../access/AccessFormAzureConfig.tsx | 2 +- .../access/AccessFormBaiduCloudConfig.tsx | 2 +- .../access/AccessFormBaishanConfig.tsx | 2 +- .../access/AccessFormBaotaPanelConfig.tsx | 4 +- .../access/AccessFormBaotaWAFConfig.tsx | 4 +- .../access/AccessFormBunnyConfig.tsx | 2 +- .../access/AccessFormBytePlusConfig.tsx | 2 +- .../access/AccessFormCMCCCloudConfig.tsx | 2 +- .../access/AccessFormCTCCCloudConfig.tsx | 2 +- .../access/AccessFormCacheFlyConfig.tsx | 2 +- .../access/AccessFormCdnflyConfig.tsx | 4 +- .../access/AccessFormClouDNSConfig.tsx | 2 +- .../access/AccessFormCloudflareConfig.tsx | 2 +- .../access/AccessFormConstellixConfig.tsx | 2 +- .../access/AccessFormDNSLAConfig.tsx | 2 +- .../access/AccessFormDeSECConfig.tsx | 2 +- .../access/AccessFormDigitalOceanConfig.tsx | 2 +- .../access/AccessFormDingTalkBotConfig.tsx | 4 +- .../access/AccessFormDiscordBotConfig.tsx | 4 +- .../access/AccessFormDogeCloudConfig.tsx | 2 +- .../access/AccessFormDuckDNSConfig.tsx | 2 +- .../access/AccessFormDynv6Config.tsx | 2 +- .../access/AccessFormEdgioConfig.tsx | 2 +- .../access/AccessFormEmailConfig.tsx | 2 +- .../access/AccessFormFlexCDNConfig.tsx | 8 +- .../access/AccessFormGcoreConfig.tsx | 2 +- .../access/AccessFormGnameConfig.tsx | 2 +- .../access/AccessFormGoDaddyConfig.tsx | 2 +- .../access/AccessFormGoEdgeConfig.tsx | 8 +- .../AccessFormGoogleTrustServicesConfig.tsx | 2 +- .../access/AccessFormHetznerConfig.tsx | 2 +- .../access/AccessFormHuaweiCloudConfig.tsx | 2 +- .../access/AccessFormJDCloudConfig.tsx | 2 +- .../access/AccessFormKubernetesConfig.tsx | 2 +- .../access/AccessFormLarkBotConfig.tsx | 4 +- .../access/AccessFormLeCDNConfig.tsx | 8 +- .../access/AccessFormMattermostConfig.tsx | 4 +- .../components/access/AccessFormNS1Config.tsx | 2 +- .../access/AccessFormNameDotComConfig.tsx | 2 +- .../access/AccessFormNameSiloConfig.tsx | 2 +- .../access/AccessFormNamecheapConfig.tsx | 2 +- .../access/AccessFormNetcupConfig.tsx | 2 +- .../access/AccessFormNetlifyConfig.tsx | 2 +- .../access/AccessFormPorkbunConfig.tsx | 2 +- .../access/AccessFormPowerDNSConfig.tsx | 4 +- .../access/AccessFormProxmoxVEConfig.tsx | 4 +- .../access/AccessFormQiniuConfig.tsx | 2 +- .../access/AccessFormRainYunConfig.tsx | 2 +- .../access/AccessFormRatPanelConfig.tsx | 4 +- .../components/access/AccessFormSSHConfig.tsx | 22 +- .../access/AccessFormSSLComConfig.tsx | 2 +- .../access/AccessFormSafeLineConfig.tsx | 4 +- .../access/AccessFormSlackBotConfig.tsx | 4 +- .../access/AccessFormTelegramBotConfig.tsx | 4 +- .../access/AccessFormTencentCloudConfig.tsx | 2 +- .../access/AccessFormUCloudConfig.tsx | 2 +- .../access/AccessFormUniCloudConfig.tsx | 2 +- .../access/AccessFormUpyunConfig.tsx | 2 +- .../access/AccessFormVercelConfig.tsx | 2 +- .../access/AccessFormVolcEngineConfig.tsx | 2 +- .../access/AccessFormWangsuConfig.tsx | 2 +- .../access/AccessFormWeComBotConfig.tsx | 4 +- .../access/AccessFormWebhookConfig.tsx | 8 +- .../access/AccessFormWestcnConfig.tsx | 2 +- .../access/AccessFormZeroSSLConfig.tsx | 2 +- .../NotifyChannelEditFormBarkFields.tsx | 9 +- .../NotifyChannelEditFormDingTalkFields.tsx | 6 +- .../NotifyChannelEditFormEmailFields.tsx | 17 +- .../NotifyChannelEditFormGotifyFields.tsx | 13 +- .../NotifyChannelEditFormLarkFields.tsx | 4 +- .../NotifyChannelEditFormMattermostFields.tsx | 10 +- .../NotifyChannelEditFormPushPlusFields.tsx | 4 +- .../NotifyChannelEditFormPushoverFields.tsx | 6 +- .../NotifyChannelEditFormServerChanFields.tsx | 4 +- .../NotifyChannelEditFormTelegramFields.tsx | 6 +- .../NotifyChannelEditFormWeComFields.tsx | 4 +- .../NotifyChannelEditFormWebhookFields.tsx | 4 +- .../notification/NotifyTemplate.tsx | 2 +- .../workflow/node/ApplyNodeConfigForm.tsx | 21 +- .../ApplyNodeConfigFormAWSRoute53Config.tsx | 8 +- .../ApplyNodeConfigFormAliyunESAConfig.tsx | 6 +- ...pplyNodeConfigFormHuaweiCloudDNSConfig.tsx | 4 +- .../ApplyNodeConfigFormJDCloudDNSConfig.tsx | 4 +- ...pplyNodeConfigFormTencentCloudEOConfig.tsx | 4 +- .../workflow/node/ConditionNodeConfigForm.tsx | 2 +- .../workflow/node/DeployNodeConfigForm.tsx | 10 +- ...eployNodeConfigForm1PanelConsoleConfig.tsx | 2 +- .../DeployNodeConfigForm1PanelSiteConfig.tsx | 6 +- .../node/DeployNodeConfigFormAPISIXConfig.tsx | 6 +- .../node/DeployNodeConfigFormAWSACMConfig.tsx | 6 +- ...eployNodeConfigFormAWSCloudFrontConfig.tsx | 2 +- .../node/DeployNodeConfigFormAWSIAMConfig.tsx | 6 +- .../DeployNodeConfigFormAliyunALBConfig.tsx | 10 +- .../DeployNodeConfigFormAliyunAPIGWConfig.tsx | 10 +- .../DeployNodeConfigFormAliyunCASConfig.tsx | 6 +- ...loyNodeConfigFormAliyunCASDeployConfig.tsx | 8 +- .../DeployNodeConfigFormAliyunCDNConfig.tsx | 4 +- .../DeployNodeConfigFormAliyunCLBConfig.tsx | 12 +- .../DeployNodeConfigFormAliyunDCDNConfig.tsx | 4 +- .../DeployNodeConfigFormAliyunDDoSConfig.tsx | 8 +- .../DeployNodeConfigFormAliyunESAConfig.tsx | 8 +- .../DeployNodeConfigFormAliyunFCConfig.tsx | 12 +- .../DeployNodeConfigFormAliyunGAConfig.tsx | 6 +- .../DeployNodeConfigFormAliyunLiveConfig.tsx | 8 +- .../DeployNodeConfigFormAliyunNLBConfig.tsx | 10 +- .../DeployNodeConfigFormAliyunOSSConfig.tsx | 12 +- .../DeployNodeConfigFormAliyunVODConfig.tsx | 10 +- .../DeployNodeConfigFormAliyunWAFConfig.tsx | 12 +- ...eployNodeConfigFormAzureKeyVaultConfig.tsx | 4 +- ...oyNodeConfigFormBaiduCloudAppBLBConfig.tsx | 10 +- ...eployNodeConfigFormBaiduCloudBLBConfig.tsx | 10 +- ...eployNodeConfigFormBaiduCloudCDNConfig.tsx | 4 +- .../DeployNodeConfigFormBaishanCDNConfig.tsx | 4 +- ...yNodeConfigFormBaotaPanelConsoleConfig.tsx | 2 +- ...ployNodeConfigFormBaotaPanelSiteConfig.tsx | 6 +- ...DeployNodeConfigFormBaotaWAFSiteConfig.tsx | 2 +- .../DeployNodeConfigFormBunnyCDNConfig.tsx | 4 +- .../DeployNodeConfigFormBytePlusCDNConfig.tsx | 4 +- .../DeployNodeConfigFormCTCCCloudAOConfig.tsx | 4 +- ...DeployNodeConfigFormCTCCCloudCDNConfig.tsx | 4 +- ...DeployNodeConfigFormCTCCCloudELBConfig.tsx | 8 +- ...eployNodeConfigFormCTCCCloudICDNConfig.tsx | 4 +- ...eployNodeConfigFormCTCCCloudLVDNConfig.tsx | 6 +- .../node/DeployNodeConfigFormCdnflyConfig.tsx | 6 +- ...DeployNodeConfigFormDogeCloudCDNConfig.tsx | 6 +- ...yNodeConfigFormEdgioApplicationsConfig.tsx | 4 +- .../DeployNodeConfigFormFlexCDNConfig.tsx | 6 +- .../DeployNodeConfigFormGcoreCDNConfig.tsx | 4 +- .../node/DeployNodeConfigFormGoEdgeConfig.tsx | 6 +- ...ployNodeConfigFormHuaweiCloudCDNConfig.tsx | 8 +- ...ployNodeConfigFormHuaweiCloudELBConfig.tsx | 11 +- ...ployNodeConfigFormHuaweiCloudWAFConfig.tsx | 11 +- .../DeployNodeConfigFormJDCloudALBConfig.tsx | 8 +- .../DeployNodeConfigFormJDCloudCDNConfig.tsx | 4 +- .../DeployNodeConfigFormJDCloudLiveConfig.tsx | 6 +- .../DeployNodeConfigFormJDCloudVODConfig.tsx | 6 +- ...oyNodeConfigFormKubernetesSecretConfig.tsx | 12 +- .../node/DeployNodeConfigFormLeCDNConfig.tsx | 6 +- .../node/DeployNodeConfigFormLocalConfig.tsx | 20 +- .../DeployNodeConfigFormNetlifySiteConfig.tsx | 2 +- .../DeployNodeConfigFormProxmoxVEConfig.tsx | 6 +- .../DeployNodeConfigFormQiniuCDNConfig.tsx | 4 +- .../DeployNodeConfigFormQiniuKodoConfig.tsx | 6 +- .../DeployNodeConfigFormQiniuPiliConfig.tsx | 6 +- .../DeployNodeConfigFormRainYunRCDNConfig.tsx | 6 +- ...DeployNodeConfigFormRatPanelSiteConfig.tsx | 2 +- .../node/DeployNodeConfigFormSSHConfig.tsx | 16 +- .../DeployNodeConfigFormSafeLineConfig.tsx | 6 +- ...loyNodeConfigFormTencentCloudCDNConfig.tsx | 4 +- ...loyNodeConfigFormTencentCloudCLBConfig.tsx | 20 +- ...loyNodeConfigFormTencentCloudCOSConfig.tsx | 10 +- ...loyNodeConfigFormTencentCloudCSSConfig.tsx | 4 +- ...oyNodeConfigFormTencentCloudECDNConfig.tsx | 4 +- ...ployNodeConfigFormTencentCloudEOConfig.tsx | 6 +- ...oyNodeConfigFormTencentCloudGAAPConfig.tsx | 4 +- ...loyNodeConfigFormTencentCloudSCFConfig.tsx | 8 +- ...loyNodeConfigFormTencentCloudSSLConfig.tsx | 2 +- ...eConfigFormTencentCloudSSLDeployConfig.tsx | 8 +- ...loyNodeConfigFormTencentCloudVODConfig.tsx | 8 +- ...loyNodeConfigFormTencentCloudWAFConfig.tsx | 12 +- .../DeployNodeConfigFormUCloudUCDNConfig.tsx | 4 +- .../DeployNodeConfigFormUCloudUS3Config.tsx | 14 +- ...loyNodeConfigFormUniCloudWebHostConfig.tsx | 2 +- .../DeployNodeConfigFormUpyunCDNConfig.tsx | 4 +- .../DeployNodeConfigFormUpyunFileConfig.tsx | 6 +- ...eployNodeConfigFormVolcEngineALBConfig.tsx | 8 +- ...eployNodeConfigFormVolcEngineCDNConfig.tsx | 4 +- ...eployNodeConfigFormVolcEngineCLBConfig.tsx | 8 +- ...deConfigFormVolcEngineCertCenterConfig.tsx | 4 +- ...ployNodeConfigFormVolcEngineDCDNConfig.tsx | 4 +- ...oyNodeConfigFormVolcEngineImageXConfig.tsx | 10 +- ...ployNodeConfigFormVolcEngineLiveConfig.tsx | 4 +- ...eployNodeConfigFormVolcEngineTOSConfig.tsx | 10 +- .../DeployNodeConfigFormWangsuCDNConfig.tsx | 2 +- ...DeployNodeConfigFormWangsuCDNProConfig.tsx | 8 +- ...yNodeConfigFormWangsuCertificateConfig.tsx | 2 +- .../DeployNodeConfigFormWebhookConfig.tsx | 2 +- .../workflow/node/MonitorNodeConfigForm.tsx | 2 +- .../workflow/node/NotifyNodeConfigForm.tsx | 10 +- .../NotifyNodeConfigFormDiscordBotConfig.tsx | 2 +- .../node/NotifyNodeConfigFormEmailConfig.tsx | 2 +- .../NotifyNodeConfigFormMattermostConfig.tsx | 2 +- .../NotifyNodeConfigFormSlackBotConfig.tsx | 2 +- .../NotifyNodeConfigFormTelegramBotConfig.tsx | 2 +- .../NotifyNodeConfigFormWebhookConfig.tsx | 2 +- .../workflow/node/StartNodeConfigForm.tsx | 30 +- .../workflow/node/UploadNodeConfigForm.tsx | 6 +- ui/src/pages/login/Login.tsx | 4 +- ui/src/pages/settings/SettingsAccount.tsx | 4 +- ui/src/pages/settings/SettingsPassword.tsx | 8 +- ui/src/pages/settings/SettingsPersistence.tsx | 6 +- ui/src/pages/settings/SettingsSSLProvider.tsx | 14 +- ui/src/pages/workflows/WorkflowDetail.tsx | 6 +- ui/src/pages/workflows/WorkflowNew.tsx | 6 +- ui/src/utils/validators.ts | 8 +- 204 files changed, 1023 insertions(+), 1060 deletions(-) diff --git a/ui/package-lock.json b/ui/package-lock.json index e1bbb340..43e91d13 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -9,34 +9,34 @@ "version": "0.0.0", "dependencies": { "@ant-design/icons": "^6.0.0", - "@ant-design/pro-components": "^2.8.7", - "@codemirror/lang-json": "^6.0.1", + "@ant-design/pro-components": "^2.8.9", + "@codemirror/lang-json": "^6.0.2", "@codemirror/lang-yaml": "^6.1.2", - "@codemirror/language": "^6.11.0", + "@codemirror/language": "^6.11.1", "@codemirror/legacy-modes": "^6.5.1", - "@uiw/codemirror-extensions-basic-setup": "^4.23.12", - "@uiw/codemirror-theme-vscode": "^4.23.12", - "@uiw/react-codemirror": "^4.23.12", + "@uiw/codemirror-extensions-basic-setup": "^4.23.13", + "@uiw/codemirror-theme-vscode": "^4.23.13", + "@uiw/react-codemirror": "^4.23.13", "ahooks": "^3.8.5", - "antd": "^5.25.3", - "antd-zod": "^6.1.0", + "antd": "^5.26.1", + "antd-zod": "^7.0.0", "clsx": "^2.1.1", - "cron-parser": "^5.2.0", + "cron-parser": "^5.3.0", "file-saver": "^2.0.5", "i18next": "^25.2.1", - "i18next-browser-languagedetector": "^8.1.0", + "i18next-browser-languagedetector": "^8.2.0", "immer": "^10.1.1", - "lucide-react": "^0.511.0", + "lucide-react": "^0.522.0", "nanoid": "^5.1.5", - "pocketbase": "^0.26.0", - "radash": "^12.1.0", + "pocketbase": "^0.26.1", + "radash": "^12.1.1", "react": "^18.3.1", "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.3.1", - "react-i18next": "^15.5.2", - "react-router-dom": "^7.6.1", + "react-i18next": "^15.5.3", + "react-router-dom": "^7.6.2", "tailwind-merge": "^2.6.0", - "zod": "^3.25.28", + "zod": "^3.25.67", "zustand": "^5.0.5" }, "devDependencies": { @@ -46,22 +46,22 @@ "@types/react": "^18.3.12", "@types/react-copy-to-clipboard": "^5.0.7", "@types/react-dom": "^18.3.1", - "@typescript-eslint/eslint-plugin": "^8.32.1", - "@typescript-eslint/parser": "^8.32.1", + "@typescript-eslint/eslint-plugin": "^8.34.1", + "@typescript-eslint/parser": "^8.34.1", "@vitejs/plugin-legacy": "^6.1.1", - "@vitejs/plugin-react": "^4.5.0", + "@vitejs/plugin-react": "^4.6.0", "autoprefixer": "^10.4.21", "eslint": "^8.57.0", "eslint-config-prettier": "^10.1.5", "eslint-import-resolver-typescript": "^3.8.3", - "eslint-plugin-import": "^2.31.0", - "eslint-plugin-prettier": "^5.4.0", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-prettier": "^5.5.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", "eslint-plugin-tailwindcss": "^3.18.0", "fs-extra": "^11.3.0", - "postcss": "^8.5.3", - "prettier": "^3.5.3", + "postcss": "^8.5.6", + "prettier": "^3.6.0", "tailwindcss": "^3.4.17", "tailwindcss-animate": "^1.0.7", "typescript": "^5.8.3", @@ -184,14 +184,14 @@ } }, "node_modules/@ant-design/pro-card": { - "version": "2.9.7", - "resolved": "https://registry.npmmirror.com/@ant-design/pro-card/-/pro-card-2.9.7.tgz", - "integrity": "sha512-uDDYowmYH1ldRfG8Mb4QOwcEEz6ptRBQDLO1tkVADCRkdOMwz82xlZneR4uVuFyKcuNmgHzarYNncozBKhFuaA==", + "version": "2.9.9", + "resolved": "https://registry.npmmirror.com/@ant-design/pro-card/-/pro-card-2.9.9.tgz", + "integrity": "sha512-n0evqAu8rmw/xCkVk7l/8Tk0HqeVPPHeieDCtFKoRIG/ajiadAVM3NfkndEjYKuWbw/dgaVOyc5wW0iBD6dKCA==", "dependencies": { "@ant-design/cssinjs": "^1.21.1", "@ant-design/icons": "^5.0.0", - "@ant-design/pro-provider": "2.15.4", - "@ant-design/pro-utils": "2.17.0", + "@ant-design/pro-provider": "2.16.1", + "@ant-design/pro-utils": "2.17.2", "@babel/runtime": "^7.18.0", "classnames": "^2.3.2", "rc-resize-observer": "^1.0.0", @@ -222,20 +222,20 @@ } }, "node_modules/@ant-design/pro-components": { - "version": "2.8.7", - "resolved": "https://registry.npmmirror.com/@ant-design/pro-components/-/pro-components-2.8.7.tgz", - "integrity": "sha512-QhibkPsUJryEjI1QmwUn+XCngGHidu0ekvricL6TIEvPgP+AUAca29XutN5+Mmn8Xfja1ca9HFTHTgFoV74Z7Q==", + "version": "2.8.9", + "resolved": "https://registry.npmmirror.com/@ant-design/pro-components/-/pro-components-2.8.9.tgz", + "integrity": "sha512-8qs4UxZOjsSoMl3goer0sGEKKlN51LxE55AkXeP924oq9ffi7tuVEE6y3qag96VwQIgbML1215qgnFoStXmF0w==", "dependencies": { - "@ant-design/pro-card": "2.9.7", - "@ant-design/pro-descriptions": "2.6.7", - "@ant-design/pro-field": "3.0.4", - "@ant-design/pro-form": "2.31.7", - "@ant-design/pro-layout": "7.22.4", - "@ant-design/pro-list": "2.6.7", - "@ant-design/pro-provider": "2.15.4", + "@ant-design/pro-card": "2.9.9", + "@ant-design/pro-descriptions": "2.6.9", + "@ant-design/pro-field": "3.0.6", + "@ant-design/pro-form": "2.31.9", + "@ant-design/pro-layout": "7.22.6", + "@ant-design/pro-list": "2.6.9", + "@ant-design/pro-provider": "2.16.1", "@ant-design/pro-skeleton": "2.2.1", - "@ant-design/pro-table": "3.19.0", - "@ant-design/pro-utils": "2.17.0", + "@ant-design/pro-table": "3.20.1", + "@ant-design/pro-utils": "2.17.2", "@babel/runtime": "^7.16.3" }, "peerDependencies": { @@ -245,15 +245,15 @@ } }, "node_modules/@ant-design/pro-descriptions": { - "version": "2.6.7", - "resolved": "https://registry.npmmirror.com/@ant-design/pro-descriptions/-/pro-descriptions-2.6.7.tgz", - "integrity": "sha512-fgn2d0kDWUODGDWKpgziZuuqPlmIoKxQFJY9Yg4nbaRp8GDDKZeSSqgvW+OxjpYM8dxq31fiz1dZlZnOPoYKpg==", + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/@ant-design/pro-descriptions/-/pro-descriptions-2.6.9.tgz", + "integrity": "sha512-UU1XIFoPCTLRUQM0aMStQ364MvCucEcVNOvgP75iGboajCWxwtwtWNqiCkHrtmoorgxpNYa0lS6Utho1fvXlQA==", "dependencies": { - "@ant-design/pro-field": "3.0.4", - "@ant-design/pro-form": "2.31.7", - "@ant-design/pro-provider": "2.15.4", + "@ant-design/pro-field": "3.0.6", + "@ant-design/pro-form": "2.31.9", + "@ant-design/pro-provider": "2.16.1", "@ant-design/pro-skeleton": "2.2.1", - "@ant-design/pro-utils": "2.17.0", + "@ant-design/pro-utils": "2.17.2", "@babel/runtime": "^7.18.0", "rc-resize-observer": "^0.2.3", "rc-util": "^5.0.6" @@ -279,13 +279,13 @@ } }, "node_modules/@ant-design/pro-field": { - "version": "3.0.4", - "resolved": "https://registry.npmmirror.com/@ant-design/pro-field/-/pro-field-3.0.4.tgz", - "integrity": "sha512-nJSng/6/pPZFdiFeTtZcBQLNrHg9tIeiKFR1+zzbnQbI3qBOFP9aBZS/+LwkQZcI2G71vrRgz2x5OhHb7AX0wQ==", + "version": "3.0.6", + "resolved": "https://registry.npmmirror.com/@ant-design/pro-field/-/pro-field-3.0.6.tgz", + "integrity": "sha512-zjJAMS5+lu7Zw95UzPY15DmEpHbT9UKPxWPiSQMAJGXUJRYm3ajDYomq7c0gWznpbxuOIiDojhbK5y4CHHcrAw==", "dependencies": { "@ant-design/icons": "^5.0.0", - "@ant-design/pro-provider": "2.15.4", - "@ant-design/pro-utils": "2.17.0", + "@ant-design/pro-provider": "2.16.1", + "@ant-design/pro-utils": "2.17.2", "@babel/runtime": "^7.18.0", "@chenshuai2144/sketch-color": "^1.0.8", "classnames": "^2.3.2", @@ -320,14 +320,14 @@ } }, "node_modules/@ant-design/pro-form": { - "version": "2.31.7", - "resolved": "https://registry.npmmirror.com/@ant-design/pro-form/-/pro-form-2.31.7.tgz", - "integrity": "sha512-0TCtIC/ynbLPoes8sLBFwFbi0tkeNmSU6the2EcyKIKDLfWHDbfkLM1OSFrzv3QD+H8OgFWMkTSOjhMOKSsOBg==", + "version": "2.31.9", + "resolved": "https://registry.npmmirror.com/@ant-design/pro-form/-/pro-form-2.31.9.tgz", + "integrity": "sha512-w8lKCWkpuf7tZnRSQAoGxlRuo2r+8sXMxo8Vba2fi7/wb4u75ECI8qQ9r5dUeN1muBxfWlqBOywEwi9jqXE23Q==", "dependencies": { "@ant-design/icons": "^5.0.0", - "@ant-design/pro-field": "3.0.4", - "@ant-design/pro-provider": "2.15.4", - "@ant-design/pro-utils": "2.17.0", + "@ant-design/pro-field": "3.0.6", + "@ant-design/pro-provider": "2.16.1", + "@ant-design/pro-utils": "2.17.2", "@babel/runtime": "^7.18.0", "@chenshuai2144/sketch-color": "^1.0.7", "@umijs/use-params": "^1.0.9", @@ -365,14 +365,14 @@ } }, "node_modules/@ant-design/pro-layout": { - "version": "7.22.4", - "resolved": "https://registry.npmmirror.com/@ant-design/pro-layout/-/pro-layout-7.22.4.tgz", - "integrity": "sha512-X2WO4L2itXemX4zhS+0NG+8kXQD5SX9sG+zjx/15BmIO3FvsUGqOHgoCg0vhd424EiyPj7WtdMZJ39G1xdgDwA==", + "version": "7.22.6", + "resolved": "https://registry.npmmirror.com/@ant-design/pro-layout/-/pro-layout-7.22.6.tgz", + "integrity": "sha512-4DGK9nZ7B0FGVpJkMCUDrksBhTHc/pg72BMOBguqMOZCdsuEuJAyIl12eYK8gasGcbYtHzjvdYCamR+TJR8Low==", "dependencies": { "@ant-design/cssinjs": "^1.21.1", "@ant-design/icons": "^5.0.0", - "@ant-design/pro-provider": "2.15.4", - "@ant-design/pro-utils": "2.17.0", + "@ant-design/pro-provider": "2.16.1", + "@ant-design/pro-utils": "2.17.2", "@babel/runtime": "^7.18.0", "@umijs/route-utils": "^4.0.0", "@umijs/use-params": "^1.0.9", @@ -411,16 +411,16 @@ } }, "node_modules/@ant-design/pro-list": { - "version": "2.6.7", - "resolved": "https://registry.npmmirror.com/@ant-design/pro-list/-/pro-list-2.6.7.tgz", - "integrity": "sha512-6k/En7pioMgepho/1HMf2DAnkSTZiat1lDg2ggCok2lhSgqXzir7x22ewJQRgPvEiVb6/qqaFQNd7a8dnrFj1w==", + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/@ant-design/pro-list/-/pro-list-2.6.9.tgz", + "integrity": "sha512-YKA/6yCjngQnwjMdAzgjMxOInfQf6Wk+gm0tZJzXs/9GYk0cMIOv5OdaSFW9IBsSmzJ97nBZECYCSOlsgz51uw==", "dependencies": { "@ant-design/cssinjs": "^1.21.1", "@ant-design/icons": "^5.0.0", - "@ant-design/pro-card": "2.9.7", - "@ant-design/pro-field": "3.0.4", - "@ant-design/pro-table": "3.19.0", - "@ant-design/pro-utils": "2.17.0", + "@ant-design/pro-card": "2.9.9", + "@ant-design/pro-field": "3.0.6", + "@ant-design/pro-table": "3.20.1", + "@ant-design/pro-utils": "2.17.2", "@babel/runtime": "^7.18.0", "classnames": "^2.3.2", "dayjs": "^1.11.10", @@ -483,9 +483,9 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/@ant-design/pro-provider": { - "version": "2.15.4", - "resolved": "https://registry.npmmirror.com/@ant-design/pro-provider/-/pro-provider-2.15.4.tgz", - "integrity": "sha512-DBX0JNUNOYXAucVqd/zTdqtXckCDqr2Lo85KIku2YzWdhptDPDZRTNqL04JShjGejDl8fzwQ8yREHgVUfzn6Gg==", + "version": "2.16.1", + "resolved": "https://registry.npmmirror.com/@ant-design/pro-provider/-/pro-provider-2.16.1.tgz", + "integrity": "sha512-9kSiptgoEybRleajA9KiMqnGqLTbIGdm7TDclBS4QGGrjkHfcXDw+GruiDwghOHvTwTkZT98Xttvw4w1XfrS+g==", "dependencies": { "@ant-design/cssinjs": "^1.21.1", "@babel/runtime": "^7.18.0", @@ -514,17 +514,17 @@ } }, "node_modules/@ant-design/pro-table": { - "version": "3.19.0", - "resolved": "https://registry.npmmirror.com/@ant-design/pro-table/-/pro-table-3.19.0.tgz", - "integrity": "sha512-nL25734d5q5oqtmG7Apn2TNJUnJE8m9dkopXMQdoNZnv8qeRQLBH+i5cZT1yh7FIO8z6QLXleg+KnR/cI7VRRw==", + "version": "3.20.1", + "resolved": "https://registry.npmmirror.com/@ant-design/pro-table/-/pro-table-3.20.1.tgz", + "integrity": "sha512-QsxKkHfkKnLIZsuznoNBVws0OGGTvOWAk+uWqgb7QBo8jxhofMUDQ/fs10wGSuX5Jm78DhVfMBGBhq8hcZaj7Q==", "dependencies": { "@ant-design/cssinjs": "^1.21.1", "@ant-design/icons": "^5.0.0", - "@ant-design/pro-card": "2.9.7", - "@ant-design/pro-field": "3.0.4", - "@ant-design/pro-form": "2.31.7", - "@ant-design/pro-provider": "2.15.4", - "@ant-design/pro-utils": "2.17.0", + "@ant-design/pro-card": "2.9.9", + "@ant-design/pro-field": "3.0.6", + "@ant-design/pro-form": "2.31.9", + "@ant-design/pro-provider": "2.16.1", + "@ant-design/pro-utils": "2.17.2", "@babel/runtime": "^7.18.0", "@dnd-kit/core": "^6.0.8", "@dnd-kit/modifiers": "^6.0.1", @@ -564,12 +564,12 @@ } }, "node_modules/@ant-design/pro-utils": { - "version": "2.17.0", - "resolved": "https://registry.npmmirror.com/@ant-design/pro-utils/-/pro-utils-2.17.0.tgz", - "integrity": "sha512-hHKUISjMEoS+E5ltJWyvNTrlEA3IimZNxtDrEhorRIbgVYAlmEN5Mj/ESSofzDM3+UlxiI5+A/Y6IHkByTfDEA==", + "version": "2.17.2", + "resolved": "https://registry.npmmirror.com/@ant-design/pro-utils/-/pro-utils-2.17.2.tgz", + "integrity": "sha512-DE7H14nfmdTyPwmJA1mgxHzcedOHSBYpTcqCvEAooK8fi8yXpcwpUs7XuUTeFHPj1gHYl/17X8Mzc3ngB8s63Q==", "dependencies": { "@ant-design/icons": "^5.0.0", - "@ant-design/pro-provider": "2.15.4", + "@ant-design/pro-provider": "2.16.1", "@babel/runtime": "^7.18.0", "classnames": "^2.3.2", "dayjs": "^1.11.10", @@ -620,44 +620,44 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", + "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.26.8", - "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.26.8.tgz", - "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "version": "7.27.5", + "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.27.5.tgz", + "integrity": "sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.26.10", - "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.26.10.tgz", - "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "version": "7.27.4", + "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.27.4.tgz", + "integrity": "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.10", - "@babel/helper-compilation-targets": "^7.26.5", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.10", - "@babel/parser": "^7.26.10", - "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.10", - "@babel/types": "^7.26.10", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.4", + "@babel/parser": "^7.27.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.27.4", + "@babel/types": "^7.27.3", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -682,13 +682,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.27.0", - "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.27.0.tgz", - "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", + "version": "7.27.5", + "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.27.5.tgz", + "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", "dev": true, "dependencies": { - "@babel/parser": "^7.27.0", - "@babel/types": "^7.27.0", + "@babel/parser": "^7.27.5", + "@babel/types": "^7.27.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -710,13 +710,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.26.5", - "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", - "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", + "version": "7.27.2", + "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.26.5", - "@babel/helper-validator-option": "^7.25.9", + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -820,27 +820,27 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.25.9", - "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "dev": true, "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.26.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "version": "7.27.3", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" }, "engines": { "node": ">=6.9.0" @@ -862,9 +862,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.26.5", - "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", - "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "dev": true, "engines": { "node": ">=6.9.0" @@ -918,27 +918,27 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.25.9", - "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, "engines": { "node": ">=6.9.0" @@ -959,25 +959,25 @@ } }, "node_modules/@babel/helpers": { - "version": "7.27.0", - "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.27.0.tgz", - "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", + "version": "7.27.6", + "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.27.6.tgz", + "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", "dev": true, "dependencies": { - "@babel/template": "^7.27.0", - "@babel/types": "^7.27.0" + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.27.0", - "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.27.0.tgz", - "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", + "version": "7.27.5", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.27.5.tgz", + "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==", "dev": true, "dependencies": { - "@babel/types": "^7.27.0" + "@babel/types": "^7.27.3" }, "bin": { "parser": "bin/babel-parser.js" @@ -1725,12 +1725,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.25.9", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", - "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1740,12 +1740,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.25.9", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", - "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -2047,38 +2047,38 @@ } }, "node_modules/@babel/runtime": { - "version": "7.27.1", - "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.27.1.tgz", - "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==", + "version": "7.27.6", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.27.6.tgz", + "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.27.0", - "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.27.0.tgz", - "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", + "version": "7.27.2", + "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/parser": "^7.27.0", - "@babel/types": "^7.27.0" + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.27.0", - "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.27.0.tgz", - "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", + "version": "7.27.4", + "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.27.4.tgz", + "integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.27.0", - "@babel/parser": "^7.27.0", - "@babel/template": "^7.27.0", - "@babel/types": "^7.27.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/parser": "^7.27.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.3", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2087,13 +2087,13 @@ } }, "node_modules/@babel/types": { - "version": "7.27.0", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.27.0.tgz", - "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", + "version": "7.27.6", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.27.6.tgz", + "integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -2134,9 +2134,9 @@ } }, "node_modules/@codemirror/lang-json": { - "version": "6.0.1", - "resolved": "https://registry.npmmirror.com/@codemirror/lang-json/-/lang-json-6.0.1.tgz", - "integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==", + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/@codemirror/lang-json/-/lang-json-6.0.2.tgz", + "integrity": "sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==", "dependencies": { "@codemirror/language": "^6.0.0", "@lezer/json": "^1.0.0" @@ -2157,9 +2157,9 @@ } }, "node_modules/@codemirror/language": { - "version": "6.11.0", - "resolved": "https://registry.npmmirror.com/@codemirror/language/-/language-6.11.0.tgz", - "integrity": "sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==", + "version": "6.11.1", + "resolved": "https://registry.npmmirror.com/@codemirror/language/-/language-6.11.1.tgz", + "integrity": "sha512-5kS1U7emOGV84vxC+ruBty5sUgcD0te6dyupyRVG2zaSjhTDM73LhVKUtVwiqSe6QwmEoA4SCiU8AKPFyumAWQ==", "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.23.0", @@ -3059,9 +3059,9 @@ } }, "node_modules/@pkgr/core": { - "version": "0.2.4", - "resolved": "https://registry.npmmirror.com/@pkgr/core/-/core-0.2.4.tgz", - "integrity": "sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw==", + "version": "0.2.7", + "resolved": "https://registry.npmmirror.com/@pkgr/core/-/core-0.2.7.tgz", + "integrity": "sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==", "dev": true, "engines": { "node": "^12.20.0 || ^14.18.0 || >=16.0.0" @@ -3223,9 +3223,9 @@ } }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.9", - "resolved": "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.9.tgz", - "integrity": "sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w==", + "version": "1.0.0-beta.19", + "resolved": "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.19.tgz", + "integrity": "sha512-3FL3mnMbPu0muGOCaKAhhFEYmqv9eTfPSJRJmANrCwtgK8VuxpsZDGK+m0LYAGoyO8+0j5uRe4PeyPDK1yA/hA==", "dev": true }, "node_modules/@rollup/rollup-android-arm-eabi": { @@ -3616,16 +3616,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.32.1", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.1.tgz", - "integrity": "sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==", + "version": "8.34.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.34.1.tgz", + "integrity": "sha512-STXcN6ebF6li4PxwNeFnqF8/2BNDvBupf2OPx2yWNzr6mKNGF7q49VM00Pz5FaomJyqvbXpY6PhO+T9w139YEQ==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.32.1", - "@typescript-eslint/type-utils": "8.32.1", - "@typescript-eslint/utils": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.1", + "@typescript-eslint/scope-manager": "8.34.1", + "@typescript-eslint/type-utils": "8.34.1", + "@typescript-eslint/utils": "8.34.1", + "@typescript-eslint/visitor-keys": "8.34.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -3639,7 +3639,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "@typescript-eslint/parser": "^8.34.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } @@ -3654,15 +3654,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.32.1", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-8.32.1.tgz", - "integrity": "sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==", + "version": "8.34.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-8.34.1.tgz", + "integrity": "sha512-4O3idHxhyzjClSMJ0a29AcoK0+YwnEqzI6oz3vlRf3xw0zbzt15MzXwItOlnr5nIth6zlY2RENLsOPvhyrKAQA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.32.1", - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/typescript-estree": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.1", + "@typescript-eslint/scope-manager": "8.34.1", + "@typescript-eslint/types": "8.34.1", + "@typescript-eslint/typescript-estree": "8.34.1", + "@typescript-eslint/visitor-keys": "8.34.1", "debug": "^4.3.4" }, "engines": { @@ -3677,14 +3677,35 @@ "typescript": ">=4.8.4 <5.9.0" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.32.1", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-8.32.1.tgz", - "integrity": "sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==", + "node_modules/@typescript-eslint/project-service": { + "version": "8.34.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/project-service/-/project-service-8.34.1.tgz", + "integrity": "sha512-nuHlOmFZfuRwLJKDGQOVc0xnQrAmuq1Mj/ISou5044y1ajGNp2BNliIqp7F2LPQ5sForz8lempMFCovfeS1XoA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.1" + "@typescript-eslint/tsconfig-utils": "^8.34.1", + "@typescript-eslint/types": "^8.34.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.34.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-8.34.1.tgz", + "integrity": "sha512-beu6o6QY4hJAgL1E8RaXNC071G4Kso2MGmJskCFQhRhg8VOH/FDbC8soP8NHN7e/Hdphwp8G8cE6OBzC8o41ZA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.34.1", + "@typescript-eslint/visitor-keys": "8.34.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3694,14 +3715,30 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.34.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.34.1.tgz", + "integrity": "sha512-K4Sjdo4/xF9NEeA2khOb7Y5nY6NSXBnod87uniVYW9kHP+hNlDV8trUSFeynA2uxWam4gIWgWoygPrv9VMWrYg==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.32.1", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-8.32.1.tgz", - "integrity": "sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==", + "version": "8.34.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-8.34.1.tgz", + "integrity": "sha512-Tv7tCCr6e5m8hP4+xFugcrwTOucB8lshffJ6zf1mF1TbU67R+ntCc6DzLNKM+s/uzDyv8gLq7tufaAhIBYeV8g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "8.32.1", - "@typescript-eslint/utils": "8.32.1", + "@typescript-eslint/typescript-estree": "8.34.1", + "@typescript-eslint/utils": "8.34.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -3718,9 +3755,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.32.1", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/types/-/types-8.32.1.tgz", - "integrity": "sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==", + "version": "8.34.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/types/-/types-8.34.1.tgz", + "integrity": "sha512-rjLVbmE7HR18kDsjNIZQHxmv9RZwlgzavryL5Lnj2ujIRTeXlKtILHgRNmQ3j4daw7zd+mQgy+uyt6Zo6I0IGA==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3731,13 +3768,15 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.32.1", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.1.tgz", - "integrity": "sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==", + "version": "8.34.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.34.1.tgz", + "integrity": "sha512-rjCNqqYPuMUF5ODD+hWBNmOitjBWghkGKJg6hiCHzUvXRy6rK22Jd3rwbP2Xi+R7oYVvIKhokHVhH41BxPV5mA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.1", + "@typescript-eslint/project-service": "8.34.1", + "@typescript-eslint/tsconfig-utils": "8.34.1", + "@typescript-eslint/types": "8.34.1", + "@typescript-eslint/visitor-keys": "8.34.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -3757,15 +3796,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.32.1", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-8.32.1.tgz", - "integrity": "sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==", + "version": "8.34.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-8.34.1.tgz", + "integrity": "sha512-mqOwUdZ3KjtGk7xJJnLbHxTuWVn3GO2WZZuM+Slhkun4+qthLdXx32C8xIXbO1kfCECb3jIs3eoxK3eryk7aoQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.32.1", - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/typescript-estree": "8.32.1" + "@typescript-eslint/scope-manager": "8.34.1", + "@typescript-eslint/types": "8.34.1", + "@typescript-eslint/typescript-estree": "8.34.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3780,13 +3819,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.32.1", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.1.tgz", - "integrity": "sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==", + "version": "8.34.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.34.1.tgz", + "integrity": "sha512-xoh5rJ+tgsRKoXnkBPFRLZ7rjKM0AfVbC68UZ/ECXoDbfggb9RbEySN359acY1vS3qZ0jVTVWzbtfapwm5ztxw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.32.1", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.34.1", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3797,9 +3836,9 @@ } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3809,9 +3848,9 @@ } }, "node_modules/@uiw/codemirror-extensions-basic-setup": { - "version": "4.23.12", - "resolved": "https://registry.npmmirror.com/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.23.12.tgz", - "integrity": "sha512-l9vuiXOTFDBetYrRLDmz3jDxQHDsrVAZ2Y6dVfmrqi2AsulsDu+y7csW0JsvaMqo79rYkaIZg8yeqmDgMb7VyQ==", + "version": "4.23.13", + "resolved": "https://registry.npmmirror.com/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.23.13.tgz", + "integrity": "sha512-U1CnDFpq6ydNqrRDS5Bdnvgso8ezwwbrmKvmAD3hmoVyRDsDU6HTtmcV+w0rZ3kElUCkKI5lY0DMvTTQ4+L3RQ==", "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/commands": "^6.0.0", @@ -3835,20 +3874,20 @@ } }, "node_modules/@uiw/codemirror-theme-vscode": { - "version": "4.23.12", - "resolved": "https://registry.npmmirror.com/@uiw/codemirror-theme-vscode/-/codemirror-theme-vscode-4.23.12.tgz", - "integrity": "sha512-ePBaUQiixrpmSoZJWCGXUStKmcM8G0VBv3UqwPR+kNGBjqDife76Gbhv77izSeEI3zRPzL+683BOdclkvWnsMg==", + "version": "4.23.13", + "resolved": "https://registry.npmmirror.com/@uiw/codemirror-theme-vscode/-/codemirror-theme-vscode-4.23.13.tgz", + "integrity": "sha512-Fn79r3NBMPP/hF9ui1e8VCyEjVbZ+rW2MIIGgq/LOkLXZSDXEZRa6NhRt991IuZ6e0R8bprrx3TGVQnkVfODbQ==", "dependencies": { - "@uiw/codemirror-themes": "4.23.12" + "@uiw/codemirror-themes": "4.23.13" }, "funding": { "url": "https://jaywcjlove.github.io/#/sponsor" } }, "node_modules/@uiw/codemirror-themes": { - "version": "4.23.12", - "resolved": "https://registry.npmmirror.com/@uiw/codemirror-themes/-/codemirror-themes-4.23.12.tgz", - "integrity": "sha512-8etEByfS9yttFZW0rcWhdZc7/JXJKRWlU5lHmJCI3GydZNGCzydNA+HtK9nWKpJUndVc58Q2sqSC5OIcwq8y6A==", + "version": "4.23.13", + "resolved": "https://registry.npmmirror.com/@uiw/codemirror-themes/-/codemirror-themes-4.23.13.tgz", + "integrity": "sha512-thk4X8VNl15XPoDiOXdkeMAIIHQOoc5lPfmgOvrhPXHzt4zvH5efLWBw3zgpwuOWF+Uk6sYrS0eumtsSO/kgcA==", "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", @@ -3864,15 +3903,15 @@ } }, "node_modules/@uiw/react-codemirror": { - "version": "4.23.12", - "resolved": "https://registry.npmmirror.com/@uiw/react-codemirror/-/react-codemirror-4.23.12.tgz", - "integrity": "sha512-yseqWdzoAAGAW7i/NiU8YrfSLVOEBjQvSx1KpDTFVV/nn0AlAZoDVTIPEBgdXrPlVUQoCrwgpEaj3uZCklk9QA==", + "version": "4.23.13", + "resolved": "https://registry.npmmirror.com/@uiw/react-codemirror/-/react-codemirror-4.23.13.tgz", + "integrity": "sha512-y65ULzxOAfpxrA/8epoAOeCfmJXu9z0P62BbGOkITJTtU7WI59KfPbbwj35npSsMAkAmDE841qZo2I8jst/THg==", "dependencies": { "@babel/runtime": "^7.18.6", "@codemirror/commands": "^6.1.0", "@codemirror/state": "^6.1.1", "@codemirror/theme-one-dark": "^6.0.0", - "@uiw/codemirror-extensions-basic-setup": "4.23.12", + "@uiw/codemirror-extensions-basic-setup": "4.23.13", "codemirror": "^6.0.0" }, "funding": { @@ -3934,15 +3973,15 @@ } }, "node_modules/@vitejs/plugin-react": { - "version": "4.5.0", - "resolved": "https://registry.npmmirror.com/@vitejs/plugin-react/-/plugin-react-4.5.0.tgz", - "integrity": "sha512-JuLWaEqypaJmOJPLWwO335Ig6jSgC1FTONCWAxnqcQthLTK/Yc9aH6hr9z/87xciejbQcnP3GnA1FWUSWeXaeg==", + "version": "4.6.0", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-react/-/plugin-react-4.6.0.tgz", + "integrity": "sha512-5Kgff+m8e2PB+9j51eGHEpn5kUzRKH2Ry0qGoe8ItJg7pqnkPrYPkDQZGgGmTa0EGarHrkjLvOdU3b1fzI8otQ==", "dev": true, "dependencies": { - "@babel/core": "^7.26.10", - "@babel/plugin-transform-react-jsx-self": "^7.25.9", - "@babel/plugin-transform-react-jsx-source": "^7.25.9", - "@rolldown/pluginutils": "1.0.0-beta.9", + "@babel/core": "^7.27.4", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.19", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, @@ -3950,7 +3989,7 @@ "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" } }, "node_modules/acorn": { @@ -4030,9 +4069,9 @@ } }, "node_modules/antd": { - "version": "5.25.3", - "resolved": "https://registry.npmmirror.com/antd/-/antd-5.25.3.tgz", - "integrity": "sha512-tBBcAFRjmWM3sitxrL/FEbQL+MTQntYY5bGa5c1ZZZHXWCynkhS3Ch/gy25mGMUY1M/9Uw3pH029v/RGht1x3w==", + "version": "5.26.1", + "resolved": "https://registry.npmmirror.com/antd/-/antd-5.26.1.tgz", + "integrity": "sha512-CiLGZ2Ftld+fuoj+U3OL8uouuqUppqFJnW4O/4bOgSWzM9XsJGibpNtUa9QArhrZ5ndfnzlPP/4RVXUK/xfSvQ==", "dependencies": { "@ant-design/colors": "^7.2.1", "@ant-design/cssinjs": "^1.23.0", @@ -4053,7 +4092,7 @@ "rc-checkbox": "~3.5.0", "rc-collapse": "~3.9.0", "rc-dialog": "~9.6.0", - "rc-drawer": "~7.2.0", + "rc-drawer": "~7.3.0", "rc-dropdown": "~4.2.1", "rc-field-form": "~2.7.0", "rc-image": "~7.12.0", @@ -4073,13 +4112,13 @@ "rc-slider": "~11.1.8", "rc-steps": "~6.0.1", "rc-switch": "~4.1.0", - "rc-table": "~7.50.5", + "rc-table": "~7.51.0", "rc-tabs": "~15.6.1", "rc-textarea": "~1.10.0", "rc-tooltip": "~6.4.0", "rc-tree": "~5.13.1", "rc-tree-select": "~5.27.0", - "rc-upload": "~4.9.0", + "rc-upload": "~4.9.2", "rc-util": "^5.44.4", "scroll-into-view-if-needed": "^3.1.0", "throttle-debounce": "^5.0.2" @@ -4094,15 +4133,15 @@ } }, "node_modules/antd-zod": { - "version": "6.1.0", - "resolved": "https://registry.npmmirror.com/antd-zod/-/antd-zod-6.1.0.tgz", - "integrity": "sha512-7gXf5NgZO9MRrn54dQVmSDujGuY9YgV6jmE4sOKw4MuFu+YgYPrk0oAEiRTZ9DveCyyZ1krurOwsXJJGuDJ3IQ==", + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/antd-zod/-/antd-zod-7.0.0.tgz", + "integrity": "sha512-1hsEiBC0WbbAJ6Z1W3lRQgaS1oGsxj9UX9eZ9jWpXh8A35OvHNovLRd/1BojrYfGvZaOX/zEJbl3X+9VgqnIcQ==", "dependencies": { "lodash.merge": "^4.6.2" }, "peerDependencies": { "antd": "^5.20.5", - "zod": ">=3.0.0" + "zod": ">=3.25.0" } }, "node_modules/antd/node_modules/@ant-design/icons": { @@ -4172,17 +4211,19 @@ } }, "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmmirror.com/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "version": "3.1.9", + "resolved": "https://registry.npmmirror.com/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -4192,17 +4233,18 @@ } }, "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmmirror.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "version": "1.2.6", + "resolved": "https://registry.npmmirror.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", + "es-abstract": "^1.23.9", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -4483,9 +4525,9 @@ } }, "node_modules/call-bind-apply-helpers": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", - "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "dev": true, "dependencies": { "es-errors": "^1.3.0", @@ -4496,13 +4538,13 @@ } }, "node_modules/call-bound": { - "version": "1.0.3", - "resolved": "https://registry.npmmirror.com/call-bound/-/call-bound-1.0.3.tgz", - "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "get-intrinsic": "^1.2.6" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -4684,9 +4726,9 @@ "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" }, "node_modules/cron-parser": { - "version": "5.2.0", - "resolved": "https://registry.npmmirror.com/cron-parser/-/cron-parser-5.2.0.tgz", - "integrity": "sha512-ED2qJtcjelmUEuoV3btwxiOm3NI8H4/eCZNX3adUkrm+/b3Xq05+YoDXyjIN57VGhskuHx/KzC367GAklo1lRg==", + "version": "5.3.0", + "resolved": "https://registry.npmmirror.com/cron-parser/-/cron-parser-5.3.0.tgz", + "integrity": "sha512-IS4mnFu6n3CFgEmXjr+B2zzGHsjJmHEdN+BViKvYSiEn3KWss9ICRDETDX/VZldiW82B94OyAZm4LIT4vcKK0g==", "dependencies": { "luxon": "^3.6.1" }, @@ -4916,26 +4958,27 @@ } }, "node_modules/es-abstract": { - "version": "1.23.8", - "resolved": "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.23.8.tgz", - "integrity": "sha512-lfab8IzDn6EpI1ibZakcgS6WsfEBiB+43cuJo+wgylx1xKXf+Sp+YR3vFuQwC/u3sxYwV8Cxe3B0DpVUu/WiJQ==", + "version": "1.24.0", + "resolved": "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", - "call-bound": "^1.0.3", + "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.2.6", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", @@ -4947,20 +4990,24 @@ "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", + "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", - "is-weakref": "^1.1.0", + "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", - "object-inspect": "^1.13.3", + "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", - "own-keys": "^1.0.0", - "regexp.prototype.flags": "^1.5.3", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", @@ -4969,7 +5016,7 @@ "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", - "which-typed-array": "^1.1.18" + "which-typed-array": "^1.1.19" }, "engines": { "node": ">= 0.4" @@ -4997,9 +5044,9 @@ } }, "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, "dependencies": { "es-errors": "^1.3.0" @@ -5009,26 +5056,30 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.4", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmmirror.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", "dev": true, "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/es-to-primitive": { @@ -5222,9 +5273,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.12.0", - "resolved": "https://registry.npmmirror.com/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", - "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "version": "2.12.1", + "resolved": "https://registry.npmmirror.com/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", "dev": true, "dependencies": { "debug": "^3.2.7" @@ -5248,29 +5299,29 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.31.0", - "resolved": "https://registry.npmmirror.com/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", - "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "version": "2.32.0", + "resolved": "https://registry.npmmirror.com/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "dependencies": { "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.8", - "array.prototype.findlastindex": "^1.2.5", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.0", + "eslint-module-utils": "^2.12.1", "hasown": "^2.0.2", - "is-core-module": "^2.15.1", + "is-core-module": "^2.16.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "object.groupby": "^1.0.3", - "object.values": "^1.2.0", + "object.values": "^1.2.1", "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.8", + "string.prototype.trimend": "^1.0.9", "tsconfig-paths": "^3.15.0" }, "engines": { @@ -5333,13 +5384,13 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "5.4.0", - "resolved": "https://registry.npmmirror.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.4.0.tgz", - "integrity": "sha512-BvQOvUhkVQM1i63iMETK9Hjud9QhqBnbtT1Zc642p9ynzBuCe5pybkOnvqZIBypXmMlsGcnU4HZ8sCTPfpAexA==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.0.tgz", + "integrity": "sha512-8qsOYwkkGrahrgoUv76NZi23koqXOGiiEzXMrT8Q7VcYaUISR+5MorIUxfWqYXN0fN/31WbSrxCxFkVQ43wwrA==", "dev": true, "dependencies": { "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.11.0" + "synckit": "^0.11.7" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -5732,12 +5783,18 @@ "dev": true }, "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmmirror.com/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "version": "0.3.5", + "resolved": "https://registry.npmmirror.com/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, "dependencies": { - "is-callable": "^1.1.3" + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/foreground-child": { @@ -5851,21 +5908,21 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.6", - "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.6.tgz", - "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "dunder-proto": "^1.0.0", + "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "math-intrinsics": "^1.0.0" + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -5874,6 +5931,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-symbol-description": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/get-symbol-description/-/get-symbol-description-1.1.0.tgz", @@ -6124,9 +6194,9 @@ } }, "node_modules/i18next-browser-languagedetector": { - "version": "8.1.0", - "resolved": "https://registry.npmmirror.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.1.0.tgz", - "integrity": "sha512-mHZxNx1Lq09xt5kCauZ/4bsXOEA2pfpwSoU11/QTJB+pD94iONFwp+ohqi///PwiFvjFOxe1akYCdHyFo1ng5Q==", + "version": "8.2.0", + "resolved": "https://registry.npmmirror.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.0.tgz", + "integrity": "sha512-P+3zEKLnOF0qmiesW383vsLdtQVyKtCNA9cjSoKCppTKPQVfKd2W8hbVo5ZhNJKDqeM7BOcvNoKJOjpHh4Js9g==", "dependencies": { "@babel/runtime": "^7.23.2" } @@ -6426,6 +6496,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz", @@ -6566,12 +6648,12 @@ } }, "node_modules/is-weakref": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/is-weakref/-/is-weakref-1.1.0.tgz", - "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==", + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", "dev": true, "dependencies": { - "call-bound": "^1.0.2" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -6810,9 +6892,9 @@ } }, "node_modules/lucide-react": { - "version": "0.511.0", - "resolved": "https://registry.npmmirror.com/lucide-react/-/lucide-react-0.511.0.tgz", - "integrity": "sha512-VK5a2ydJ7xm8GvBeKLS9mu1pVK6ucef9780JVUjw6bAjJL/QXnd4Y0p7SPeOUMC27YhzNCZvm5d/QX0Tp3rc0w==", + "version": "0.522.0", + "resolved": "https://registry.npmmirror.com/lucide-react/-/lucide-react-0.522.0.tgz", + "integrity": "sha512-jnJbw974yZ7rQHHEFKJOlWAefG3ATSCZHANZxIdx8Rk/16siuwjgA4fBULpXEAWx/RlTs3FzmKW/udWUuO0aRw==", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } @@ -6992,9 +7074,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.3", - "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.3.tgz", - "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "version": "1.13.4", + "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, "engines": { "node": ">= 0.4" @@ -7273,9 +7355,9 @@ } }, "node_modules/pocketbase": { - "version": "0.26.0", - "resolved": "https://registry.npmmirror.com/pocketbase/-/pocketbase-0.26.0.tgz", - "integrity": "sha512-WBBeOgz4Jnrd7a1KEzSBUJqpTortKKCcp16j5KoF+4tNIyQHsmynj+qRSvS56/RVacVMbAqO8Qkfj3N84fpzEw==" + "version": "0.26.1", + "resolved": "https://registry.npmmirror.com/pocketbase/-/pocketbase-0.26.1.tgz", + "integrity": "sha512-fjcPDpxyqTZCwqGUTPUV7vssIsNMqHxk9GxbhxYHPEf18RqX2d9cpSqbbHk7aas30jqkgptuKfG7aY/Mytjj3g==" }, "node_modules/possible-typed-array-names": { "version": "1.0.0", @@ -7287,9 +7369,9 @@ } }, "node_modules/postcss": { - "version": "8.5.3", - "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.3.tgz", - "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "version": "8.5.6", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ { @@ -7306,7 +7388,7 @@ } ], "dependencies": { - "nanoid": "^3.3.8", + "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -7430,9 +7512,9 @@ "dev": true }, "node_modules/postcss/node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "version": "3.3.11", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { @@ -7457,9 +7539,9 @@ } }, "node_modules/prettier": { - "version": "3.5.3", - "resolved": "https://registry.npmmirror.com/prettier/-/prettier-3.5.3.tgz", - "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/prettier/-/prettier-3.6.0.tgz", + "integrity": "sha512-ujSB9uXHJKzM/2GBuE0hBOUgC77CN3Bnpqa+g80bkv3T3A93wL/xlzDATHhnhkzifz/UE2SNOvmbTz5hSkDlHw==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -7528,9 +7610,9 @@ ] }, "node_modules/radash": { - "version": "12.1.0", - "resolved": "https://registry.npmmirror.com/radash/-/radash-12.1.0.tgz", - "integrity": "sha512-b0Zcf09AhqKS83btmUeYBS8tFK7XL2e3RvLmZcm0sTdF1/UUlHSsjXdCcWNxe7yfmAlPve5ym0DmKGtTzP6kVQ==", + "version": "12.1.1", + "resolved": "https://registry.npmmirror.com/radash/-/radash-12.1.1.tgz", + "integrity": "sha512-h36JMxKRqrAxVD8201FrCpyeNuUY9Y5zZwujr20fFO77tpUtGa6EZzfKw/3WaiBX95fq7+MpsuMLNdSnORAwSA==", "engines": { "node": ">=14.18.0" } @@ -7597,9 +7679,9 @@ } }, "node_modules/rc-drawer": { - "version": "7.2.0", - "resolved": "https://registry.npmmirror.com/rc-drawer/-/rc-drawer-7.2.0.tgz", - "integrity": "sha512-9lOQ7kBekEJRdEpScHvtmEtXnAsy+NGDXiRWc2ZVC7QXAazNVbeT4EraQKYwCME8BJLa8Bxqxvs5swwyOepRwg==", + "version": "7.3.0", + "resolved": "https://registry.npmmirror.com/rc-drawer/-/rc-drawer-7.3.0.tgz", + "integrity": "sha512-DX6CIgiBWNpJIMGFO8BAISFkxiuKitoizooj4BDyee8/SnBn0zwO2FHrNDpqqepj0E/TFTDpmEBCyFuTgC7MOg==", "dependencies": { "@babel/runtime": "^7.23.9", "@rc-component/portal": "^1.1.1", @@ -7956,9 +8038,9 @@ } }, "node_modules/rc-table": { - "version": "7.50.5", - "resolved": "https://registry.npmmirror.com/rc-table/-/rc-table-7.50.5.tgz", - "integrity": "sha512-FDZu8aolhSYd3v9KOc3lZOVAU77wmRRu44R0Wfb8Oj1dXRUsloFaXMSl6f7yuWZUxArJTli7k8TEOX2mvhDl4A==", + "version": "7.51.1", + "resolved": "https://registry.npmmirror.com/rc-table/-/rc-table-7.51.1.tgz", + "integrity": "sha512-5iq15mTHhvC42TlBLRCoCBLoCmGlbRZAlyF21FonFnS/DIC8DeRqnmdyVREwt2CFbPceM0zSNdEeVfiGaqYsKw==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/context": "^1.4.0", @@ -8063,9 +8145,9 @@ } }, "node_modules/rc-upload": { - "version": "4.9.0", - "resolved": "https://registry.npmmirror.com/rc-upload/-/rc-upload-4.9.0.tgz", - "integrity": "sha512-pAzlPnyiFn1GCtEybEG2m9nXNzQyWXqWV2xFYCmDxjN9HzyjS5Pz2F+pbNdYw8mMJsixLEKLG0wVy9vOGxJMJA==", + "version": "4.9.2", + "resolved": "https://registry.npmmirror.com/rc-upload/-/rc-upload-4.9.2.tgz", + "integrity": "sha512-nHx+9rbd1FKMiMRYsqQ3NkXUv7COHPBo3X1Obwq9SWS6/diF/A0aJ5OHubvwUAIDs+4RMleljV0pcrNUc823GQ==", "dependencies": { "@babel/runtime": "^7.18.3", "classnames": "^2.2.5", @@ -8148,11 +8230,11 @@ "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" }, "node_modules/react-i18next": { - "version": "15.5.2", - "resolved": "https://registry.npmmirror.com/react-i18next/-/react-i18next-15.5.2.tgz", - "integrity": "sha512-ePODyXgmZQAOYTbZXQn5rRsSBu3Gszo69jxW6aKmlSgxKAI1fOhDwSu6bT4EKHciWPKQ7v7lPrjeiadR6Gi+1A==", + "version": "15.5.3", + "resolved": "https://registry.npmmirror.com/react-i18next/-/react-i18next-15.5.3.tgz", + "integrity": "sha512-ypYmOKOnjqPEJZO4m1BI0kS8kWqkBNsKYyhVUfij0gvjy9xJNoG/VcGkxq5dRlVwzmrmY1BQMAmpbbUBLwC4Kw==", "dependencies": { - "@babel/runtime": "^7.25.0", + "@babel/runtime": "^7.27.6", "html-parse-stringify": "^3.0.1" }, "peerDependencies": { @@ -8192,9 +8274,9 @@ } }, "node_modules/react-router": { - "version": "7.6.1", - "resolved": "https://registry.npmmirror.com/react-router/-/react-router-7.6.1.tgz", - "integrity": "sha512-hPJXXxHJZEsPFNVbtATH7+MMX43UDeOauz+EAU4cgqTn7ojdI9qQORqS8Z0qmDlL1TclO/6jLRYUEtbWidtdHQ==", + "version": "7.6.2", + "resolved": "https://registry.npmmirror.com/react-router/-/react-router-7.6.2.tgz", + "integrity": "sha512-U7Nv3y+bMimgWjhlT5CRdzHPu2/KVmqPwKUCChW8en5P3znxUqwlYFlbmyj8Rgp1SF6zs5X4+77kBVknkg6a0w==", "dependencies": { "cookie": "^1.0.1", "set-cookie-parser": "^2.6.0" @@ -8213,11 +8295,11 @@ } }, "node_modules/react-router-dom": { - "version": "7.6.1", - "resolved": "https://registry.npmmirror.com/react-router-dom/-/react-router-dom-7.6.1.tgz", - "integrity": "sha512-vxU7ei//UfPYQ3iZvHuO1D/5fX3/JOqhNTbRR+WjSBWxf9bIvpWK+ftjmdfJHzPOuMQKe2fiEdG+dZX6E8uUpA==", + "version": "7.6.2", + "resolved": "https://registry.npmmirror.com/react-router-dom/-/react-router-dom-7.6.2.tgz", + "integrity": "sha512-Q8zb6VlTbdYKK5JJBLQEN06oTUa/RAbG/oQS1auK1I0TbJOXktqm+QENEVJU6QvWynlXPRBXI3fiOQcSEA78rA==", "dependencies": { - "react-router": "7.6.1" + "react-router": "7.6.2" }, "engines": { "node": ">=20.0.0" @@ -8312,14 +8394,16 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.3", - "resolved": "https://registry.npmmirror.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", - "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", + "version": "1.5.4", + "resolved": "https://registry.npmmirror.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", "set-function-name": "^2.0.2" }, "engines": { @@ -8652,6 +8736,20 @@ "node": ">= 0.4" } }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/shallowequal/-/shallowequal-1.1.0.tgz", @@ -8798,6 +8896,19 @@ "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", "dev": true }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/string-convert": { "version": "0.2.1", "resolved": "https://registry.npmmirror.com/string-convert/-/string-convert-0.2.1.tgz", @@ -9047,13 +9158,12 @@ } }, "node_modules/synckit": { - "version": "0.11.4", - "resolved": "https://registry.npmmirror.com/synckit/-/synckit-0.11.4.tgz", - "integrity": "sha512-Q/XQKRaJiLiFIBNN+mndW7S/RHxvwzuZS6ZwmRzUBqJBv/5QIKCEwkBC8GBf8EQJKYnaFs0wOZbKTXBPj8L9oQ==", + "version": "0.11.8", + "resolved": "https://registry.npmmirror.com/synckit/-/synckit-0.11.8.tgz", + "integrity": "sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==", "dev": true, "dependencies": { - "@pkgr/core": "^0.2.3", - "tslib": "^2.8.1" + "@pkgr/core": "^0.2.4" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -9748,15 +9858,16 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.18", - "resolved": "https://registry.npmmirror.com/which-typed-array/-/which-typed-array-1.1.18.tgz", - "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", + "version": "1.1.19", + "resolved": "https://registry.npmmirror.com/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "for-each": "^0.3.3", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, @@ -9940,9 +10051,9 @@ } }, "node_modules/zod": { - "version": "3.25.28", - "resolved": "https://registry.npmmirror.com/zod/-/zod-3.25.28.tgz", - "integrity": "sha512-/nt/67WYKnr5by3YS7LroZJbtcCBurDKKPBPWWzaxvVCGuG/NOsiKkrjoOhI8mJ+SQUXEbUzeB3S+6XDUEEj7Q==", + "version": "3.25.67", + "resolved": "https://registry.npmmirror.com/zod/-/zod-3.25.67.tgz", + "integrity": "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==", "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/ui/package.json b/ui/package.json index b8383a99..019cb430 100644 --- a/ui/package.json +++ b/ui/package.json @@ -11,34 +11,34 @@ }, "dependencies": { "@ant-design/icons": "^6.0.0", - "@ant-design/pro-components": "^2.8.7", - "@codemirror/lang-json": "^6.0.1", + "@ant-design/pro-components": "^2.8.9", + "@codemirror/lang-json": "^6.0.2", "@codemirror/lang-yaml": "^6.1.2", - "@codemirror/language": "^6.11.0", + "@codemirror/language": "^6.11.1", "@codemirror/legacy-modes": "^6.5.1", - "@uiw/codemirror-extensions-basic-setup": "^4.23.12", - "@uiw/codemirror-theme-vscode": "^4.23.12", - "@uiw/react-codemirror": "^4.23.12", + "@uiw/codemirror-extensions-basic-setup": "^4.23.13", + "@uiw/codemirror-theme-vscode": "^4.23.13", + "@uiw/react-codemirror": "^4.23.13", "ahooks": "^3.8.5", - "antd": "^5.25.3", - "antd-zod": "^6.1.0", + "antd": "^5.26.1", + "antd-zod": "^7.0.0", "clsx": "^2.1.1", - "cron-parser": "^5.2.0", + "cron-parser": "^5.3.0", "file-saver": "^2.0.5", "i18next": "^25.2.1", - "i18next-browser-languagedetector": "^8.1.0", + "i18next-browser-languagedetector": "^8.2.0", "immer": "^10.1.1", - "lucide-react": "^0.511.0", + "lucide-react": "^0.522.0", "nanoid": "^5.1.5", - "pocketbase": "^0.26.0", - "radash": "^12.1.0", + "pocketbase": "^0.26.1", + "radash": "^12.1.1", "react": "^18.3.1", "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.3.1", - "react-i18next": "^15.5.2", - "react-router-dom": "^7.6.1", + "react-i18next": "^15.5.3", + "react-router-dom": "^7.6.2", "tailwind-merge": "^2.6.0", - "zod": "^3.25.28", + "zod": "^3.25.67", "zustand": "^5.0.5" }, "devDependencies": { @@ -48,22 +48,22 @@ "@types/react": "^18.3.12", "@types/react-copy-to-clipboard": "^5.0.7", "@types/react-dom": "^18.3.1", - "@typescript-eslint/eslint-plugin": "^8.32.1", - "@typescript-eslint/parser": "^8.32.1", + "@typescript-eslint/eslint-plugin": "^8.34.1", + "@typescript-eslint/parser": "^8.34.1", "@vitejs/plugin-legacy": "^6.1.1", - "@vitejs/plugin-react": "^4.5.0", + "@vitejs/plugin-react": "^4.6.0", "autoprefixer": "^10.4.21", "eslint": "^8.57.0", "eslint-config-prettier": "^10.1.5", "eslint-import-resolver-typescript": "^3.8.3", - "eslint-plugin-import": "^2.31.0", - "eslint-plugin-prettier": "^5.4.0", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-prettier": "^5.5.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", "eslint-plugin-tailwindcss": "^3.18.0", "fs-extra": "^11.3.0", - "postcss": "^8.5.3", - "prettier": "^3.5.3", + "postcss": "^8.5.6", + "prettier": "^3.6.0", "tailwindcss": "^3.4.17", "tailwindcss-animate": "^1.0.7", "typescript": "^5.8.3", diff --git a/ui/src/components/access/AccessForm.tsx b/ui/src/components/access/AccessForm.tsx index 2d8bee1b..09553347 100644 --- a/ui/src/components/access/AccessForm.tsx +++ b/ui/src/components/access/AccessForm.tsx @@ -2,7 +2,7 @@ import { forwardRef, useImperativeHandle, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import AccessProviderPicker from "@/components/provider/AccessProviderPicker"; import AccessProviderSelect from "@/components/provider/AccessProviderSelect"; @@ -108,7 +108,7 @@ const AccessForm = forwardRef(({ className, const formSchema = z.object({ name: z - .string({ message: t("access.form.name.placeholder") }) + .string(t("access.form.name.placeholder")) .min(1, t("access.form.name.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), provider: z.nativeEnum(ACCESS_PROVIDERS, { diff --git a/ui/src/components/access/AccessForm1PanelConfig.tsx b/ui/src/components/access/AccessForm1PanelConfig.tsx index 3af64e98..03086bf6 100644 --- a/ui/src/components/access/AccessForm1PanelConfig.tsx +++ b/ui/src/components/access/AccessForm1PanelConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigFor1Panel } from "@/domain/access"; @@ -27,7 +27,7 @@ const AccessForm1PanelConfig = ({ form: formInst, formName, disabled, initialVal const { t } = useTranslation(); const formSchema = z.object({ - serverUrl: z.string().url(t("common.errmsg.url_invalid")), + serverUrl: z.url(t("common.errmsg.url_invalid")), apiVersion: z.string().nonempty(t("access.form.1panel_api_version.placeholder")), apiKey: z .string() diff --git a/ui/src/components/access/AccessFormACMECAConfig.tsx b/ui/src/components/access/AccessFormACMECAConfig.tsx index fbba1c73..34765a36 100644 --- a/ui/src/components/access/AccessFormACMECAConfig.tsx +++ b/ui/src/components/access/AccessFormACMECAConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForACMECA } from "@/domain/access"; @@ -25,7 +25,7 @@ const AccessFormACMECAConfig = ({ form: formInst, formName, disabled, initialVal const { t } = useTranslation(); const formSchema = z.object({ - endpoint: z.string().url(t("common.errmsg.url_invalid")), + endpoint: z.url(t("common.errmsg.url_invalid")), eabKid: z.string().nullish(), eabHmacKey: z.string().nullish(), }); diff --git a/ui/src/components/access/AccessFormACMEHttpReqConfig.tsx b/ui/src/components/access/AccessFormACMEHttpReqConfig.tsx index 6cdd8e3c..86f9cf2c 100644 --- a/ui/src/components/access/AccessFormACMEHttpReqConfig.tsx +++ b/ui/src/components/access/AccessFormACMEHttpReqConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForACMEHttpReq } from "@/domain/access"; @@ -26,7 +26,7 @@ const AccessFormACMEHttpReqConfig = ({ form: formInst, formName, disabled, initi const { t } = useTranslation(); const formSchema = z.object({ - endpoint: z.string().url(t("common.errmsg.url_invalid")), + endpoint: z.url(t("common.errmsg.url_invalid")), mode: z.string().nullish(), username: z .string() diff --git a/ui/src/components/access/AccessFormAPISIXConfig.tsx b/ui/src/components/access/AccessFormAPISIXConfig.tsx index 71de8521..f3fcca60 100644 --- a/ui/src/components/access/AccessFormAPISIXConfig.tsx +++ b/ui/src/components/access/AccessFormAPISIXConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForAPISIX } from "@/domain/access"; @@ -26,7 +26,7 @@ const AccessFormAPISIXConfig = ({ form: formInst, formName, disabled, initialVal const { t } = useTranslation(); const formSchema = z.object({ - serverUrl: z.string().url(t("common.errmsg.url_invalid")), + serverUrl: z.url(t("common.errmsg.url_invalid")), apiKey: z.string().nonempty(t("access.form.apisix_api_key.placeholder")), allowInsecureConnections: z.boolean().nullish(), }); diff --git a/ui/src/components/access/AccessFormAWSConfig.tsx b/ui/src/components/access/AccessFormAWSConfig.tsx index 89500feb..b60d64fb 100644 --- a/ui/src/components/access/AccessFormAWSConfig.tsx +++ b/ui/src/components/access/AccessFormAWSConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForAWS } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormAliyunConfig.tsx b/ui/src/components/access/AccessFormAliyunConfig.tsx index f48c3297..882d2621 100644 --- a/ui/src/components/access/AccessFormAliyunConfig.tsx +++ b/ui/src/components/access/AccessFormAliyunConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForAliyun } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormAzureConfig.tsx b/ui/src/components/access/AccessFormAzureConfig.tsx index 48be8aa5..faf3a6dc 100644 --- a/ui/src/components/access/AccessFormAzureConfig.tsx +++ b/ui/src/components/access/AccessFormAzureConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { AutoComplete, Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForAzure } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormBaiduCloudConfig.tsx b/ui/src/components/access/AccessFormBaiduCloudConfig.tsx index ab7abffc..4e4cbc09 100644 --- a/ui/src/components/access/AccessFormBaiduCloudConfig.tsx +++ b/ui/src/components/access/AccessFormBaiduCloudConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForBaiduCloud } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormBaishanConfig.tsx b/ui/src/components/access/AccessFormBaishanConfig.tsx index ab17c62b..1be47e5e 100644 --- a/ui/src/components/access/AccessFormBaishanConfig.tsx +++ b/ui/src/components/access/AccessFormBaishanConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForBaishan } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormBaotaPanelConfig.tsx b/ui/src/components/access/AccessFormBaotaPanelConfig.tsx index 6acbc62c..a5633c29 100644 --- a/ui/src/components/access/AccessFormBaotaPanelConfig.tsx +++ b/ui/src/components/access/AccessFormBaotaPanelConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForBaotaPanel } from "@/domain/access"; @@ -26,7 +26,7 @@ const AccessFormBaotaPanelConfig = ({ form: formInst, formName, disabled, initia const { t } = useTranslation(); const formSchema = z.object({ - serverUrl: z.string().url(t("common.errmsg.url_invalid")), + serverUrl: z.url(t("common.errmsg.url_invalid")), apiKey: z.string().nonempty(t("access.form.baotapanel_api_key.placeholder")), allowInsecureConnections: z.boolean().nullish(), }); diff --git a/ui/src/components/access/AccessFormBaotaWAFConfig.tsx b/ui/src/components/access/AccessFormBaotaWAFConfig.tsx index 13e4a2c2..f4894088 100644 --- a/ui/src/components/access/AccessFormBaotaWAFConfig.tsx +++ b/ui/src/components/access/AccessFormBaotaWAFConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForBaotaWAF } from "@/domain/access"; @@ -26,7 +26,7 @@ const AccessFormBaotaWAFConfig = ({ form: formInst, formName, disabled, initialV const { t } = useTranslation(); const formSchema = z.object({ - serverUrl: z.string().url(t("common.errmsg.url_invalid")), + serverUrl: z.url(t("common.errmsg.url_invalid")), apiKey: z.string().nonempty(t("access.form.baotawaf_api_key.placeholder")), allowInsecureConnections: z.boolean().nullish(), }); diff --git a/ui/src/components/access/AccessFormBunnyConfig.tsx b/ui/src/components/access/AccessFormBunnyConfig.tsx index 8ea052f7..fecb1b52 100644 --- a/ui/src/components/access/AccessFormBunnyConfig.tsx +++ b/ui/src/components/access/AccessFormBunnyConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForBunny } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormBytePlusConfig.tsx b/ui/src/components/access/AccessFormBytePlusConfig.tsx index 5902edb8..1108ad41 100644 --- a/ui/src/components/access/AccessFormBytePlusConfig.tsx +++ b/ui/src/components/access/AccessFormBytePlusConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForBytePlus } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormCMCCCloudConfig.tsx b/ui/src/components/access/AccessFormCMCCCloudConfig.tsx index 9ee88a07..da32fc43 100644 --- a/ui/src/components/access/AccessFormCMCCCloudConfig.tsx +++ b/ui/src/components/access/AccessFormCMCCCloudConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForCMCCCloud } from "@/domain/access"; type AccessFormCMCCCloudConfigFieldValues = Nullish; diff --git a/ui/src/components/access/AccessFormCTCCCloudConfig.tsx b/ui/src/components/access/AccessFormCTCCCloudConfig.tsx index f0e9df39..3ef4b7cb 100644 --- a/ui/src/components/access/AccessFormCTCCCloudConfig.tsx +++ b/ui/src/components/access/AccessFormCTCCCloudConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForCTCCCloud } from "@/domain/access"; type AccessFormCTCCCloudConfigFieldValues = Nullish; diff --git a/ui/src/components/access/AccessFormCacheFlyConfig.tsx b/ui/src/components/access/AccessFormCacheFlyConfig.tsx index 79ca197f..4d5d4862 100644 --- a/ui/src/components/access/AccessFormCacheFlyConfig.tsx +++ b/ui/src/components/access/AccessFormCacheFlyConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForCacheFly } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormCdnflyConfig.tsx b/ui/src/components/access/AccessFormCdnflyConfig.tsx index 6e06d0e7..37bee25e 100644 --- a/ui/src/components/access/AccessFormCdnflyConfig.tsx +++ b/ui/src/components/access/AccessFormCdnflyConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForCdnfly } from "@/domain/access"; @@ -27,7 +27,7 @@ const AccessFormCdnflyConfig = ({ form: formInst, formName, disabled, initialVal const { t } = useTranslation(); const formSchema = z.object({ - serverUrl: z.string().url(t("common.errmsg.url_invalid")), + serverUrl: z.url(t("common.errmsg.url_invalid")), apiKey: z .string() .min(1, t("access.form.cdnfly_api_key.placeholder")) diff --git a/ui/src/components/access/AccessFormClouDNSConfig.tsx b/ui/src/components/access/AccessFormClouDNSConfig.tsx index 922a8e75..dd729513 100644 --- a/ui/src/components/access/AccessFormClouDNSConfig.tsx +++ b/ui/src/components/access/AccessFormClouDNSConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForClouDNS } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormCloudflareConfig.tsx b/ui/src/components/access/AccessFormCloudflareConfig.tsx index 6e9ba6c1..c67c0c34 100644 --- a/ui/src/components/access/AccessFormCloudflareConfig.tsx +++ b/ui/src/components/access/AccessFormCloudflareConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForCloudflare } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormConstellixConfig.tsx b/ui/src/components/access/AccessFormConstellixConfig.tsx index 8e028034..406f2d96 100644 --- a/ui/src/components/access/AccessFormConstellixConfig.tsx +++ b/ui/src/components/access/AccessFormConstellixConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForConstellix } from "@/domain/access"; type AccessFormConstellixConfigFieldValues = Nullish; diff --git a/ui/src/components/access/AccessFormDNSLAConfig.tsx b/ui/src/components/access/AccessFormDNSLAConfig.tsx index ee5ac5e6..06b8fe41 100644 --- a/ui/src/components/access/AccessFormDNSLAConfig.tsx +++ b/ui/src/components/access/AccessFormDNSLAConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForDNSLA } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormDeSECConfig.tsx b/ui/src/components/access/AccessFormDeSECConfig.tsx index 10f5a101..5c570850 100644 --- a/ui/src/components/access/AccessFormDeSECConfig.tsx +++ b/ui/src/components/access/AccessFormDeSECConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForDeSEC } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormDigitalOceanConfig.tsx b/ui/src/components/access/AccessFormDigitalOceanConfig.tsx index 421ee9cc..c0d85d62 100644 --- a/ui/src/components/access/AccessFormDigitalOceanConfig.tsx +++ b/ui/src/components/access/AccessFormDigitalOceanConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForDigitalOcean } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormDingTalkBotConfig.tsx b/ui/src/components/access/AccessFormDingTalkBotConfig.tsx index 59904e18..914e4d2a 100644 --- a/ui/src/components/access/AccessFormDingTalkBotConfig.tsx +++ b/ui/src/components/access/AccessFormDingTalkBotConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForDingTalkBot } from "@/domain/access"; @@ -26,7 +26,7 @@ const AccessFormDingTalkBotConfig = ({ form: formInst, formName, disabled, initi const { t } = useTranslation(); const formSchema = z.object({ - webhookUrl: z.string().url(t("common.errmsg.url_invalid")), + webhookUrl: z.url(t("common.errmsg.url_invalid")), secret: z.string().nonempty(t("access.form.dingtalkbot_secret.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/access/AccessFormDiscordBotConfig.tsx b/ui/src/components/access/AccessFormDiscordBotConfig.tsx index 5f844ccc..4c1d345b 100644 --- a/ui/src/components/access/AccessFormDiscordBotConfig.tsx +++ b/ui/src/components/access/AccessFormDiscordBotConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForDiscordBot } from "@/domain/access"; @@ -26,7 +26,7 @@ const AccessFormDiscordBotConfig = ({ form: formInst, formName, disabled, initia const formSchema = z.object({ botToken: z - .string({ message: t("access.form.discordbot_token.placeholder") }) + .string(t("access.form.discordbot_token.placeholder")) .min(1, t("access.form.discordbot_token.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), defaultChannelId: z.string().nullish(), diff --git a/ui/src/components/access/AccessFormDogeCloudConfig.tsx b/ui/src/components/access/AccessFormDogeCloudConfig.tsx index 3e61d75f..f38ee881 100644 --- a/ui/src/components/access/AccessFormDogeCloudConfig.tsx +++ b/ui/src/components/access/AccessFormDogeCloudConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForDogeCloud } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormDuckDNSConfig.tsx b/ui/src/components/access/AccessFormDuckDNSConfig.tsx index 6b9c81b8..cb6f4c3a 100644 --- a/ui/src/components/access/AccessFormDuckDNSConfig.tsx +++ b/ui/src/components/access/AccessFormDuckDNSConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForDuckDNS } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormDynv6Config.tsx b/ui/src/components/access/AccessFormDynv6Config.tsx index 87e16c1e..0d7a44fa 100644 --- a/ui/src/components/access/AccessFormDynv6Config.tsx +++ b/ui/src/components/access/AccessFormDynv6Config.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForDynv6 } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormEdgioConfig.tsx b/ui/src/components/access/AccessFormEdgioConfig.tsx index a91298c9..fe20158d 100644 --- a/ui/src/components/access/AccessFormEdgioConfig.tsx +++ b/ui/src/components/access/AccessFormEdgioConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForEdgio } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormEmailConfig.tsx b/ui/src/components/access/AccessFormEmailConfig.tsx index ae3ac5c9..e36e4984 100644 --- a/ui/src/components/access/AccessFormEmailConfig.tsx +++ b/ui/src/components/access/AccessFormEmailConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, InputNumber, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForEmail } from "@/domain/access"; import { validEmailAddress, validPortNumber } from "@/utils/validators"; diff --git a/ui/src/components/access/AccessFormFlexCDNConfig.tsx b/ui/src/components/access/AccessFormFlexCDNConfig.tsx index f07b8359..f07cd416 100644 --- a/ui/src/components/access/AccessFormFlexCDNConfig.tsx +++ b/ui/src/components/access/AccessFormFlexCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Radio, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForFlexCDN } from "@/domain/access"; @@ -28,10 +28,8 @@ const AccessFormFlexCDNConfig = ({ form: formInst, formName, disabled, initialVa const { t } = useTranslation(); const formSchema = z.object({ - serverUrl: z.string().url(t("common.errmsg.url_invalid")), - role: z.union([z.literal("user"), z.literal("admin")], { - message: t("access.form.flexcdn_api_role.placeholder"), - }), + serverUrl: z.url(t("common.errmsg.url_invalid")), + role: z.literal(["user", "admin"], t("access.form.flexcdn_api_role.placeholder")), accessKeyId: z.string().nonempty(t("access.form.flexcdn_access_key_id.placeholder")), accessKey: z.string().nonempty(t("access.form.flexcdn_access_key.placeholder")), allowInsecureConnections: z.boolean().nullish(), diff --git a/ui/src/components/access/AccessFormGcoreConfig.tsx b/ui/src/components/access/AccessFormGcoreConfig.tsx index f78d7309..fce3113e 100644 --- a/ui/src/components/access/AccessFormGcoreConfig.tsx +++ b/ui/src/components/access/AccessFormGcoreConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForGcore } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormGnameConfig.tsx b/ui/src/components/access/AccessFormGnameConfig.tsx index 990f01b6..e330cf9a 100644 --- a/ui/src/components/access/AccessFormGnameConfig.tsx +++ b/ui/src/components/access/AccessFormGnameConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForGname } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormGoDaddyConfig.tsx b/ui/src/components/access/AccessFormGoDaddyConfig.tsx index c604a8b3..6398cff7 100644 --- a/ui/src/components/access/AccessFormGoDaddyConfig.tsx +++ b/ui/src/components/access/AccessFormGoDaddyConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForGoDaddy } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormGoEdgeConfig.tsx b/ui/src/components/access/AccessFormGoEdgeConfig.tsx index 822c410b..9508660b 100644 --- a/ui/src/components/access/AccessFormGoEdgeConfig.tsx +++ b/ui/src/components/access/AccessFormGoEdgeConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Radio, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForGoEdge } from "@/domain/access"; @@ -28,10 +28,8 @@ const AccessFormGoEdgeConfig = ({ form: formInst, formName, disabled, initialVal const { t } = useTranslation(); const formSchema = z.object({ - serverUrl: z.string().url(t("common.errmsg.url_invalid")), - role: z.union([z.literal("user"), z.literal("admin")], { - message: t("access.form.goedge_api_role.placeholder"), - }), + serverUrl: z.url(t("common.errmsg.url_invalid")), + role: z.literal(["user", "admin"], t("access.form.goedge_api_role.placeholder")), accessKeyId: z.string().nonempty(t("access.form.goedge_access_key_id.placeholder")), accessKey: z.string().nonempty(t("access.form.goedge_access_key.placeholder")), allowInsecureConnections: z.boolean().nullish(), diff --git a/ui/src/components/access/AccessFormGoogleTrustServicesConfig.tsx b/ui/src/components/access/AccessFormGoogleTrustServicesConfig.tsx index b30384f5..0fc93e32 100644 --- a/ui/src/components/access/AccessFormGoogleTrustServicesConfig.tsx +++ b/ui/src/components/access/AccessFormGoogleTrustServicesConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForGoogleTrustServices } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormHetznerConfig.tsx b/ui/src/components/access/AccessFormHetznerConfig.tsx index b596e997..9935a9fb 100644 --- a/ui/src/components/access/AccessFormHetznerConfig.tsx +++ b/ui/src/components/access/AccessFormHetznerConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForHetzner } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormHuaweiCloudConfig.tsx b/ui/src/components/access/AccessFormHuaweiCloudConfig.tsx index fc56d558..662f4f4d 100644 --- a/ui/src/components/access/AccessFormHuaweiCloudConfig.tsx +++ b/ui/src/components/access/AccessFormHuaweiCloudConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForHuaweiCloud } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormJDCloudConfig.tsx b/ui/src/components/access/AccessFormJDCloudConfig.tsx index 10fb4bad..5ca330fc 100644 --- a/ui/src/components/access/AccessFormJDCloudConfig.tsx +++ b/ui/src/components/access/AccessFormJDCloudConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForJDCloud } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormKubernetesConfig.tsx b/ui/src/components/access/AccessFormKubernetesConfig.tsx index ff2bd491..dad70229 100644 --- a/ui/src/components/access/AccessFormKubernetesConfig.tsx +++ b/ui/src/components/access/AccessFormKubernetesConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import TextFileInput from "@/components/TextFileInput"; import { type AccessConfigForKubernetes } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormLarkBotConfig.tsx b/ui/src/components/access/AccessFormLarkBotConfig.tsx index 2a07505e..92a732c3 100644 --- a/ui/src/components/access/AccessFormLarkBotConfig.tsx +++ b/ui/src/components/access/AccessFormLarkBotConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForLarkBot } from "@/domain/access"; @@ -25,7 +25,7 @@ const AccessFormLarkBotConfig = ({ form: formInst, formName, disabled, initialVa const { t } = useTranslation(); const formSchema = z.object({ - webhookUrl: z.string().url(t("common.errmsg.url_invalid")), + webhookUrl: z.url(t("common.errmsg.url_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/access/AccessFormLeCDNConfig.tsx b/ui/src/components/access/AccessFormLeCDNConfig.tsx index 1f9feabc..de3f1e47 100644 --- a/ui/src/components/access/AccessFormLeCDNConfig.tsx +++ b/ui/src/components/access/AccessFormLeCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Radio, Select, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForLeCDN } from "@/domain/access"; @@ -29,10 +29,8 @@ const AccessFormLeCDNConfig = ({ form: formInst, formName, disabled, initialValu const { t } = useTranslation(); const formSchema = z.object({ - serverUrl: z.string().url(t("common.errmsg.url_invalid")), - role: z.union([z.literal("client"), z.literal("master")], { - message: t("access.form.lecdn_api_role.placeholder"), - }), + serverUrl: z.url(t("common.errmsg.url_invalid")), + role: z.literal(["client", "master"], t("access.form.lecdn_api_role.placeholder")), username: z.string().nonempty(t("access.form.lecdn_username.placeholder")), password: z.string().nonempty(t("access.form.lecdn_password.placeholder")), allowInsecureConnections: z.boolean().nullish(), diff --git a/ui/src/components/access/AccessFormMattermostConfig.tsx b/ui/src/components/access/AccessFormMattermostConfig.tsx index a583cc19..5735d159 100644 --- a/ui/src/components/access/AccessFormMattermostConfig.tsx +++ b/ui/src/components/access/AccessFormMattermostConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForMattermost } from "@/domain/access"; @@ -27,7 +27,7 @@ const AccessFormMattermostConfig = ({ form: formInst, formName, disabled, initia const { t } = useTranslation(); const formSchema = z.object({ - serverUrl: z.string().url(t("common.errmsg.url_invalid")), + serverUrl: z.url(t("common.errmsg.url_invalid")), username: z.string().nonempty(t("access.form.mattermost_username.placeholder")), password: z.string().nonempty(t("access.form.mattermost_password.placeholder")), defaultChannelId: z.string().nullish(), diff --git a/ui/src/components/access/AccessFormNS1Config.tsx b/ui/src/components/access/AccessFormNS1Config.tsx index 4080b79b..82d8107e 100644 --- a/ui/src/components/access/AccessFormNS1Config.tsx +++ b/ui/src/components/access/AccessFormNS1Config.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForNS1 } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormNameDotComConfig.tsx b/ui/src/components/access/AccessFormNameDotComConfig.tsx index e5a7a372..370f4a3c 100644 --- a/ui/src/components/access/AccessFormNameDotComConfig.tsx +++ b/ui/src/components/access/AccessFormNameDotComConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForNameDotCom } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormNameSiloConfig.tsx b/ui/src/components/access/AccessFormNameSiloConfig.tsx index a9421ffe..ce5491e9 100644 --- a/ui/src/components/access/AccessFormNameSiloConfig.tsx +++ b/ui/src/components/access/AccessFormNameSiloConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForNameSilo } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormNamecheapConfig.tsx b/ui/src/components/access/AccessFormNamecheapConfig.tsx index 2ac81909..4d174212 100644 --- a/ui/src/components/access/AccessFormNamecheapConfig.tsx +++ b/ui/src/components/access/AccessFormNamecheapConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForNamecheap } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormNetcupConfig.tsx b/ui/src/components/access/AccessFormNetcupConfig.tsx index 02aa5272..0c1fbd8d 100644 --- a/ui/src/components/access/AccessFormNetcupConfig.tsx +++ b/ui/src/components/access/AccessFormNetcupConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForNetcup } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormNetlifyConfig.tsx b/ui/src/components/access/AccessFormNetlifyConfig.tsx index 91d0c31e..44767bba 100644 --- a/ui/src/components/access/AccessFormNetlifyConfig.tsx +++ b/ui/src/components/access/AccessFormNetlifyConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForNetlify } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormPorkbunConfig.tsx b/ui/src/components/access/AccessFormPorkbunConfig.tsx index 65193db7..ecd52e6b 100644 --- a/ui/src/components/access/AccessFormPorkbunConfig.tsx +++ b/ui/src/components/access/AccessFormPorkbunConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForPorkbun } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormPowerDNSConfig.tsx b/ui/src/components/access/AccessFormPowerDNSConfig.tsx index e9dc9756..1dad3b2c 100644 --- a/ui/src/components/access/AccessFormPowerDNSConfig.tsx +++ b/ui/src/components/access/AccessFormPowerDNSConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForPowerDNS } from "@/domain/access"; @@ -26,7 +26,7 @@ const AccessFormPowerDNSConfig = ({ form: formInst, formName, disabled, initialV const { t } = useTranslation(); const formSchema = z.object({ - serverUrl: z.string().url(t("common.errmsg.url_invalid")), + serverUrl: z.url(t("common.errmsg.url_invalid")), apiKey: z .string() .min(1, t("access.form.powerdns_api_key.placeholder")) diff --git a/ui/src/components/access/AccessFormProxmoxVEConfig.tsx b/ui/src/components/access/AccessFormProxmoxVEConfig.tsx index b2d44011..6ba1c921 100644 --- a/ui/src/components/access/AccessFormProxmoxVEConfig.tsx +++ b/ui/src/components/access/AccessFormProxmoxVEConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForProxmoxVE } from "@/domain/access"; @@ -26,7 +26,7 @@ const AccessFormProxmoxVEConfig = ({ form: formInst, formName, disabled, initial const { t } = useTranslation(); const formSchema = z.object({ - serverUrl: z.string().url(t("common.errmsg.url_invalid")), + serverUrl: z.url(t("common.errmsg.url_invalid")), apiToken: z.string().nonempty(t("access.form.proxmoxve_api_token.placeholder")), apiTokenSecret: z.string().nullish(), allowInsecureConnections: z.boolean().nullish(), diff --git a/ui/src/components/access/AccessFormQiniuConfig.tsx b/ui/src/components/access/AccessFormQiniuConfig.tsx index dcbebcd0..1fb53845 100644 --- a/ui/src/components/access/AccessFormQiniuConfig.tsx +++ b/ui/src/components/access/AccessFormQiniuConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForQiniu } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormRainYunConfig.tsx b/ui/src/components/access/AccessFormRainYunConfig.tsx index b9b0b171..a07208f4 100644 --- a/ui/src/components/access/AccessFormRainYunConfig.tsx +++ b/ui/src/components/access/AccessFormRainYunConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForRainYun } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormRatPanelConfig.tsx b/ui/src/components/access/AccessFormRatPanelConfig.tsx index 26448f46..4de0c878 100644 --- a/ui/src/components/access/AccessFormRatPanelConfig.tsx +++ b/ui/src/components/access/AccessFormRatPanelConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForRatPanel } from "@/domain/access"; @@ -27,7 +27,7 @@ const AccessFormRatPanelConfig = ({ form: formInst, formName, disabled, initialV const { t } = useTranslation(); const formSchema = z.object({ - serverUrl: z.string().url(t("common.errmsg.url_invalid")), + serverUrl: z.url(t("common.errmsg.url_invalid")), accessTokenId: z.preprocess((v) => Number(v), z.number().positive(t("access.form.ratpanel_access_token_id.placeholder"))), accessToken: z.string().nonempty(t("access.form.ratpanel_access_token.placeholder")), allowInsecureConnections: z.boolean().nullish(), diff --git a/ui/src/components/access/AccessFormSSHConfig.tsx b/ui/src/components/access/AccessFormSSHConfig.tsx index 56532771..99120f14 100644 --- a/ui/src/components/access/AccessFormSSHConfig.tsx +++ b/ui/src/components/access/AccessFormSSHConfig.tsx @@ -2,7 +2,7 @@ import { useTranslation } from "react-i18next"; import { ArrowDownOutlined, ArrowUpOutlined, CloseOutlined, PlusOutlined } from "@ant-design/icons"; import { Button, Collapse, Form, type FormInstance, Input, InputNumber, Select, Space } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; import TextFileInput from "@/components/TextFileInput"; @@ -44,9 +44,7 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues .int(t("access.form.ssh_port.placeholder")) .refine((v) => validPortNumber(v), t("common.errmsg.port_invalid")) ), - authMethod: z.union([z.literal(AUTH_METHOD_NONE), z.literal(AUTH_METHOD_PASSWORD), z.literal(AUTH_METHOD_KEY)], { - message: t("access.form.ssh_auth_method.placeholder"), - }), + authMethod: z.literal([AUTH_METHOD_NONE, AUTH_METHOD_PASSWORD, AUTH_METHOD_KEY], t("access.form.ssh_auth_method.placeholder")), username: z .string() .min(1, t("access.form.ssh_username.placeholder")) @@ -55,12 +53,18 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues .string() .max(64, t("common.errmsg.string_max", { max: 64 })) .nullish() - .refine((v) => fieldAuthMethod !== AUTH_METHOD_PASSWORD || !!v?.trim(), t("access.form.ssh_password.placeholder")), + .refine((v) => { + if (fieldAuthMethod !== AUTH_METHOD_PASSWORD) return true; + return !!v?.trim(); + }, t("access.form.ssh_password.placeholder")), key: z .string() .max(20480, t("common.errmsg.string_max", { max: 20480 })) .nullish() - .refine((v) => fieldAuthMethod !== AUTH_METHOD_KEY || !!v?.trim(), t("access.form.ssh_key.placeholder")), + .refine((v) => { + if (fieldAuthMethod !== AUTH_METHOD_KEY) return true; + return !!v?.trim(); + }, t("access.form.ssh_key.placeholder")), keyPassphrase: z .string() .max(20480, t("common.errmsg.string_max", { max: 20480 })) @@ -77,9 +81,7 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues .int(t("access.form.ssh_port.placeholder")) .refine((v) => validPortNumber(v), t("common.errmsg.port_invalid")) ), - authMethod: z.union([z.literal(AUTH_METHOD_NONE), z.literal(AUTH_METHOD_PASSWORD), z.literal(AUTH_METHOD_KEY)], { - message: t("access.form.ssh_auth_method.placeholder"), - }), + authMethod: z.literal([AUTH_METHOD_NONE, AUTH_METHOD_PASSWORD, AUTH_METHOD_KEY], t("access.form.ssh_auth_method.placeholder")), username: z .string() .min(1, t("access.form.ssh_username.placeholder")) @@ -97,7 +99,7 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues .max(20480, t("common.errmsg.string_max", { max: 20480 })) .nullish(), }), - { message: t("access.form.ssh_jump_servers.errmsg.invalid") } + { error: t("access.form.ssh_jump_servers.errmsg.invalid") } ) .nullish(), }); diff --git a/ui/src/components/access/AccessFormSSLComConfig.tsx b/ui/src/components/access/AccessFormSSLComConfig.tsx index 22b60ae4..9fcd71a5 100644 --- a/ui/src/components/access/AccessFormSSLComConfig.tsx +++ b/ui/src/components/access/AccessFormSSLComConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForSSLCom } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormSafeLineConfig.tsx b/ui/src/components/access/AccessFormSafeLineConfig.tsx index e3d3e75d..ad5e2c43 100644 --- a/ui/src/components/access/AccessFormSafeLineConfig.tsx +++ b/ui/src/components/access/AccessFormSafeLineConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForSafeLine } from "@/domain/access"; @@ -26,7 +26,7 @@ const AccessFormSafeLineConfig = ({ form: formInst, formName, disabled, initialV const { t } = useTranslation(); const formSchema = z.object({ - serverUrl: z.string().url(t("common.errmsg.url_invalid")), + serverUrl: z.url(t("common.errmsg.url_invalid")), apiToken: z .string() .min(1, t("access.form.safeline_api_token.placeholder")) diff --git a/ui/src/components/access/AccessFormSlackBotConfig.tsx b/ui/src/components/access/AccessFormSlackBotConfig.tsx index a0bdbad4..493d5a1d 100644 --- a/ui/src/components/access/AccessFormSlackBotConfig.tsx +++ b/ui/src/components/access/AccessFormSlackBotConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForSlackBot } from "@/domain/access"; @@ -26,7 +26,7 @@ const AccessFormSlackBotConfig = ({ form: formInst, formName, disabled, initialV const formSchema = z.object({ botToken: z - .string({ message: t("access.form.slackbot_token.placeholder") }) + .string(t("access.form.slackbot_token.placeholder")) .min(1, t("access.form.slackbot_token.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), defaultChannelId: z.string().nullish(), diff --git a/ui/src/components/access/AccessFormTelegramBotConfig.tsx b/ui/src/components/access/AccessFormTelegramBotConfig.tsx index a347610f..bafc36ca 100644 --- a/ui/src/components/access/AccessFormTelegramBotConfig.tsx +++ b/ui/src/components/access/AccessFormTelegramBotConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForTelegramBot } from "@/domain/access"; @@ -26,7 +26,7 @@ const AccessFormTelegramBotConfig = ({ form: formInst, formName, disabled, initi const formSchema = z.object({ botToken: z - .string({ message: t("access.form.telegrambot_token.placeholder") }) + .string(t("access.form.telegrambot_token.placeholder")) .min(1, t("access.form.telegrambot_token.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), defaultChatId: z diff --git a/ui/src/components/access/AccessFormTencentCloudConfig.tsx b/ui/src/components/access/AccessFormTencentCloudConfig.tsx index 540ebdd9..4af7b647 100644 --- a/ui/src/components/access/AccessFormTencentCloudConfig.tsx +++ b/ui/src/components/access/AccessFormTencentCloudConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForTencentCloud } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormUCloudConfig.tsx b/ui/src/components/access/AccessFormUCloudConfig.tsx index 395d185e..462d5865 100644 --- a/ui/src/components/access/AccessFormUCloudConfig.tsx +++ b/ui/src/components/access/AccessFormUCloudConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForUCloud } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormUniCloudConfig.tsx b/ui/src/components/access/AccessFormUniCloudConfig.tsx index 8b6d1346..b985c580 100644 --- a/ui/src/components/access/AccessFormUniCloudConfig.tsx +++ b/ui/src/components/access/AccessFormUniCloudConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForUniCloud } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormUpyunConfig.tsx b/ui/src/components/access/AccessFormUpyunConfig.tsx index 24feb9f8..83228f50 100644 --- a/ui/src/components/access/AccessFormUpyunConfig.tsx +++ b/ui/src/components/access/AccessFormUpyunConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForUpyun } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormVercelConfig.tsx b/ui/src/components/access/AccessFormVercelConfig.tsx index a3a1954e..593066a5 100644 --- a/ui/src/components/access/AccessFormVercelConfig.tsx +++ b/ui/src/components/access/AccessFormVercelConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForVercel } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormVolcEngineConfig.tsx b/ui/src/components/access/AccessFormVolcEngineConfig.tsx index c9a302a2..54c77485 100644 --- a/ui/src/components/access/AccessFormVolcEngineConfig.tsx +++ b/ui/src/components/access/AccessFormVolcEngineConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForVolcEngine } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormWangsuConfig.tsx b/ui/src/components/access/AccessFormWangsuConfig.tsx index fe2950c4..71fbe0a6 100644 --- a/ui/src/components/access/AccessFormWangsuConfig.tsx +++ b/ui/src/components/access/AccessFormWangsuConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForWangsu } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormWeComBotConfig.tsx b/ui/src/components/access/AccessFormWeComBotConfig.tsx index 16a205f5..cb63e48b 100644 --- a/ui/src/components/access/AccessFormWeComBotConfig.tsx +++ b/ui/src/components/access/AccessFormWeComBotConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForWeComBot } from "@/domain/access"; @@ -25,7 +25,7 @@ const AccessFormWeComBotConfig = ({ form: formInst, formName, disabled, initialV const { t } = useTranslation(); const formSchema = z.object({ - webhookUrl: z.string().url(t("common.errmsg.url_invalid")), + webhookUrl: z.url(t("common.errmsg.url_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/access/AccessFormWebhookConfig.tsx b/ui/src/components/access/AccessFormWebhookConfig.tsx index 7ceec29a..b0459469 100644 --- a/ui/src/components/access/AccessFormWebhookConfig.tsx +++ b/ui/src/components/access/AccessFormWebhookConfig.tsx @@ -2,7 +2,7 @@ import { useTranslation } from "react-i18next"; import { DownOutlined as DownOutlinedIcon } from "@ant-design/icons"; import { Alert, Button, Dropdown, Form, type FormInstance, Input, Select, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import CodeInput from "@/components/CodeInput"; import Show from "@/components/Show"; @@ -49,10 +49,8 @@ const AccessFormWebhookConfig = ({ form: formInst, formName, disabled, initialVa const { t } = useTranslation(); const formSchema = z.object({ - url: z.string().url(t("common.errmsg.url_invalid")), - method: z.union([z.literal("GET"), z.literal("POST"), z.literal("PUT"), z.literal("PATCH"), z.literal("DELETE")], { - message: t("access.form.webhook_method.placeholder"), - }), + url: z.url(t("common.errmsg.url_invalid")), + method: z.literal(["GET", "POST", "PUT", "PATCH", "DELETE"], t("access.form.webhook_method.placeholder")), headers: z .string() .nullish() diff --git a/ui/src/components/access/AccessFormWestcnConfig.tsx b/ui/src/components/access/AccessFormWestcnConfig.tsx index 34439316..35ce6b58 100644 --- a/ui/src/components/access/AccessFormWestcnConfig.tsx +++ b/ui/src/components/access/AccessFormWestcnConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForWestcn } from "@/domain/access"; diff --git a/ui/src/components/access/AccessFormZeroSSLConfig.tsx b/ui/src/components/access/AccessFormZeroSSLConfig.tsx index a1653667..6579dbc0 100644 --- a/ui/src/components/access/AccessFormZeroSSLConfig.tsx +++ b/ui/src/components/access/AccessFormZeroSSLConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type AccessConfigForZeroSSL } from "@/domain/access"; diff --git a/ui/src/components/notification/NotifyChannelEditFormBarkFields.tsx b/ui/src/components/notification/NotifyChannelEditFormBarkFields.tsx index 154b870a..e10fea9f 100644 --- a/ui/src/components/notification/NotifyChannelEditFormBarkFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormBarkFields.tsx @@ -1,18 +1,15 @@ import { useTranslation } from "react-i18next"; import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; const NotifyChannelEditFormBarkFields = () => { const { t } = useTranslation(); const formSchema = z.object({ - serverUrl: z - .string({ message: t("settings.notification.channel.form.bark_server_url.placeholder") }) - .url(t("common.errmsg.url_invalid")) - .nullish(), + serverUrl: z.url(t("common.errmsg.url_invalid")).nullish(), deviceKey: z - .string({ message: t("settings.notification.channel.form.bark_device_key.placeholder") }) + .string(t("settings.notification.channel.form.bark_device_key.placeholder")) .nonempty(t("settings.notification.channel.form.bark_device_key.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/notification/NotifyChannelEditFormDingTalkFields.tsx b/ui/src/components/notification/NotifyChannelEditFormDingTalkFields.tsx index f7daa4bf..b6a959ae 100644 --- a/ui/src/components/notification/NotifyChannelEditFormDingTalkFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormDingTalkFields.tsx @@ -1,17 +1,17 @@ import { useTranslation } from "react-i18next"; import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; const NotifyChannelEditFormDingTalkFields = () => { const { t } = useTranslation(); const formSchema = z.object({ accessToken: z - .string({ message: t("settings.notification.channel.form.dingtalk_access_token.placeholder") }) + .string(t("settings.notification.channel.form.dingtalk_access_token.placeholder")) .nonempty(t("settings.notification.channel.form.dingtalk_access_token.placeholder")), secret: z - .string({ message: t("settings.notification.channel.form.dingtalk_secret.placeholder") }) + .string(t("settings.notification.channel.form.dingtalk_secret.placeholder")) .nonempty(t("settings.notification.channel.form.dingtalk_secret.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/notification/NotifyChannelEditFormEmailFields.tsx b/ui/src/components/notification/NotifyChannelEditFormEmailFields.tsx index d7c08c4f..fd935b7c 100644 --- a/ui/src/components/notification/NotifyChannelEditFormEmailFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormEmailFields.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, Input, InputNumber, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validPortNumber } from "@/utils/validators"; @@ -10,27 +10,24 @@ const NotifyChannelEditFormEmailFields = () => { const formSchema = z.object({ smtpHost: z - .string({ message: t("settings.notification.channel.form.email_smtp_host.placeholder") }) + .string(t("settings.notification.channel.form.email_smtp_host.placeholder")) .min(1, t("settings.notification.channel.form.email_smtp_host.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), smtpPort: z.preprocess( (v) => Number(v), - z - .number({ message: t("settings.notification.channel.form.email_smtp_port.placeholder") }) - .int(t("settings.notification.channel.form.email_smtp_port.placeholder")) - .refine((v) => validPortNumber(v), t("common.errmsg.port_invalid")) + z.number().refine((v) => validPortNumber(v), t("common.errmsg.port_invalid")) ), smtpTLS: z.boolean().nullish(), username: z - .string({ message: t("settings.notification.channel.form.email_username.placeholder") }) + .string(t("settings.notification.channel.form.email_username.placeholder")) .min(1, t("settings.notification.channel.form.email_username.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), password: z - .string({ message: t("settings.notification.channel.form.email_password.placeholder") }) + .string(t("settings.notification.channel.form.email_password.placeholder")) .min(1, t("settings.notification.channel.form.email_password.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), - senderAddress: z.string({ message: t("settings.notification.channel.form.email_sender_address.placeholder") }).email(t("common.errmsg.email_invalid")), - receiverAddress: z.string({ message: t("settings.notification.channel.form.email_receiver_address.placeholder") }).email(t("common.errmsg.email_invalid")), + senderAddress: z.email(t("common.errmsg.email_invalid")), + receiverAddress: z.email(t("common.errmsg.email_invalid")), }); const formRule = createSchemaFieldRule(formSchema); const formInst = Form.useFormInstance>(); diff --git a/ui/src/components/notification/NotifyChannelEditFormGotifyFields.tsx b/ui/src/components/notification/NotifyChannelEditFormGotifyFields.tsx index 69aa4b46..4e0fd6e1 100644 --- a/ui/src/components/notification/NotifyChannelEditFormGotifyFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormGotifyFields.tsx @@ -1,20 +1,15 @@ import { useTranslation } from "react-i18next"; import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; const NotifyChannelEditFormGotifyFields = () => { const { t } = useTranslation(); const formSchema = z.object({ - url: z.string({ message: t("settings.notification.channel.form.gotify_url.placeholder") }).url({ message: t("common.errmsg.url_invalid") }), - token: z.string({ message: t("settings.notification.channel.form.gotify_token.placeholder") }), - priority: z.preprocess( - (val) => Number(val), - z - .number({ message: t("settings.notification.channel.form.gotify_priority.placeholder") }) - .gte(0, { message: t("settings.notification.channel.form.gotify_priority.error.gte0") }) - ), + url: z.url(t("common.errmsg.url_invalid")), + token: z.string(t("settings.notification.channel.form.gotify_token.placeholder")), + priority: z.preprocess((val) => Number(val), z.number().gte(0, t("settings.notification.channel.form.gotify_priority.error.gte0"))), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/notification/NotifyChannelEditFormLarkFields.tsx b/ui/src/components/notification/NotifyChannelEditFormLarkFields.tsx index bd683824..058e731f 100644 --- a/ui/src/components/notification/NotifyChannelEditFormLarkFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormLarkFields.tsx @@ -1,13 +1,13 @@ import { useTranslation } from "react-i18next"; import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; const NotifyChannelEditFormLarkFields = () => { const { t } = useTranslation(); const formSchema = z.object({ - webhookUrl: z.string({ message: t("settings.notification.channel.form.lark_webhook_url.placeholder") }).url(t("common.errmsg.url_invalid")), + webhookUrl: z.url(t("common.errmsg.url_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/notification/NotifyChannelEditFormMattermostFields.tsx b/ui/src/components/notification/NotifyChannelEditFormMattermostFields.tsx index 829a2a0d..93105810 100644 --- a/ui/src/components/notification/NotifyChannelEditFormMattermostFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormMattermostFields.tsx @@ -1,21 +1,21 @@ import { useTranslation } from "react-i18next"; import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; const NotifyChannelEditFormMattermostFields = () => { const { t } = useTranslation(); const formSchema = z.object({ - serverUrl: z.string({ message: t("settings.notification.channel.form.mattermost_server_url.placeholder") }).url(t("common.errmsg.url_invalid")), + serverUrl: z.url(t("common.errmsg.url_invalid")), channelId: z - .string({ message: t("settings.notification.channel.form.mattermost_channel_id.placeholder") }) + .string(t("settings.notification.channel.form.mattermost_channel_id.placeholder")) .nonempty(t("settings.notification.channel.form.mattermost_channel_id.placeholder")), username: z - .string({ message: t("settings.notification.channel.form.mattermost_username.placeholder") }) + .string(t("settings.notification.channel.form.mattermost_username.placeholder")) .nonempty(t("settings.notification.channel.form.mattermost_username.placeholder")), password: z - .string({ message: t("settings.notification.channel.form.mattermost_password.placeholder") }) + .string(t("settings.notification.channel.form.mattermost_password.placeholder")) .nonempty(t("settings.notification.channel.form.mattermost_password.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/notification/NotifyChannelEditFormPushPlusFields.tsx b/ui/src/components/notification/NotifyChannelEditFormPushPlusFields.tsx index 36f6e21a..f106b918 100644 --- a/ui/src/components/notification/NotifyChannelEditFormPushPlusFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormPushPlusFields.tsx @@ -1,13 +1,13 @@ import { useTranslation } from "react-i18next"; import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; const NotifyChannelEditFormPushPlusFields = () => { const { t } = useTranslation(); const formSchema = z.object({ - token: z.string({ message: t("settings.notification.channel.form.pushplus_token.placeholder") }), + token: z.string(t("settings.notification.channel.form.pushplus_token.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/notification/NotifyChannelEditFormPushoverFields.tsx b/ui/src/components/notification/NotifyChannelEditFormPushoverFields.tsx index 449c98fa..51fdd7ff 100644 --- a/ui/src/components/notification/NotifyChannelEditFormPushoverFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormPushoverFields.tsx @@ -1,17 +1,17 @@ import { useTranslation } from "react-i18next"; import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; const NotifyChannelEditFormPushoverFields = () => { const { t } = useTranslation(); const formSchema = z.object({ token: z - .string({ message: t("settings.notification.channel.form.pushover_token.placeholder") }) + .string(t("settings.notification.channel.form.pushover_token.placeholder")) .nonempty(t("settings.notification.channel.form.pushover_token.placeholder")), user: z - .string({ message: t("settings.notification.channel.form.pushover_user.placeholder") }) + .string(t("settings.notification.channel.form.pushover_user.placeholder")) .nonempty(t("settings.notification.channel.form.pushover_user.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/notification/NotifyChannelEditFormServerChanFields.tsx b/ui/src/components/notification/NotifyChannelEditFormServerChanFields.tsx index b820f925..2fd24a6a 100644 --- a/ui/src/components/notification/NotifyChannelEditFormServerChanFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormServerChanFields.tsx @@ -1,13 +1,13 @@ import { useTranslation } from "react-i18next"; import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; const NotifyChannelEditFormServerChanFields = () => { const { t } = useTranslation(); const formSchema = z.object({ - url: z.string({ message: t("settings.notification.channel.form.serverchan_url.placeholder") }).url(t("common.errmsg.url_invalid")), + url: z.url(t("common.errmsg.url_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/notification/NotifyChannelEditFormTelegramFields.tsx b/ui/src/components/notification/NotifyChannelEditFormTelegramFields.tsx index 4d6b31f4..5397df5c 100644 --- a/ui/src/components/notification/NotifyChannelEditFormTelegramFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormTelegramFields.tsx @@ -1,18 +1,18 @@ import { useTranslation } from "react-i18next"; import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; const NotifyChannelEditFormTelegramFields = () => { const { t } = useTranslation(); const formSchema = z.object({ apiToken: z - .string({ message: t("settings.notification.channel.form.telegram_api_token.placeholder") }) + .string(t("settings.notification.channel.form.telegram_api_token.placeholder")) .min(1, t("settings.notification.channel.form.telegram_api_token.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), chatId: z - .string({ message: t("settings.notification.channel.form.telegram_chat_id.placeholder") }) + .string(t("settings.notification.channel.form.telegram_chat_id.placeholder")) .min(1, t("settings.notification.channel.form.telegram_chat_id.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); diff --git a/ui/src/components/notification/NotifyChannelEditFormWeComFields.tsx b/ui/src/components/notification/NotifyChannelEditFormWeComFields.tsx index 645653a4..bc490b25 100644 --- a/ui/src/components/notification/NotifyChannelEditFormWeComFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormWeComFields.tsx @@ -1,13 +1,13 @@ import { useTranslation } from "react-i18next"; import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; const NotifyChannelEditFormWeComFields = () => { const { t } = useTranslation(); const formSchema = z.object({ - webhookUrl: z.string({ message: t("settings.notification.channel.form.wecom_webhook_url.placeholder") }).url({ message: t("common.errmsg.url_invalid") }), + webhookUrl: z.url(t("common.errmsg.url_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/notification/NotifyChannelEditFormWebhookFields.tsx b/ui/src/components/notification/NotifyChannelEditFormWebhookFields.tsx index abf935c2..09288be1 100644 --- a/ui/src/components/notification/NotifyChannelEditFormWebhookFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormWebhookFields.tsx @@ -1,13 +1,13 @@ import { useTranslation } from "react-i18next"; import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; const NotifyChannelEditFormWebhookFields = () => { const { t } = useTranslation(); const formSchema = z.object({ - url: z.string({ message: t("settings.notification.channel.form.webhook_url.placeholder") }).url(t("common.errmsg.url_invalid")), + url: z.url(t("common.errmsg.url_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/notification/NotifyTemplate.tsx b/ui/src/components/notification/NotifyTemplate.tsx index 152596e7..28c34ae0 100644 --- a/ui/src/components/notification/NotifyTemplate.tsx +++ b/ui/src/components/notification/NotifyTemplate.tsx @@ -4,7 +4,7 @@ import { useRequest } from "ahooks"; import { Button, Form, Input, Skeleton, message, notification } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { ClientResponseError } from "pocketbase"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; import { type NotifyTemplatesSettingsContent, SETTINGS_NAMES, defaultNotifyTemplate } from "@/domain/settings"; diff --git a/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx b/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx index 402f6763..0edd6a4a 100644 --- a/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx @@ -10,7 +10,7 @@ import { import { useControllableValue } from "ahooks"; import { AutoComplete, Button, Divider, Flex, Form, type FormInstance, Input, InputNumber, Select, Switch, Tooltip, Typography } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import AccessEditModal from "@/components/access/AccessEditModal"; import AccessSelect from "@/components/access/AccessSelect"; @@ -60,22 +60,20 @@ const ApplyNodeConfigForm = forwardRef { + domains: z.string(t("workflow_node.apply.form.domains.placeholder")).refine((v) => { if (!v) return false; return String(v) .split(MULTIPLE_INPUT_SEPARATOR) .every((e) => validDomainName(e, { allowWildcard: true })); }, t("common.errmsg.domain_invalid")), - contactEmail: z.string({ message: t("workflow_node.apply.form.contact_email.placeholder") }).email(t("common.errmsg.email_invalid")), + contactEmail: z.email(t("common.errmsg.email_invalid")), challengeType: z.string().nullish(), - provider: z.string({ message: t("workflow_node.apply.form.provider.placeholder") }).nonempty(t("workflow_node.apply.form.provider.placeholder")), - providerAccessId: z - .string({ message: t("workflow_node.apply.form.provider_access.placeholder") }) - .min(1, t("workflow_node.apply.form.provider_access.placeholder")), + provider: z.string(t("workflow_node.apply.form.provider.placeholder")).nonempty(t("workflow_node.apply.form.provider.placeholder")), + providerAccessId: z.string(t("workflow_node.apply.form.provider_access.placeholder")).min(1, t("workflow_node.apply.form.provider_access.placeholder")), providerConfig: z.any().nullish(), - caProvider: z.string({ message: t("workflow_node.apply.form.ca_provider.placeholder") }).nullish(), + caProvider: z.string(t("workflow_node.apply.form.ca_provider.placeholder")).nullish(), caProviderAccessId: z - .string({ message: t("workflow_node.apply.form.ca_provider_access.placeholder") }) + .string(t("workflow_node.apply.form.ca_provider_access.placeholder")) .nullish() .refine((v) => { if (!fieldCAProvider) return true; @@ -84,14 +82,13 @@ const ApplyNodeConfigForm = forwardRef { if (!v) return true; + return String(v) .split(MULTIPLE_INPUT_SEPARATOR) .every((e) => validIPv4Address(e) || validIPv6Address(e) || validDomainName(e)); diff --git a/ui/src/components/workflow/node/ApplyNodeConfigFormAWSRoute53Config.tsx b/ui/src/components/workflow/node/ApplyNodeConfigFormAWSRoute53Config.tsx index 03698cb1..02dae8f2 100644 --- a/ui/src/components/workflow/node/ApplyNodeConfigFormAWSRoute53Config.tsx +++ b/ui/src/components/workflow/node/ApplyNodeConfigFormAWSRoute53Config.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type ApplyNodeConfigFormAWSRoute53ConfigFieldValues = Nullish<{ region: string; @@ -33,11 +33,9 @@ const ApplyNodeConfigFormAWSRoute53Config = ({ const { t } = useTranslation(); const formSchema = z.object({ - region: z - .string({ message: t("workflow_node.apply.form.aws_route53_region.placeholder") }) - .nonempty(t("workflow_node.apply.form.aws_route53_region.placeholder")), + region: z.string(t("workflow_node.apply.form.aws_route53_region.placeholder")).nonempty(t("workflow_node.apply.form.aws_route53_region.placeholder")), hostedZoneId: z - .string({ message: t("workflow_node.apply.form.aws_route53_hosted_zone_id.placeholder") }) + .string(t("workflow_node.apply.form.aws_route53_hosted_zone_id.placeholder")) .nonempty(t("workflow_node.apply.form.aws_route53_hosted_zone_id.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/ApplyNodeConfigFormAliyunESAConfig.tsx b/ui/src/components/workflow/node/ApplyNodeConfigFormAliyunESAConfig.tsx index 0ef39b22..32505de4 100644 --- a/ui/src/components/workflow/node/ApplyNodeConfigFormAliyunESAConfig.tsx +++ b/ui/src/components/workflow/node/ApplyNodeConfigFormAliyunESAConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type ApplyNodeConfigFormAliyunESAConfigFieldValues = Nullish<{ region: string; @@ -23,9 +23,7 @@ const ApplyNodeConfigFormAliyunESAConfig = ({ form: formInst, formName, disabled const { t } = useTranslation(); const formSchema = z.object({ - region: z - .string({ message: t("workflow_node.apply.form.aliyun_esa_region.placeholder") }) - .nonempty(t("workflow_node.apply.form.aliyun_esa_region.placeholder")), + region: z.string(t("workflow_node.apply.form.aliyun_esa_region.placeholder")).nonempty(t("workflow_node.apply.form.aliyun_esa_region.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/ApplyNodeConfigFormHuaweiCloudDNSConfig.tsx b/ui/src/components/workflow/node/ApplyNodeConfigFormHuaweiCloudDNSConfig.tsx index e806dd64..8814d21c 100644 --- a/ui/src/components/workflow/node/ApplyNodeConfigFormHuaweiCloudDNSConfig.tsx +++ b/ui/src/components/workflow/node/ApplyNodeConfigFormHuaweiCloudDNSConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type ApplyNodeConfigFormHuaweiCloudDNSConfigFieldValues = Nullish<{ region: string; @@ -32,7 +32,7 @@ const ApplyNodeConfigFormHuaweiCloudDNSConfig = ({ const formSchema = z.object({ region: z - .string({ message: t("workflow_node.apply.form.huaweicloud_dns_region.placeholder") }) + .string(t("workflow_node.apply.form.huaweicloud_dns_region.placeholder")) .nonempty(t("workflow_node.apply.form.huaweicloud_dns_region.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/ApplyNodeConfigFormJDCloudDNSConfig.tsx b/ui/src/components/workflow/node/ApplyNodeConfigFormJDCloudDNSConfig.tsx index cca7efd5..92aca5fd 100644 --- a/ui/src/components/workflow/node/ApplyNodeConfigFormJDCloudDNSConfig.tsx +++ b/ui/src/components/workflow/node/ApplyNodeConfigFormJDCloudDNSConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type ApplyNodeConfigFormJDCloudDNSConfigFieldValues = Nullish<{ regionId: string; @@ -32,7 +32,7 @@ const ApplyNodeConfigFormJDCloudDNSConfig = ({ const formSchema = z.object({ regionId: z - .string({ message: t("workflow_node.apply.form.jdcloud_dns_region_id.placeholder") }) + .string(t("workflow_node.apply.form.jdcloud_dns_region_id.placeholder")) .nonempty(t("workflow_node.apply.form.jdcloud_dns_region_id.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/ApplyNodeConfigFormTencentCloudEOConfig.tsx b/ui/src/components/workflow/node/ApplyNodeConfigFormTencentCloudEOConfig.tsx index f71e33e7..f76a0085 100644 --- a/ui/src/components/workflow/node/ApplyNodeConfigFormTencentCloudEOConfig.tsx +++ b/ui/src/components/workflow/node/ApplyNodeConfigFormTencentCloudEOConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type ApplyNodeConfigFormTencentCloudEOConfigFieldValues = Nullish<{ zoneId: string; @@ -30,7 +30,7 @@ const ApplyNodeConfigFormTencentCloudEOConfig = ({ const formSchema = z.object({ zoneId: z - .string({ message: t("workflow_node.apply.form.tencentcloud_eo_zone_id.placeholder") }) + .string(t("workflow_node.apply.form.tencentcloud_eo_zone_id.placeholder")) .nonempty(t("workflow_node.apply.form.tencentcloud_eo_zone_id.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/ConditionNodeConfigForm.tsx b/ui/src/components/workflow/node/ConditionNodeConfigForm.tsx index 1a2794e7..4f5f78c8 100644 --- a/ui/src/components/workflow/node/ConditionNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/ConditionNodeConfigForm.tsx @@ -2,7 +2,7 @@ import { forwardRef, memo, useImperativeHandle, useRef } from "react"; import { useTranslation } from "react-i18next"; import { Form, type FormInstance } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type Expr, type WorkflowNodeConfigForCondition, defaultNodeConfigForCondition } from "@/domain/workflow"; import { useAntdForm } from "@/hooks"; diff --git a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx index 318e3c95..16e587ea 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx @@ -3,7 +3,7 @@ import { useTranslation } from "react-i18next"; import { PlusOutlined as PlusOutlinedIcon, QuestionCircleOutlined as QuestionCircleOutlinedIcon } from "@ant-design/icons"; import { Button, Divider, Flex, Form, type FormInstance, Select, Switch, Tooltip, Typography, theme } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import AccessEditModal from "@/components/access/AccessEditModal"; import AccessSelect from "@/components/access/AccessSelect"; @@ -137,12 +137,10 @@ const DeployNodeConfigForm = forwardRef { if (!fieldProvider) return true; diff --git a/ui/src/components/workflow/node/DeployNodeConfigForm1PanelConsoleConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigForm1PanelConsoleConfig.tsx index b17150d8..b8e19186 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigForm1PanelConsoleConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigForm1PanelConsoleConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigForm1PanelConsoleConfigFieldValues = Nullish<{ autoRestart?: boolean; diff --git a/ui/src/components/workflow/node/DeployNodeConfigForm1PanelSiteConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigForm1PanelSiteConfig.tsx index 94a9bce2..e0e7e037 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigForm1PanelSiteConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigForm1PanelSiteConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; @@ -38,9 +38,7 @@ const DeployNodeConfigForm1PanelSiteConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - resourceType: z.union([z.literal(RESOURCE_TYPE_WEBSITE), z.literal(RESOURCE_TYPE_CERTIFICATE)], { - message: t("workflow_node.deploy.form.1panel_site_resource_type.placeholder"), - }), + resourceType: z.literal([RESOURCE_TYPE_WEBSITE, RESOURCE_TYPE_CERTIFICATE], t("workflow_node.deploy.form.1panel_site_resource_type.placeholder")), websiteId: z .union([z.string(), z.number().int()]) .nullish() diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAPISIXConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAPISIXConfig.tsx index 0fd67674..6998c0fd 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAPISIXConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAPISIXConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; @@ -31,9 +31,7 @@ const DeployNodeConfigFormAPISIXConfig = ({ form: formInst, formName, disabled, const { t } = useTranslation(); const formSchema = z.object({ - resourceType: z.literal(RESOURCE_TYPE_CERTIFICATE, { - message: t("workflow_node.deploy.form.apisix_resource_type.placeholder"), - }), + resourceType: z.literal(RESOURCE_TYPE_CERTIFICATE, t("workflow_node.deploy.form.apisix_resource_type.placeholder")), certificateId: z .string() .nullish() diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAWSACMConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAWSACMConfig.tsx index df7ba9b6..3d95b028 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAWSACMConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAWSACMConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormAWSACMConfigFieldValues = Nullish<{ region: string; @@ -24,9 +24,7 @@ const DeployNodeConfigFormAWSACMConfig = ({ form: formInst, formName, disabled, const { t } = useTranslation(); const formSchema = z.object({ - region: z - .string({ message: t("workflow_node.deploy.form.aws_acm_region.placeholder") }) - .nonempty(t("workflow_node.deploy.form.aws_acm_region.placeholder")), + region: z.string(t("workflow_node.deploy.form.aws_acm_region.placeholder")).nonempty(t("workflow_node.deploy.form.aws_acm_region.placeholder")), certificateArn: z.string().nullish(), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAWSCloudFrontConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAWSCloudFrontConfig.tsx index 3a15eea0..5c3169fe 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAWSCloudFrontConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAWSCloudFrontConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormAWSCloudFrontConfigFieldValues = Nullish<{ region: string; diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAWSIAMConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAWSIAMConfig.tsx index fa89d83b..d9e5365c 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAWSIAMConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAWSIAMConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormAWSIAMConfigFieldValues = Nullish<{ region: string; @@ -26,9 +26,7 @@ const DeployNodeConfigFormAWSIAMConfig = ({ form: formInst, formName, disabled, const { t } = useTranslation(); const formSchema = z.object({ - region: z - .string({ message: t("workflow_node.deploy.form.aws_iam_region.placeholder") }) - .nonempty(t("workflow_node.deploy.form.aws_iam_region.placeholder")), + region: z.string(t("workflow_node.deploy.form.aws_iam_region.placeholder")).nonempty(t("workflow_node.deploy.form.aws_iam_region.placeholder")), certificatePath: z .string() .nullish() diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunALBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunALBConfig.tsx index 5203130e..235d2a2a 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunALBConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunALBConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; import { validDomainName } from "@/utils/validators"; @@ -41,12 +41,8 @@ const DeployNodeConfigFormAliyunALBConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - region: z - .string({ message: t("workflow_node.deploy.form.aliyun_alb_region.placeholder") }) - .nonempty(t("workflow_node.deploy.form.aliyun_alb_region.placeholder")), - resourceType: z.union([z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { - message: t("workflow_node.deploy.form.aliyun_alb_resource_type.placeholder"), - }), + region: z.string(t("workflow_node.deploy.form.aliyun_alb_region.placeholder")).nonempty(t("workflow_node.deploy.form.aliyun_alb_region.placeholder")), + resourceType: z.literal([RESOURCE_TYPE_LOADBALANCER, RESOURCE_TYPE_LISTENER], t("workflow_node.deploy.form.aliyun_alb_resource_type.placeholder")), loadbalancerId: z .string() .max(64, t("common.errmsg.string_max", { max: 64 })) diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunAPIGWConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunAPIGWConfig.tsx index c88c9e5a..3fb8f166 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunAPIGWConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunAPIGWConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; import { validDomainName } from "@/utils/validators"; @@ -39,12 +39,8 @@ const DeployNodeConfigFormAliyunAPIGWConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - serviceType: z.union([z.literal(SERVICE_TYPE_CLOUDNATIVE), z.literal(SERVICE_TYPE_TRADITIONAL)], { - message: t("workflow_node.deploy.form.aliyun_apigw_service_type.placeholder"), - }), - region: z - .string({ message: t("workflow_node.deploy.form.aliyun_apigw_region.placeholder") }) - .nonempty(t("workflow_node.deploy.form.aliyun_apigw_region.placeholder")), + serviceType: z.literal([SERVICE_TYPE_CLOUDNATIVE, SERVICE_TYPE_TRADITIONAL], t("workflow_node.deploy.form.aliyun_apigw_service_type.placeholder")), + region: z.string(t("workflow_node.deploy.form.aliyun_apigw_region.placeholder")).nonempty(t("workflow_node.deploy.form.aliyun_apigw_region.placeholder")), gatewayId: z .string() .nullish() diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCASConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCASConfig.tsx index 1ea744fd..807dced6 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCASConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCASConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormAliyunCASConfigFieldValues = Nullish<{ region: string; @@ -29,9 +29,7 @@ const DeployNodeConfigFormAliyunCASConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - region: z - .string({ message: t("workflow_node.deploy.form.aliyun_cas_region.placeholder") }) - .nonempty(t("workflow_node.deploy.form.aliyun_cas_region.placeholder")), + region: z.string(t("workflow_node.deploy.form.aliyun_cas_region.placeholder")).nonempty(t("workflow_node.deploy.form.aliyun_cas_region.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCASDeployConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCASDeployConfig.tsx index d7e961ae..f16a0c79 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCASDeployConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCASDeployConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Alert, Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import MultipleSplitValueInput from "@/components/MultipleSplitValueInput"; @@ -36,16 +36,16 @@ const DeployNodeConfigFormAliyunCASDeployConfig = ({ const formSchema = z.object({ region: z - .string({ message: t("workflow_node.deploy.form.aliyun_cas_deploy_region.placeholder") }) + .string(t("workflow_node.deploy.form.aliyun_cas_deploy_region.placeholder")) .nonempty(t("workflow_node.deploy.form.aliyun_cas_deploy_region.placeholder")), - resourceIds: z.string({ message: t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.placeholder") }).refine((v) => { + resourceIds: z.string(t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.placeholder")).refine((v) => { if (!v) return false; return String(v) .split(MULTIPLE_INPUT_SEPARATOR) .every((e) => /^[1-9]\d*$/.test(e)); }, t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.errmsg.invalid")), contactIds: z - .string({ message: t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.placeholder") }) + .string(t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.placeholder")) .nullish() .refine((v) => { if (!v) return true; diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCDNConfig.tsx index 5efffd9f..ab9d7ec0 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,7 +32,7 @@ const DeployNodeConfigFormAliyunCDNConfig = ({ const formSchema = z.object({ domain: z - .string({ message: t("workflow_node.deploy.form.aliyun_cdn_domain.placeholder") }) + .string(t("workflow_node.deploy.form.aliyun_cdn_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCLBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCLBConfig.tsx index 43e843ad..c14fda82 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCLBConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCLBConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; import { validDomainName, validPortNumber } from "@/utils/validators"; @@ -42,14 +42,10 @@ const DeployNodeConfigFormAliyunCLBConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - resourceType: z.union([z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { - message: t("workflow_node.deploy.form.aliyun_clb_resource_type.placeholder"), - }), - region: z - .string({ message: t("workflow_node.deploy.form.aliyun_clb_region.placeholder") }) - .nonempty(t("workflow_node.deploy.form.aliyun_clb_region.placeholder")), + resourceType: z.literal([RESOURCE_TYPE_LOADBALANCER, RESOURCE_TYPE_LISTENER], t("workflow_node.deploy.form.aliyun_clb_resource_type.placeholder")), + region: z.string(t("workflow_node.deploy.form.aliyun_clb_region.placeholder")).nonempty(t("workflow_node.deploy.form.aliyun_clb_region.placeholder")), loadbalancerId: z - .string({ message: t("workflow_node.deploy.form.aliyun_clb_loadbalancer_id.placeholder") }) + .string(t("workflow_node.deploy.form.aliyun_clb_loadbalancer_id.placeholder")) .min(1, t("workflow_node.deploy.form.aliyun_clb_loadbalancer_id.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), listenerPort: z.preprocess( diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunDCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunDCDNConfig.tsx index 836bdca0..3ee69105 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunDCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunDCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,7 +32,7 @@ const DeployNodeConfigFormAliyunDCDNConfig = ({ const formSchema = z.object({ domain: z - .string({ message: t("workflow_node.deploy.form.aliyun_dcdn_domain.placeholder") }) + .string(t("workflow_node.deploy.form.aliyun_dcdn_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunDDoSConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunDDoSConfig.tsx index 6081e0af..3ba56397 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunDDoSConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunDDoSConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,11 +32,9 @@ const DeployNodeConfigFormAliyunDDoSConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - region: z - .string({ message: t("workflow_node.deploy.form.aliyun_ddos_region.placeholder") }) - .nonempty(t("workflow_node.deploy.form.aliyun_ddos_region.placeholder")), + region: z.string(t("workflow_node.deploy.form.aliyun_ddos_region.placeholder")).nonempty(t("workflow_node.deploy.form.aliyun_ddos_region.placeholder")), domain: z - .string({ message: t("workflow_node.deploy.form.aliyun_ddos_domain.placeholder") }) + .string(t("workflow_node.deploy.form.aliyun_ddos_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunESAConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunESAConfig.tsx index 91c34b08..484fc48c 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunESAConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunESAConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormAliyunESAConfigFieldValues = Nullish<{ region: string; @@ -30,10 +30,8 @@ const DeployNodeConfigFormAliyunESAConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - region: z - .string({ message: t("workflow_node.deploy.form.aliyun_esa_region.placeholder") }) - .nonempty(t("workflow_node.deploy.form.aliyun_esa_region.placeholder")), - siteId: z.union([z.string(), z.number()]).refine((v) => { + region: z.string(t("workflow_node.deploy.form.aliyun_esa_region.placeholder")).nonempty(t("workflow_node.deploy.form.aliyun_esa_region.placeholder")), + siteId: z.union([z.string(), z.number().int()]).refine((v) => { return /^\d+$/.test(v + "") && +v > 0; }, t("workflow_node.deploy.form.aliyun_esa_site_id.placeholder")), }); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunFCConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunFCConfig.tsx index c20dc15a..69fbffe3 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunFCConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunFCConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -29,14 +29,10 @@ const DeployNodeConfigFormAliyunFCConfig = ({ form: formInst, formName, disabled const { t } = useTranslation(); const formSchema = z.object({ - serviceVersion: z.union([z.literal("2.0"), z.literal("3.0")], { - message: t("workflow_node.deploy.form.aliyun_fc_service_version.placeholder"), - }), - region: z - .string({ message: t("workflow_node.deploy.form.aliyun_fc_region.placeholder") }) - .nonempty(t("workflow_node.deploy.form.aliyun_fc_region.placeholder")), + serviceVersion: z.literal(["2.0", "3.0"], t("workflow_node.deploy.form.aliyun_fc_service_version.placeholder")), + region: z.string(t("workflow_node.deploy.form.aliyun_fc_region.placeholder")).nonempty(t("workflow_node.deploy.form.aliyun_fc_region.placeholder")), domain: z - .string({ message: t("workflow_node.deploy.form.aliyun_fc_domain.placeholder") }) + .string(t("workflow_node.deploy.form.aliyun_fc_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunGAConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunGAConfig.tsx index 39991869..072567ae 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunGAConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunGAConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; import { validDomainName } from "@/utils/validators"; @@ -34,9 +34,7 @@ const DeployNodeConfigFormAliyunGAConfig = ({ form: formInst, formName, disabled const { t } = useTranslation(); const formSchema = z.object({ - resourceType: z.union([z.literal(RESOURCE_TYPE_ACCELERATOR), z.literal(RESOURCE_TYPE_LISTENER)], { - message: t("workflow_node.deploy.form.aliyun_ga_resource_type.placeholder"), - }), + resourceType: z.literal([RESOURCE_TYPE_ACCELERATOR, RESOURCE_TYPE_LISTENER], t("workflow_node.deploy.form.aliyun_ga_resource_type.placeholder")), acceleratorId: z.string().max(64, t("common.errmsg.string_max", { max: 64 })), listenerId: z .string() diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunLiveConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunLiveConfig.tsx index 569b1469..e2e88b5c 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunLiveConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunLiveConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,11 +32,9 @@ const DeployNodeConfigFormAliyunLiveConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - region: z - .string({ message: t("workflow_node.deploy.form.aliyun_live_region.placeholder") }) - .nonempty(t("workflow_node.deploy.form.aliyun_live_region.placeholder")), + region: z.string(t("workflow_node.deploy.form.aliyun_live_region.placeholder")).nonempty(t("workflow_node.deploy.form.aliyun_live_region.placeholder")), domain: z - .string({ message: t("workflow_node.deploy.form.aliyun_live_domain.placeholder") }) + .string(t("workflow_node.deploy.form.aliyun_live_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunNLBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunNLBConfig.tsx index 25bd93a9..b6fe7af0 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunNLBConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunNLBConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; @@ -39,12 +39,8 @@ const DeployNodeConfigFormAliyunNLBConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - region: z - .string({ message: t("workflow_node.deploy.form.aliyun_nlb_region.placeholder") }) - .nonempty(t("workflow_node.deploy.form.aliyun_nlb_region.placeholder")), - resourceType: z.union([z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { - message: t("workflow_node.deploy.form.aliyun_nlb_resource_type.placeholder"), - }), + region: z.string(t("workflow_node.deploy.form.aliyun_nlb_region.placeholder")).nonempty(t("workflow_node.deploy.form.aliyun_nlb_region.placeholder")), + resourceType: z.literal([RESOURCE_TYPE_LOADBALANCER, RESOURCE_TYPE_LISTENER], t("workflow_node.deploy.form.aliyun_nlb_resource_type.placeholder")), loadbalancerId: z .string() .max(64, t("common.errmsg.string_max", { max: 64 })) diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunOSSConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunOSSConfig.tsx index 5aefa851..6468b671 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunOSSConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunOSSConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -33,14 +33,10 @@ const DeployNodeConfigFormAliyunOSSConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - region: z - .string({ message: t("workflow_node.deploy.form.aliyun_oss_region.placeholder") }) - .nonempty(t("workflow_node.deploy.form.aliyun_oss_region.placeholder")), - bucket: z - .string({ message: t("workflow_node.deploy.form.aliyun_oss_bucket.placeholder") }) - .nonempty(t("workflow_node.deploy.form.aliyun_oss_bucket.placeholder")), + region: z.string(t("workflow_node.deploy.form.aliyun_oss_region.placeholder")).nonempty(t("workflow_node.deploy.form.aliyun_oss_region.placeholder")), + bucket: z.string(t("workflow_node.deploy.form.aliyun_oss_bucket.placeholder")).nonempty(t("workflow_node.deploy.form.aliyun_oss_bucket.placeholder")), domain: z - .string({ message: t("workflow_node.deploy.form.aliyun_oss_domain.placeholder") }) + .string(t("workflow_node.deploy.form.aliyun_oss_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunVODConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunVODConfig.tsx index 752d28cd..ab70eb9c 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunVODConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunVODConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,12 +32,8 @@ const DeployNodeConfigFormAliyunVODConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - region: z - .string({ message: t("workflow_node.deploy.form.aliyun_vod_region.placeholder") }) - .nonempty(t("workflow_node.deploy.form.aliyun_vod_region.placeholder")), - domain: z - .string({ message: t("workflow_node.deploy.form.aliyun_vod_domain.placeholder") }) - .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + region: z.string(t("workflow_node.deploy.form.aliyun_vod_region.placeholder")).nonempty(t("workflow_node.deploy.form.aliyun_vod_region.placeholder")), + domain: z.string(t("workflow_node.deploy.form.aliyun_vod_domain.placeholder")).refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunWAFConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunWAFConfig.tsx index f7044063..58681fa3 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunWAFConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunWAFConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -36,14 +36,10 @@ const DeployNodeConfigFormAliyunWAFConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - region: z - .string({ message: t("workflow_node.deploy.form.aliyun_waf_region.placeholder") }) - .nonempty(t("workflow_node.deploy.form.aliyun_waf_region.placeholder")), - serviceVersion: z.literal("3.0", { - message: t("workflow_node.deploy.form.aliyun_waf_service_version.placeholder"), - }), + region: z.string(t("workflow_node.deploy.form.aliyun_waf_region.placeholder")).nonempty(t("workflow_node.deploy.form.aliyun_waf_region.placeholder")), + serviceVersion: z.literal("3.0", t("workflow_node.deploy.form.aliyun_waf_service_version.placeholder")), instanceId: z - .string({ message: t("workflow_node.deploy.form.aliyun_waf_instance_id.placeholder") }) + .string(t("workflow_node.deploy.form.aliyun_waf_instance_id.placeholder")) .nonempty(t("workflow_node.deploy.form.aliyun_waf_instance_id.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), domain: z diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAzureKeyVaultConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAzureKeyVaultConfig.tsx index 952d3e23..1fab432b 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAzureKeyVaultConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAzureKeyVaultConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormAzureKeyVaultConfigFieldValues = Nullish<{ keyvaultName: string; @@ -31,7 +31,7 @@ const DeployNodeConfigFormAzureKeyVaultConfig = ({ const formSchema = z.object({ keyvaultName: z - .string({ message: t("workflow_node.deploy.form.azure_keyvault_name.placeholder") }) + .string(t("workflow_node.deploy.form.azure_keyvault_name.placeholder")) .nonempty(t("workflow_node.deploy.form.azure_keyvault_name.placeholder")), certificateName: z .string() diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudAppBLBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudAppBLBConfig.tsx index 0f9f45b7..894409a1 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudAppBLBConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudAppBLBConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; import { validDomainName, validPortNumber } from "@/utils/validators"; @@ -43,13 +43,11 @@ const DeployNodeConfigFormBaiduCloudAppBLBConfig = ({ const formSchema = z.object({ region: z - .string({ message: t("workflow_node.deploy.form.baiducloud_appblb_region.placeholder") }) + .string(t("workflow_node.deploy.form.baiducloud_appblb_region.placeholder")) .nonempty(t("workflow_node.deploy.form.baiducloud_appblb_region.placeholder")), - resourceType: z.union([z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { - message: t("workflow_node.deploy.form.baiducloud_appblb_resource_type.placeholder"), - }), + resourceType: z.literal([RESOURCE_TYPE_LOADBALANCER, RESOURCE_TYPE_LISTENER], t("workflow_node.deploy.form.baiducloud_appblb_resource_type.placeholder")), loadbalancerId: z - .string({ message: t("workflow_node.deploy.form.baiducloud_appblb_loadbalancer_id.placeholder") }) + .string(t("workflow_node.deploy.form.baiducloud_appblb_loadbalancer_id.placeholder")) .min(1, t("workflow_node.deploy.form.baiducloud_appblb_loadbalancer_id.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), listenerPort: z.preprocess( diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudBLBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudBLBConfig.tsx index c0a1593a..5f40e69d 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudBLBConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudBLBConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; import { validDomainName, validPortNumber } from "@/utils/validators"; @@ -43,13 +43,11 @@ const DeployNodeConfigFormBaiduCloudBLBConfig = ({ const formSchema = z.object({ region: z - .string({ message: t("workflow_node.deploy.form.baiducloud_blb_region.placeholder") }) + .string(t("workflow_node.deploy.form.baiducloud_blb_region.placeholder")) .nonempty(t("workflow_node.deploy.form.baiducloud_blb_region.placeholder")), - resourceType: z.union([z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { - message: t("workflow_node.deploy.form.baiducloud_blb_resource_type.placeholder"), - }), + resourceType: z.literal([RESOURCE_TYPE_LOADBALANCER, RESOURCE_TYPE_LISTENER], t("workflow_node.deploy.form.baiducloud_blb_resource_type.placeholder")), loadbalancerId: z - .string({ message: t("workflow_node.deploy.form.baiducloud_blb_loadbalancer_id.placeholder") }) + .string(t("workflow_node.deploy.form.baiducloud_blb_loadbalancer_id.placeholder")) .min(1, t("workflow_node.deploy.form.baiducloud_blb_loadbalancer_id.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), listenerPort: z.preprocess( diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudCDNConfig.tsx index 3302e0e9..c17511e5 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,7 +32,7 @@ const DeployNodeConfigFormBaiduCloudCDNConfig = ({ const formSchema = z.object({ domain: z - .string({ message: t("workflow_node.deploy.form.baiducloud_cdn_domain.placeholder") }) + .string(t("workflow_node.deploy.form.baiducloud_cdn_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormBaishanCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormBaishanCDNConfig.tsx index 7d32bef5..b4346213 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormBaishanCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormBaishanCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -33,7 +33,7 @@ const DeployNodeConfigFormBaishanCDNConfig = ({ const formSchema = z.object({ domain: z - .string({ message: t("workflow_node.deploy.form.baishan_cdn_domain.placeholder") }) + .string(t("workflow_node.deploy.form.baishan_cdn_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), certificateId: z .union([z.string(), z.number().int()]) diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormBaotaPanelConsoleConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormBaotaPanelConsoleConfig.tsx index ca440a27..fd6701e6 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormBaotaPanelConsoleConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormBaotaPanelConsoleConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormBaotaPanelConsoleConfigFieldValues = Nullish<{ autoRestart?: boolean; diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormBaotaPanelSiteConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormBaotaPanelSiteConfig.tsx index 079e4190..640e420f 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormBaotaPanelSiteConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormBaotaPanelSiteConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import MultipleSplitValueInput from "@/components/MultipleSplitValueInput"; import Show from "@/components/Show"; @@ -43,9 +43,7 @@ const DeployNodeConfigFormBaotaPanelSiteConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - siteType: z.union([z.literal(SITE_TYPE_PHP), z.literal(SITE_TYPE_OTHER)], { - message: t("workflow_node.deploy.form.baotapanel_site_type.placeholder"), - }), + siteType: z.literal([SITE_TYPE_PHP, SITE_TYPE_OTHER], t("workflow_node.deploy.form.baotapanel_site_type.placeholder")), siteName: z .string() .nullish() diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormBaotaWAFSiteConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormBaotaWAFSiteConfig.tsx index 7c0ae293..f50bb380 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormBaotaWAFSiteConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormBaotaWAFSiteConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, InputNumber } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validPortNumber } from "@/utils/validators"; diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormBunnyCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormBunnyCDNConfig.tsx index d6a42f3b..b52d3c22 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormBunnyCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormBunnyCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; type DeployNodeConfigFormBunnyCDNConfigFieldValues = Nullish<{ @@ -29,7 +29,7 @@ const DeployNodeConfigFormBunnyCDNConfig = ({ form: formInst, formName, disabled return /^\d+$/.test(v + "") && +v! > 0; }, t("workflow_node.deploy.form.bunny_cdn_pull_zone_id.placeholder")), hostname: z - .string({ message: t("workflow_node.deploy.form.bunny_cdn_hostname.placeholder") }) + .string(t("workflow_node.deploy.form.bunny_cdn_hostname.placeholder")) .nonempty(t("workflow_node.deploy.form.bunny_cdn_hostname.placeholder")) .refine((v) => { return validDomainName(v!, { allowWildcard: true }); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormBytePlusCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormBytePlusCDNConfig.tsx index 4cd93415..6ac7a953 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormBytePlusCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormBytePlusCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,7 +32,7 @@ const DeployNodeConfigFormBytePlusCDNConfig = ({ const formSchema = z.object({ domain: z - .string({ message: t("workflow_node.deploy.form.byteplus_cdn_domain.placeholder") }) + .string(t("workflow_node.deploy.form.byteplus_cdn_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudAOConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudAOConfig.tsx index f46934cd..3f2d6441 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudAOConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudAOConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,7 +32,7 @@ const DeployNodeConfigFormCTCCCloudAOConfig = ({ const formSchema = z.object({ domain: z - .string({ message: t("workflow_node.deploy.form.ctcccloud_ao_domain.placeholder") }) + .string(t("workflow_node.deploy.form.ctcccloud_ao_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudCDNConfig.tsx index b7f564e5..25df0b0f 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,7 +32,7 @@ const DeployNodeConfigFormCTCCCloudCDNConfig = ({ const formSchema = z.object({ domain: z - .string({ message: t("workflow_node.deploy.form.ctcccloud_cdn_domain.placeholder") }) + .string(t("workflow_node.deploy.form.ctcccloud_cdn_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudELBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudELBConfig.tsx index 02413ea9..2b969261 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudELBConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudELBConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; @@ -40,11 +40,9 @@ const DeployNodeConfigFormCTCCCloudELBConfig = ({ const formSchema = z.object({ regionId: z - .string({ message: t("workflow_node.deploy.form.ctcccloud_elb_region_id.placeholder") }) + .string(t("workflow_node.deploy.form.ctcccloud_elb_region_id.placeholder")) .nonempty(t("workflow_node.deploy.form.ctcccloud_elb_region_id.placeholder")), - resourceType: z.union([z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { - message: t("workflow_node.deploy.form.ctcccloud_elb_resource_type.placeholder"), - }), + resourceType: z.literal([RESOURCE_TYPE_LOADBALANCER, RESOURCE_TYPE_LISTENER], t("workflow_node.deploy.form.ctcccloud_elb_resource_type.placeholder")), loadbalancerId: z .string() .max(64, t("common.errmsg.string_max", { max: 64 })) diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudICDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudICDNConfig.tsx index 0e94650b..350b6fe5 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudICDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudICDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,7 +32,7 @@ const DeployNodeConfigFormCTCCCloudICDNConfig = ({ const formSchema = z.object({ domain: z - .string({ message: t("workflow_node.deploy.form.ctcccloud_icdn_domain.placeholder") }) + .string(t("workflow_node.deploy.form.ctcccloud_icdn_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudLVDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudLVDNConfig.tsx index 54f22907..0fc427f1 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudLVDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormCTCCCloudLVDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -31,9 +31,7 @@ const DeployNodeConfigFormCTCCCloudLVDNConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - domain: z - .string({ message: t("workflow_node.deploy.form.ctcccloud_lvdn_domain.placeholder") }) - .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + domain: z.string(t("workflow_node.deploy.form.ctcccloud_lvdn_domain.placeholder")).refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormCdnflyConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormCdnflyConfig.tsx index 4d6ae25c..8aa77a93 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormCdnflyConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormCdnflyConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; @@ -32,9 +32,7 @@ const DeployNodeConfigFormCdnflyConfig = ({ form: formInst, formName, disabled, const { t } = useTranslation(); const formSchema = z.object({ - resourceType: z.union([z.literal(RESOURCE_TYPE_SITE), z.literal(RESOURCE_TYPE_CERTIFICATE)], { - message: t("workflow_node.deploy.form.cdnfly_resource_type.placeholder"), - }), + resourceType: z.literal([RESOURCE_TYPE_SITE, RESOURCE_TYPE_CERTIFICATE], t("workflow_node.deploy.form.cdnfly_resource_type.placeholder")), siteId: z .union([z.string(), z.number().int()]) .nullish() diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormDogeCloudCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormDogeCloudCDNConfig.tsx index ebe832bc..2be2b7ab 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormDogeCloudCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormDogeCloudCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -31,9 +31,7 @@ const DeployNodeConfigFormDogeCloudCDNConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - domain: z - .string({ message: t("workflow_node.deploy.form.dogecloud_cdn_domain.placeholder") }) - .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + domain: z.string(t("workflow_node.deploy.form.dogecloud_cdn_domain.placeholder")).refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormEdgioApplicationsConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormEdgioApplicationsConfig.tsx index 599e4ec4..bac348c8 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormEdgioApplicationsConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormEdgioApplicationsConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormEdgioApplicationsConfigFieldValues = Nullish<{ environmentId: string; @@ -30,7 +30,7 @@ const DeployNodeConfigFormEdgioApplicationsConfig = ({ const formSchema = z.object({ environmentId: z - .string({ message: t("workflow_node.deploy.form.edgio_applications_environment_id.placeholder") }) + .string(t("workflow_node.deploy.form.edgio_applications_environment_id.placeholder")) .min(1, t("workflow_node.deploy.form.edgio_applications_environment_id.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormFlexCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormFlexCDNConfig.tsx index e24652be..b44fefe2 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormFlexCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormFlexCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; @@ -31,9 +31,7 @@ const DeployNodeConfigFormFlexCDNConfig = ({ form: formInst, formName, disabled, const { t } = useTranslation(); const formSchema = z.object({ - resourceType: z.literal(RESOURCE_TYPE_CERTIFICATE, { - message: t("workflow_node.deploy.form.flexcdn_resource_type.placeholder"), - }), + resourceType: z.literal(RESOURCE_TYPE_CERTIFICATE, t("workflow_node.deploy.form.flexcdn_resource_type.placeholder")), certificateId: z .union([z.string(), z.number().int()]) .nullish() diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormGcoreCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormGcoreCDNConfig.tsx index f21a4bb9..1939a0b9 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormGcoreCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormGcoreCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormGcoreCDNConfigFieldValues = Nullish<{ resourceId: string | number; @@ -26,7 +26,7 @@ const DeployNodeConfigFormGcoreCDNConfig = ({ form: formInst, formName, disabled const { t } = useTranslation(); const formSchema = z.object({ - resourceId: z.union([z.string(), z.number()]).refine((v) => { + resourceId: z.union([z.string(), z.number().int()]).refine((v) => { return /^\d+$/.test(v + "") && +v > 0; }, t("workflow_node.deploy.form.gcore_cdn_resource_id.placeholder")), certificateId: z diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormGoEdgeConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormGoEdgeConfig.tsx index 5e0f7f85..5288f64d 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormGoEdgeConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormGoEdgeConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; @@ -31,9 +31,7 @@ const DeployNodeConfigFormGoEdgeConfig = ({ form: formInst, formName, disabled, const { t } = useTranslation(); const formSchema = z.object({ - resourceType: z.literal(RESOURCE_TYPE_CERTIFICATE, { - message: t("workflow_node.deploy.form.goedge_resource_type.placeholder"), - }), + resourceType: z.literal(RESOURCE_TYPE_CERTIFICATE, t("workflow_node.deploy.form.goedge_resource_type.placeholder")), certificateId: z .union([z.string(), z.number().int()]) .nullish() diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudCDNConfig.tsx index 93d0a300..9bdab801 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -33,11 +33,9 @@ const DeployNodeConfigFormHuaweiCloudCDNConfig = ({ const formSchema = z.object({ region: z - .string({ message: t("workflow_node.deploy.form.huaweicloud_cdn_region.placeholder") }) + .string(t("workflow_node.deploy.form.huaweicloud_cdn_region.placeholder")) .nonempty(t("workflow_node.deploy.form.huaweicloud_cdn_region.placeholder")), - domain: z - .string({ message: t("workflow_node.deploy.form.huaweicloud_cdn_domain.placeholder") }) - .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + domain: z.string(t("workflow_node.deploy.form.huaweicloud_cdn_domain.placeholder")).refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudELBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudELBConfig.tsx index bc0d4f58..caf8694b 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudELBConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudELBConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; @@ -42,11 +42,12 @@ const DeployNodeConfigFormHuaweiCloudELBConfig = ({ const formSchema = z.object({ region: z - .string({ message: t("workflow_node.deploy.form.huaweicloud_elb_region.placeholder") }) + .string(t("workflow_node.deploy.form.huaweicloud_elb_region.placeholder")) .nonempty(t("workflow_node.deploy.form.huaweicloud_elb_region.placeholder")), - resourceType: z.union([z.literal(RESOURCE_TYPE_CERTIFICATE), z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { - message: t("workflow_node.deploy.form.huaweicloud_elb_resource_type.placeholder"), - }), + resourceType: z.literal( + [RESOURCE_TYPE_CERTIFICATE, RESOURCE_TYPE_LOADBALANCER, RESOURCE_TYPE_LISTENER], + t("workflow_node.deploy.form.huaweicloud_elb_resource_type.placeholder") + ), certificateId: z .string() .max(64, t("common.errmsg.string_max", { max: 64 })) diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudWAFConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudWAFConfig.tsx index 1ef64837..fb62480a 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudWAFConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudWAFConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; import { validDomainName } from "@/utils/validators"; @@ -41,11 +41,12 @@ const DeployNodeConfigFormHuaweiCloudWAFConfig = ({ const formSchema = z.object({ region: z - .string({ message: t("workflow_node.deploy.form.huaweicloud_waf_region.placeholder") }) + .string(t("workflow_node.deploy.form.huaweicloud_waf_region.placeholder")) .nonempty(t("workflow_node.deploy.form.huaweicloud_waf_region.placeholder")), - resourceType: z.union([z.literal(RESOURCE_TYPE_CERTIFICATE), z.literal(RESOURCE_TYPE_CLOUDSERVER), z.literal(RESOURCE_TYPE_PREMIUMHOST)], { - message: t("workflow_node.deploy.form.huaweicloud_waf_resource_type.placeholder"), - }), + resourceType: z.literal( + [RESOURCE_TYPE_CERTIFICATE, RESOURCE_TYPE_CLOUDSERVER, RESOURCE_TYPE_PREMIUMHOST], + t("workflow_node.deploy.form.huaweicloud_waf_resource_type.placeholder") + ), certificateId: z .string() .max(64, t("common.errmsg.string_max", { max: 64 })) diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudALBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudALBConfig.tsx index 5a1365e1..f6ed2e7f 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudALBConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudALBConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; import { validDomainName } from "@/utils/validators"; @@ -42,11 +42,9 @@ const DeployNodeConfigFormJDCloudALBConfig = ({ const formSchema = z.object({ regionId: z - .string({ message: t("workflow_node.deploy.form.jdcloud_alb_region_id.placeholder") }) + .string(t("workflow_node.deploy.form.jdcloud_alb_region_id.placeholder")) .nonempty(t("workflow_node.deploy.form.jdcloud_alb_region_id.placeholder")), - resourceType: z.union([z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { - message: t("workflow_node.deploy.form.jdcloud_alb_resource_type.placeholder"), - }), + resourceType: z.literal([RESOURCE_TYPE_LOADBALANCER, RESOURCE_TYPE_LISTENER], t("workflow_node.deploy.form.jdcloud_alb_resource_type.placeholder")), loadbalancerId: z .string() .max(64, t("common.errmsg.string_max", { max: 64 })) diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudCDNConfig.tsx index 9d8af17e..ed5c4b88 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,7 +32,7 @@ const DeployNodeConfigFormJDCloudCDNConfig = ({ const formSchema = z.object({ domain: z - .string({ message: t("workflow_node.deploy.form.jdcloud_cdn_domain.placeholder") }) + .string(t("workflow_node.deploy.form.jdcloud_cdn_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudLiveConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudLiveConfig.tsx index 5e13f5eb..44310413 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudLiveConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudLiveConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -31,9 +31,7 @@ const DeployNodeConfigFormJDCloudLiveConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - domain: z - .string({ message: t("workflow_node.deploy.form.jdcloud_live_domain.placeholder") }) - .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + domain: z.string(t("workflow_node.deploy.form.jdcloud_live_domain.placeholder")).refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudVODConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudVODConfig.tsx index ad64a735..481a75a2 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudVODConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudVODConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -31,9 +31,7 @@ const DeployNodeConfigFormJDCloudVODConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - domain: z - .string({ message: t("workflow_node.deploy.form.jdcloud_vod_domain.placeholder") }) - .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + domain: z.string(t("workflow_node.deploy.form.jdcloud_vod_domain.placeholder")).refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormKubernetesSecretConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormKubernetesSecretConfig.tsx index fcd67072..fa16c828 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormKubernetesSecretConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormKubernetesSecretConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormKubernetesSecretConfigFieldValues = Nullish<{ namespace: string; @@ -39,23 +39,23 @@ const DeployNodeConfigFormKubernetesSecretConfig = ({ const formSchema = z.object({ namespace: z - .string({ message: t("workflow_node.deploy.form.k8s_namespace.placeholder") }) + .string(t("workflow_node.deploy.form.k8s_namespace.placeholder")) .nonempty(t("workflow_node.deploy.form.k8s_namespace.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), secretName: z - .string({ message: t("workflow_node.deploy.form.k8s_secret_name.placeholder") }) + .string(t("workflow_node.deploy.form.k8s_secret_name.placeholder")) .nonempty(t("workflow_node.deploy.form.k8s_secret_name.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), secretType: z - .string({ message: t("workflow_node.deploy.form.k8s_secret_type.placeholder") }) + .string(t("workflow_node.deploy.form.k8s_secret_type.placeholder")) .nonempty(t("workflow_node.deploy.form.k8s_secret_type.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), secretDataKeyForCrt: z - .string({ message: t("workflow_node.deploy.form.k8s_secret_data_key_for_crt.placeholder") }) + .string(t("workflow_node.deploy.form.k8s_secret_data_key_for_crt.placeholder")) .nonempty(t("workflow_node.deploy.form.k8s_secret_data_key_for_crt.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), secretDataKeyForKey: z - .string({ message: t("workflow_node.deploy.form.k8s_secret_data_key_for_key.placeholder") }) + .string(t("workflow_node.deploy.form.k8s_secret_data_key_for_key.placeholder")) .nonempty(t("workflow_node.deploy.form.k8s_secret_data_key_for_key.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), }); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormLeCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormLeCDNConfig.tsx index 0636cedf..b1d769cc 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormLeCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormLeCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; @@ -33,9 +33,7 @@ const DeployNodeConfigFormLeCDNConfig = ({ form: formInst, formName, disabled, i const { t } = useTranslation(); const formSchema = z.object({ - resourceType: z.literal(RESOURCE_TYPE_CERTIFICATE, { - message: t("workflow_node.deploy.form.lecdn_resource_type.placeholder"), - }), + resourceType: z.literal(RESOURCE_TYPE_CERTIFICATE, t("workflow_node.deploy.form.lecdn_resource_type.placeholder")), certificateId: z .union([z.string(), z.number().int()]) .nullish() diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormLocalConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormLocalConfig.tsx index 36d22a08..eddeb981 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormLocalConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormLocalConfig.tsx @@ -2,7 +2,7 @@ import { useTranslation } from "react-i18next"; import { DownOutlined as DownOutlinedIcon } from "@ant-design/icons"; import { Alert, Button, Dropdown, Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import CodeInput from "@/components/CodeInput"; import Show from "@/components/Show"; @@ -160,9 +160,7 @@ const DeployNodeConfigFormLocalConfig = ({ form: formInst, formName, disabled, i const { t } = useTranslation(); const formSchema = z.object({ - format: z.union([z.literal(FORMAT_PEM), z.literal(FORMAT_PFX), z.literal(FORMAT_JKS)], { - message: t("workflow_node.deploy.form.local_format.placeholder"), - }), + format: z.literal([FORMAT_PEM, FORMAT_PFX, FORMAT_JKS], t("workflow_node.deploy.form.local_format.placeholder")), certPath: z .string() .min(1, t("workflow_node.deploy.form.local_cert_path.tooltip")) @@ -179,30 +177,28 @@ const DeployNodeConfigFormLocalConfig = ({ form: formInst, formName, disabled, i .string() .max(256, t("common.errmsg.string_max", { max: 256 })) .nullish() - .refine((v) => fieldFormat !== FORMAT_PEM || !!v?.trim(), { message: t("workflow_node.deploy.form.local_key_path.tooltip") }), + .refine((v) => fieldFormat !== FORMAT_PEM || !!v?.trim(), t("workflow_node.deploy.form.local_key_path.tooltip")), pfxPassword: z .string() .max(64, t("common.errmsg.string_max", { max: 256 })) .nullish() - .refine((v) => fieldFormat !== FORMAT_PFX || !!v?.trim(), { message: t("workflow_node.deploy.form.local_pfx_password.tooltip") }), + .refine((v) => fieldFormat !== FORMAT_PFX || !!v?.trim(), t("workflow_node.deploy.form.local_pfx_password.tooltip")), jksAlias: z .string() .max(64, t("common.errmsg.string_max", { max: 256 })) .nullish() - .refine((v) => fieldFormat !== FORMAT_JKS || !!v?.trim(), { message: t("workflow_node.deploy.form.local_jks_alias.tooltip") }), + .refine((v) => fieldFormat !== FORMAT_JKS || !!v?.trim(), t("workflow_node.deploy.form.local_jks_alias.tooltip")), jksKeypass: z .string() .max(64, t("common.errmsg.string_max", { max: 256 })) .nullish() - .refine((v) => fieldFormat !== FORMAT_JKS || !!v?.trim(), { message: t("workflow_node.deploy.form.local_jks_keypass.tooltip") }), + .refine((v) => fieldFormat !== FORMAT_JKS || !!v?.trim(), t("workflow_node.deploy.form.local_jks_keypass.tooltip")), jksStorepass: z .string() .max(64, t("common.errmsg.string_max", { max: 256 })) .nullish() - .refine((v) => fieldFormat !== FORMAT_JKS || !!v?.trim(), { message: t("workflow_node.deploy.form.local_jks_storepass.tooltip") }), - shellEnv: z.union([z.literal(SHELLENV_SH), z.literal(SHELLENV_CMD), z.literal(SHELLENV_POWERSHELL)], { - message: t("workflow_node.deploy.form.local_shell_env.placeholder"), - }), + .refine((v) => fieldFormat !== FORMAT_JKS || !!v?.trim(), t("workflow_node.deploy.form.local_jks_storepass.tooltip")), + shellEnv: z.literal([SHELLENV_SH, SHELLENV_CMD, SHELLENV_POWERSHELL], t("workflow_node.deploy.form.local_shell_env.placeholder")), preCommand: z .string() .max(20480, t("common.errmsg.string_max", { max: 20480 })) diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormNetlifySiteConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormNetlifySiteConfig.tsx index ffa38fae..1a6a29c4 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormNetlifySiteConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormNetlifySiteConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormNetlifySiteConfigFieldValues = Nullish<{ siteId: string; diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormProxmoxVEConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormProxmoxVEConfig.tsx index 444b1082..4e761a47 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormProxmoxVEConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormProxmoxVEConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormProxmoxVEConfigFieldValues = Nullish<{ nodeName: string; @@ -32,9 +32,7 @@ const DeployNodeConfigFormProxmoxVEConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - nodeName: z - .string({ message: t("workflow_node.deploy.form.proxmoxve_node_name.placeholder") }) - .nonempty(t("workflow_node.deploy.form.proxmoxve_node_name.placeholder")), + nodeName: z.string(t("workflow_node.deploy.form.proxmoxve_node_name.placeholder")).nonempty(t("workflow_node.deploy.form.proxmoxve_node_name.placeholder")), autoRestart: z.boolean().nullish(), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormQiniuCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormQiniuCDNConfig.tsx index b2c4075f..08c613c3 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormQiniuCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormQiniuCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -26,7 +26,7 @@ const DeployNodeConfigFormQiniuCDNConfig = ({ form: formInst, formName, disabled const formSchema = z.object({ domain: z - .string({ message: t("workflow_node.deploy.form.qiniu_cdn_domain.placeholder") }) + .string(t("workflow_node.deploy.form.qiniu_cdn_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormQiniuKodoConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormQiniuKodoConfig.tsx index e7a7dfb7..56822a69 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormQiniuKodoConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormQiniuKodoConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -31,9 +31,7 @@ const DeployNodeConfigFormQiniuKodoConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - domain: z - .string({ message: t("workflow_node.deploy.form.qiniu_kodo_domain.placeholder") }) - .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + domain: z.string(t("workflow_node.deploy.form.qiniu_kodo_domain.placeholder")).refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormQiniuPiliConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormQiniuPiliConfig.tsx index 2cac6de7..b54eedf0 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormQiniuPiliConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormQiniuPiliConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,9 +32,9 @@ const DeployNodeConfigFormQiniuPiliConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - hub: z.string({ message: t("workflow_node.deploy.form.qiniu_pili_hub.placeholder") }).nonempty(t("workflow_node.deploy.form.qiniu_pili_hub.placeholder")), + hub: z.string(t("workflow_node.deploy.form.qiniu_pili_hub.placeholder")).nonempty(t("workflow_node.deploy.form.qiniu_pili_hub.placeholder")), domain: z - .string({ message: t("workflow_node.deploy.form.qiniu_pili_domain.placeholder") }) + .string(t("workflow_node.deploy.form.qiniu_pili_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormRainYunRCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormRainYunRCDNConfig.tsx index b13ad5cb..06753388 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormRainYunRCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormRainYunRCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -34,11 +34,11 @@ const DeployNodeConfigFormRainYunRCDNConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - instanceId: z.union([z.string(), z.number()]).refine((v) => { + instanceId: z.union([z.string(), z.number().int()]).refine((v) => { return /^\d+$/.test(v + "") && +v > 0; }, t("workflow_node.deploy.form.rainyun_rcdn_instance_id.placeholder")), domain: z - .string({ message: t("workflow_node.deploy.form.rainyun_rcdn_domain.placeholder") }) + .string(t("workflow_node.deploy.form.rainyun_rcdn_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormRatPanelSiteConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormRatPanelSiteConfig.tsx index 03f86913..9aa2cf7e 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormRatPanelSiteConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormRatPanelSiteConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormRatPanelSiteConfigFieldValues = Nullish<{ siteName: string; diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormSSHConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormSSHConfig.tsx index 304f638e..ebeb1cff 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormSSHConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormSSHConfig.tsx @@ -2,7 +2,7 @@ import { useTranslation } from "react-i18next"; import { DownOutlined as DownOutlinedIcon } from "@ant-design/icons"; import { Button, Dropdown, Form, type FormInstance, Input, Select, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import CodeInput from "@/components/CodeInput"; import Show from "@/components/Show"; @@ -192,9 +192,7 @@ const DeployNodeConfigFormSSHConfig = ({ form: formInst, formName, disabled, ini const { t } = useTranslation(); const formSchema = z.object({ - format: z.union([z.literal(FORMAT_PEM), z.literal(FORMAT_PFX), z.literal(FORMAT_JKS)], { - message: t("workflow_node.deploy.form.ssh_format.placeholder"), - }), + format: z.literal([FORMAT_PEM, FORMAT_PFX, FORMAT_JKS], t("workflow_node.deploy.form.ssh_format.placeholder")), certPath: z .string() .min(1, t("workflow_node.deploy.form.ssh_cert_path.tooltip")) @@ -203,7 +201,7 @@ const DeployNodeConfigFormSSHConfig = ({ form: formInst, formName, disabled, ini .string() .max(256, t("common.errmsg.string_max", { max: 256 })) .nullish() - .refine((v) => fieldFormat !== FORMAT_PEM || !!v?.trim(), { message: t("workflow_node.deploy.form.ssh_key_path.tooltip") }), + .refine((v) => fieldFormat !== FORMAT_PEM || !!v?.trim(), t("workflow_node.deploy.form.ssh_key_path.tooltip")), certPathForServerOnly: z .string() .max(256, t("common.errmsg.string_max", { max: 256 })) @@ -216,22 +214,22 @@ const DeployNodeConfigFormSSHConfig = ({ form: formInst, formName, disabled, ini .string() .max(64, t("common.errmsg.string_max", { max: 256 })) .nullish() - .refine((v) => fieldFormat !== FORMAT_PFX || !!v?.trim(), { message: t("workflow_node.deploy.form.ssh_pfx_password.tooltip") }), + .refine((v) => fieldFormat !== FORMAT_PFX || !!v?.trim(), t("workflow_node.deploy.form.ssh_pfx_password.tooltip")), jksAlias: z .string() .max(64, t("common.errmsg.string_max", { max: 256 })) .nullish() - .refine((v) => fieldFormat !== FORMAT_JKS || !!v?.trim(), { message: t("workflow_node.deploy.form.ssh_jks_alias.tooltip") }), + .refine((v) => fieldFormat !== FORMAT_JKS || !!v?.trim(), t("workflow_node.deploy.form.ssh_jks_alias.tooltip")), jksKeypass: z .string() .max(64, t("common.errmsg.string_max", { max: 256 })) .nullish() - .refine((v) => fieldFormat !== FORMAT_JKS || !!v?.trim(), { message: t("workflow_node.deploy.form.ssh_jks_keypass.tooltip") }), + .refine((v) => fieldFormat !== FORMAT_JKS || !!v?.trim(), t("workflow_node.deploy.form.ssh_jks_keypass.tooltip")), jksStorepass: z .string() .max(64, t("common.errmsg.string_max", { max: 256 })) .nullish() - .refine((v) => fieldFormat !== FORMAT_JKS || !!v?.trim(), { message: t("workflow_node.deploy.form.ssh_jks_storepass.tooltip") }), + .refine((v) => fieldFormat !== FORMAT_JKS || !!v?.trim(), t("workflow_node.deploy.form.ssh_jks_storepass.tooltip")), preCommand: z .string() .max(20480, t("common.errmsg.string_max", { max: 20480 })) diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormSafeLineConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormSafeLineConfig.tsx index c5905e14..49f350be 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormSafeLineConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormSafeLineConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; @@ -31,9 +31,7 @@ const DeployNodeConfigFormSafeLineConfig = ({ form: formInst, formName, disabled const { t } = useTranslation(); const formSchema = z.object({ - resourceType: z.literal(RESOURCE_TYPE_CERTIFICATE, { - message: t("workflow_node.deploy.form.safeline_resource_type.placeholder"), - }), + resourceType: z.literal(RESOURCE_TYPE_CERTIFICATE, t("workflow_node.deploy.form.safeline_resource_type.placeholder")), certificateId: z .union([z.string(), z.number().int()]) .nullish() diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCDNConfig.tsx index 5dd10dd6..bc9e938d 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -34,7 +34,7 @@ const DeployNodeConfigFormTencentCloudCDNConfig = ({ const formSchema = z.object({ endpoint: z.string().nullish(), domain: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_cdn_domain.placeholder") }) + .string(t("workflow_node.deploy.form.tencentcloud_cdn_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCLBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCLBConfig.tsx index b21f3661..fdd945e1 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCLBConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCLBConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; import { validDomainName } from "@/utils/validators"; @@ -23,10 +23,10 @@ export type DeployNodeConfigFormTencentCloudCLBConfigProps = { onValuesChange?: (values: DeployNodeConfigFormTencentCloudCLBConfigFieldValues) => void; }; -const RESOURCE_TYPE_VIA_SSLDEPLOY = "ssl-deploy" as const; const RESOURCE_TYPE_LOADBALANCER = "loadbalancer" as const; const RESOURCE_TYPE_LISTENER = "listener" as const; const RESOURCE_TYPE_RULEDOMAIN = "ruledomain" as const; +const RESOURCE_TYPE_VIA_SSLDEPLOY = "ssl-deploy" as const; const initFormModel = (): DeployNodeConfigFormTencentCloudCLBConfigFieldValues => { return { @@ -45,12 +45,12 @@ const DeployNodeConfigFormTencentCloudCLBConfig = ({ const formSchema = z.object({ endpoint: z.string().nullish(), - resourceType: z.union( - [z.literal(RESOURCE_TYPE_VIA_SSLDEPLOY), z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER), z.literal(RESOURCE_TYPE_RULEDOMAIN)], - { message: t("workflow_node.deploy.form.tencentcloud_clb_resource_type.placeholder") } + resourceType: z.literal( + [RESOURCE_TYPE_LOADBALANCER, RESOURCE_TYPE_LISTENER, RESOURCE_TYPE_RULEDOMAIN, RESOURCE_TYPE_VIA_SSLDEPLOY], + t("workflow_node.deploy.form.tencentcloud_clb_resource_type.placeholder") ), region: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_clb_region.placeholder") }) + .string(t("workflow_node.deploy.form.tencentcloud_clb_region.placeholder")) .nonempty(t("workflow_node.deploy.form.tencentcloud_clb_region.placeholder")), loadbalancerId: z .string() @@ -61,7 +61,7 @@ const DeployNodeConfigFormTencentCloudCLBConfig = ({ .max(64, t("common.errmsg.string_max", { max: 64 })) .nullish() .refine( - (v) => ![RESOURCE_TYPE_VIA_SSLDEPLOY, RESOURCE_TYPE_LISTENER, RESOURCE_TYPE_RULEDOMAIN].includes(fieldResourceType) || !!v?.trim(), + (v) => ![RESOURCE_TYPE_LISTENER, RESOURCE_TYPE_RULEDOMAIN, RESOURCE_TYPE_VIA_SSLDEPLOY].includes(fieldResourceType) || !!v?.trim(), t("workflow_node.deploy.form.tencentcloud_clb_listener_id.placeholder") ), domain: z @@ -106,9 +106,6 @@ const DeployNodeConfigFormTencentCloudCLBConfig = ({ diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCOSConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCOSConfig.tsx index 6192c9b9..5d05727c 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCOSConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCOSConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -34,14 +34,12 @@ const DeployNodeConfigFormTencentCloudCOSConfig = ({ const formSchema = z.object({ region: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_cos_region.placeholder") }) + .string(t("workflow_node.deploy.form.tencentcloud_cos_region.placeholder")) .nonempty(t("workflow_node.deploy.form.tencentcloud_cos_region.placeholder")), bucket: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_cos_bucket.placeholder") }) + .string(t("workflow_node.deploy.form.tencentcloud_cos_bucket.placeholder")) .nonempty(t("workflow_node.deploy.form.tencentcloud_cos_bucket.placeholder")), - domain: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_cos_domain.placeholder") }) - .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + domain: z.string(t("workflow_node.deploy.form.tencentcloud_cos_domain.placeholder")).refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCSSConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCSSConfig.tsx index b9de0c8d..b0118a98 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCSSConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCSSConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -34,7 +34,7 @@ const DeployNodeConfigFormTencentCloudCSSConfig = ({ const formSchema = z.object({ endpoint: z.string().nullish(), domain: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_css_domain.placeholder") }) + .string(t("workflow_node.deploy.form.tencentcloud_css_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudECDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudECDNConfig.tsx index 6484babc..034f8945 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudECDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudECDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -34,7 +34,7 @@ const DeployNodeConfigFormTencentCloudECDNConfig = ({ const formSchema = z.object({ endpoint: z.string().nullish(), domain: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_ecdn_domain.placeholder") }) + .string(t("workflow_node.deploy.form.tencentcloud_ecdn_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudEOConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudEOConfig.tsx index 7ad8c068..a69d8e38 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudEOConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudEOConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -35,10 +35,10 @@ const DeployNodeConfigFormTencentCloudEOConfig = ({ const formSchema = z.object({ endpoint: z.string().nullish(), zoneId: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_eo_zone_id.placeholder") }) + .string(t("workflow_node.deploy.form.tencentcloud_eo_zone_id.placeholder")) .nonempty(t("workflow_node.deploy.form.tencentcloud_eo_zone_id.placeholder")), domain: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_eo_domain.placeholder") }) + .string(t("workflow_node.deploy.form.tencentcloud_eo_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudGAAPConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudGAAPConfig.tsx index ff6141f2..1cac40dc 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudGAAPConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudGAAPConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; @@ -40,7 +40,7 @@ const DeployNodeConfigFormTencentCloudGAAPConfig = ({ const formSchema = z.object({ endpoint: z.string().nullish(), - resourceType: z.literal(RESOURCE_TYPE_LISTENER, { message: t("workflow_node.deploy.form.tencentcloud_gaap_resource_type.placeholder") }), + resourceType: z.literal(RESOURCE_TYPE_LISTENER, t("workflow_node.deploy.form.tencentcloud_gaap_resource_type.placeholder")), proxyId: z.string().nullish(), listenerId: z .string() diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSCFConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSCFConfig.tsx index c62f30ca..3128a41a 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSCFConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSCFConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -35,11 +35,9 @@ const DeployNodeConfigFormTencentCloudSCFConfig = ({ const formSchema = z.object({ endpoint: z.string().nullish(), region: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_scf_region.placeholder") }) + .string(t("workflow_node.deploy.form.tencentcloud_scf_region.placeholder")) .nonempty(t("workflow_node.deploy.form.tencentcloud_scf_region.placeholder")), - domain: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_scf_domain.placeholder") }) - .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + domain: z.string(t("workflow_node.deploy.form.tencentcloud_scf_domain.placeholder")).refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLConfig.tsx index c7f1f634..f079790d 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormTencentCloudSSLConfigFieldValues = Nullish<{ endpoint?: string; diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLDeployConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLDeployConfig.tsx index b003876c..37c82584 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLDeployConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLDeployConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Alert, AutoComplete, Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import MultipleSplitValueInput from "@/components/MultipleSplitValueInput"; @@ -38,12 +38,12 @@ const DeployNodeConfigFormTencentCloudSSLDeployConfig = ({ const formSchema = z.object({ endpoint: z.string().nullish(), region: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_ssl_deploy_region.placeholder") }) + .string(t("workflow_node.deploy.form.tencentcloud_ssl_deploy_region.placeholder")) .nonempty(t("workflow_node.deploy.form.tencentcloud_ssl_deploy_region.placeholder")), resourceType: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_type.placeholder") }) + .string(t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_type.placeholder")) .nonempty(t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_type.placeholder")), - resourceIds: z.string({ message: t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.placeholder") }).refine((v) => { + resourceIds: z.string(t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.placeholder")).refine((v) => { if (!v) return false; return String(v) .split(MULTIPLE_INPUT_SEPARATOR) diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudVODConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudVODConfig.tsx index 99136b9a..9a47a221 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudVODConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudVODConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -35,15 +35,13 @@ const DeployNodeConfigFormTencentCloudVODConfig = ({ const formSchema = z.object({ endpoint: z.string().nullish(), subAppId: z - .union([z.string(), z.number()]) + .union([z.string(), z.number().int()]) .nullish() .refine((v) => { if (v == null) return true; return /^\d+$/.test(v + "") && +v > 0; }, t("workflow_node.deploy.form.tencentcloud_vod_sub_app_id.placeholder")), - domain: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_vod_domain.placeholder") }) - .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + domain: z.string(t("workflow_node.deploy.form.tencentcloud_vod_domain.placeholder")).refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudWAFConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudWAFConfig.tsx index 6cf53c6f..c70195c7 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudWAFConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudWAFConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -37,16 +37,14 @@ const DeployNodeConfigFormTencentCloudWAFConfig = ({ const formSchema = z.object({ endpoint: z.string().nullish(), region: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_waf_region.placeholder") }) + .string(t("workflow_node.deploy.form.tencentcloud_waf_region.placeholder")) .nonempty(t("workflow_node.deploy.form.tencentcloud_waf_region.placeholder")), - domain: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_waf_domain.placeholder") }) - .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + domain: z.string(t("workflow_node.deploy.form.tencentcloud_waf_domain.placeholder")).refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), domainId: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_waf_domain_id.placeholder") }) + .string(t("workflow_node.deploy.form.tencentcloud_waf_domain_id.placeholder")) .nonempty(t("workflow_node.deploy.form.tencentcloud_waf_domain_id.placeholder")), instanceId: z - .string({ message: t("workflow_node.deploy.form.tencentcloud_waf_instance_id.placeholder") }) + .string(t("workflow_node.deploy.form.tencentcloud_waf_instance_id.placeholder")) .nonempty(t("workflow_node.deploy.form.tencentcloud_waf_instance_id.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormUCloudUCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormUCloudUCDNConfig.tsx index 41c059fc..fd244161 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormUCloudUCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormUCloudUCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormUCloudUCDNConfigFieldValues = Nullish<{ domainId: string; @@ -30,7 +30,7 @@ const DeployNodeConfigFormUCloudUCDNConfig = ({ const formSchema = z.object({ domainId: z - .string({ message: t("workflow_node.deploy.form.ucloud_ucdn_domain_id.placeholder") }) + .string(t("workflow_node.deploy.form.ucloud_ucdn_domain_id.placeholder")) .nonempty(t("workflow_node.deploy.form.ucloud_ucdn_domain_id.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormUCloudUS3Config.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormUCloudUS3Config.tsx index a2ea684b..fe917e9f 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormUCloudUS3Config.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormUCloudUS3Config.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -33,15 +33,9 @@ const DeployNodeConfigFormUCloudUS3Config = ({ const { t } = useTranslation(); const formSchema = z.object({ - region: z - .string({ message: t("workflow_node.deploy.form.ucloud_us3_region.placeholder") }) - .nonempty(t("workflow_node.deploy.form.ucloud_us3_region.placeholder")), - bucket: z - .string({ message: t("workflow_node.deploy.form.ucloud_us3_bucket.placeholder") }) - .nonempty(t("workflow_node.deploy.form.ucloud_us3_bucket.placeholder")), - domain: z - .string({ message: t("workflow_node.deploy.form.ucloud_us3_domain.placeholder") }) - .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + region: z.string(t("workflow_node.deploy.form.ucloud_us3_region.placeholder")).nonempty(t("workflow_node.deploy.form.ucloud_us3_region.placeholder")), + bucket: z.string(t("workflow_node.deploy.form.ucloud_us3_bucket.placeholder")).nonempty(t("workflow_node.deploy.form.ucloud_us3_bucket.placeholder")), + domain: z.string(t("workflow_node.deploy.form.ucloud_us3_domain.placeholder")).refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormUniCloudWebHostConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormUniCloudWebHostConfig.tsx index 21624c52..c0265173 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormUniCloudWebHostConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormUniCloudWebHostConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Alert, Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormUpyunCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormUpyunCDNConfig.tsx index c18d570c..6cebec9a 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormUpyunCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormUpyunCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Alert, Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -26,7 +26,7 @@ const DeployNodeConfigFormUpyunCDNConfig = ({ form: formInst, formName, disabled const formSchema = z.object({ domain: z - .string({ message: t("workflow_node.deploy.form.upyun_cdn_domain.placeholder") }) + .string(t("workflow_node.deploy.form.upyun_cdn_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormUpyunFileConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormUpyunFileConfig.tsx index 68ea3369..49faf0f9 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormUpyunFileConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormUpyunFileConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Alert, Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -31,9 +31,7 @@ const DeployNodeConfigFormUpyunFileConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - domain: z - .string({ message: t("workflow_node.deploy.form.upyun_file_domain.placeholder") }) - .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + domain: z.string(t("workflow_node.deploy.form.upyun_file_domain.placeholder")).refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineALBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineALBConfig.tsx index 68880421..8f062816 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineALBConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineALBConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; import { validDomainName } from "@/utils/validators"; @@ -42,11 +42,9 @@ const DeployNodeConfigFormVolcEngineALBConfig = ({ const formSchema = z.object({ region: z - .string({ message: t("workflow_node.deploy.form.volcengine_alb_region.placeholder") }) + .string(t("workflow_node.deploy.form.volcengine_alb_region.placeholder")) .nonempty(t("workflow_node.deploy.form.volcengine_alb_region.placeholder")), - resourceType: z.union([z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { - message: t("workflow_node.deploy.form.volcengine_alb_resource_type.placeholder"), - }), + resourceType: z.literal([RESOURCE_TYPE_LOADBALANCER, RESOURCE_TYPE_LISTENER], t("workflow_node.deploy.form.volcengine_alb_resource_type.placeholder")), loadbalancerId: z .string() .max(64, t("common.errmsg.string_max", { max: 64 })) diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCDNConfig.tsx index c420e96e..d86777dc 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,7 +32,7 @@ const DeployNodeConfigFormVolcEngineCDNConfig = ({ const formSchema = z.object({ domain: z - .string({ message: t("workflow_node.deploy.form.volcengine_cdn_domain.placeholder") }) + .string(t("workflow_node.deploy.form.volcengine_cdn_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCLBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCLBConfig.tsx index 80778e01..ec9c0925 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCLBConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCLBConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; @@ -40,11 +40,9 @@ const DeployNodeConfigFormVolcEngineCLBConfig = ({ const formSchema = z.object({ region: z - .string({ message: t("workflow_node.deploy.form.volcengine_clb_region.placeholder") }) + .string(t("workflow_node.deploy.form.volcengine_clb_region.placeholder")) .nonempty(t("workflow_node.deploy.form.volcengine_clb_region.placeholder")), - resourceType: z.union([z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER)], { - message: t("workflow_node.deploy.form.volcengine_clb_resource_type.placeholder"), - }), + resourceType: z.literal([RESOURCE_TYPE_LOADBALANCER, RESOURCE_TYPE_LISTENER], t("workflow_node.deploy.form.volcengine_clb_resource_type.placeholder")), loadbalancerId: z .string() .max(64, t("common.errmsg.string_max", { max: 64 })) diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCertCenterConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCertCenterConfig.tsx index 28fb16f6..2350aeec 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCertCenterConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCertCenterConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormVolcEngineCertCenterConfigFieldValues = Nullish<{ region: string; @@ -30,7 +30,7 @@ const DeployNodeConfigFormVolcEngineCertCenterConfig = ({ const formSchema = z.object({ region: z - .string({ message: t("workflow_node.deploy.form.volcengine_certcenter_region.placeholder") }) + .string(t("workflow_node.deploy.form.volcengine_certcenter_region.placeholder")) .nonempty(t("workflow_node.deploy.form.volcengine_certcenter_region.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineDCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineDCDNConfig.tsx index 0d430e1e..ce254665 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineDCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineDCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,7 +32,7 @@ const DeployNodeConfigFormVolcEngineDCDNConfig = ({ const formSchema = z.object({ domain: z - .string({ message: t("workflow_node.deploy.form.volcengine_dcdn_domain.placeholder") }) + .string(t("workflow_node.deploy.form.volcengine_dcdn_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineImageXConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineImageXConfig.tsx index 5ce81fd0..d1cb3fdb 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineImageXConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineImageXConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,14 +32,12 @@ const DeployNodeConfigFormVolcEngineImageXConfig = ({ const formSchema = z.object({ region: z - .string({ message: t("workflow_node.deploy.form.volcengine_imagex_region.placeholder") }) + .string(t("workflow_node.deploy.form.volcengine_imagex_region.placeholder")) .nonempty(t("workflow_node.deploy.form.volcengine_imagex_region.placeholder")), serviceId: z - .string({ message: t("workflow_node.deploy.form.volcengine_imagex_service_id.placeholder") }) + .string(t("workflow_node.deploy.form.volcengine_imagex_service_id.placeholder")) .nonempty(t("workflow_node.deploy.form.volcengine_imagex_service_id.placeholder")), - domain: z - .string({ message: t("workflow_node.deploy.form.volcengine_imagex_domain.placeholder") }) - .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + domain: z.string(t("workflow_node.deploy.form.volcengine_imagex_domain.placeholder")).refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineLiveConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineLiveConfig.tsx index 3845c1ac..316cd017 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineLiveConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineLiveConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -32,7 +32,7 @@ const DeployNodeConfigFormVolcEngineLiveConfig = ({ const formSchema = z.object({ domain: z - .string({ message: t("workflow_node.deploy.form.volcengine_live_domain.placeholder") }) + .string(t("workflow_node.deploy.form.volcengine_live_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineTOSConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineTOSConfig.tsx index 516dc123..29a39710 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineTOSConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineTOSConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -34,14 +34,12 @@ const DeployNodeConfigFormVolcEngineTOSConfig = ({ const formSchema = z.object({ region: z - .string({ message: t("workflow_node.deploy.form.volcengine_tos_region.placeholder") }) + .string(t("workflow_node.deploy.form.volcengine_tos_region.placeholder")) .nonempty(t("workflow_node.deploy.form.volcengine_tos_region.placeholder")), bucket: z - .string({ message: t("workflow_node.deploy.form.volcengine_tos_bucket.placeholder") }) + .string(t("workflow_node.deploy.form.volcengine_tos_bucket.placeholder")) .nonempty(t("workflow_node.deploy.form.volcengine_tos_bucket.placeholder")), - domain: z - .string({ message: t("workflow_node.deploy.form.volcengine_tos_domain.placeholder") }) - .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + domain: z.string(t("workflow_node.deploy.form.volcengine_tos_domain.placeholder")).refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormWangsuCDNConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormWangsuCDNConfig.tsx index 7650894e..8dbc6115 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormWangsuCDNConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormWangsuCDNConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import MultipleSplitValueInput from "@/components/MultipleSplitValueInput"; import { validDomainName } from "@/utils/validators"; diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormWangsuCDNProConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormWangsuCDNProConfig.tsx index e89e1e8d..282283ca 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormWangsuCDNProConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormWangsuCDNProConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validDomainName } from "@/utils/validators"; @@ -39,11 +39,9 @@ const DeployNodeConfigFormWangsuCDNProConfig = ({ const { t } = useTranslation(); const formSchema = z.object({ - resourceType: z.union([z.literal(ENVIRONMENT_PRODUCTION), z.literal(ENVIRONMENT_STAGING)], { - message: t("workflow_node.deploy.form.wangsu_cdnpro_environment.placeholder"), - }), + resourceType: z.literal([ENVIRONMENT_PRODUCTION, ENVIRONMENT_STAGING], t("workflow_node.deploy.form.wangsu_cdnpro_environment.placeholder")), domain: z - .string({ message: t("workflow_node.deploy.form.wangsu_cdnpro_domain.placeholder") }) + .string(t("workflow_node.deploy.form.wangsu_cdnpro_domain.placeholder")) .refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), certificateId: z.string().nullish(), webhookId: z.string().nullish(), diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormWangsuCertificateConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormWangsuCertificateConfig.tsx index 739e4b28..84ee2c3b 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormWangsuCertificateConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormWangsuCertificateConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; type DeployNodeConfigFormWangsuCertificateConfigFieldValues = Nullish<{ certificateId?: string; diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormWebhookConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormWebhookConfig.tsx index 5dae40e8..9c7f0318 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormWebhookConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormWebhookConfig.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Alert, Form, type FormInstance } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import CodeInput from "@/components/CodeInput"; diff --git a/ui/src/components/workflow/node/MonitorNodeConfigForm.tsx b/ui/src/components/workflow/node/MonitorNodeConfigForm.tsx index 92eef42e..9a8f6bc4 100644 --- a/ui/src/components/workflow/node/MonitorNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/MonitorNodeConfigForm.tsx @@ -2,7 +2,7 @@ import { forwardRef, memo, useImperativeHandle } from "react"; import { useTranslation } from "react-i18next"; import { Alert, Form, type FormInstance, Input, InputNumber } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { type WorkflowNodeConfigForMonitor, defaultNodeConfigForMonitor } from "@/domain/workflow"; import { useAntdForm } from "@/hooks"; diff --git a/ui/src/components/workflow/node/NotifyNodeConfigForm.tsx b/ui/src/components/workflow/node/NotifyNodeConfigForm.tsx index 09c6e02e..5b90bbfd 100644 --- a/ui/src/components/workflow/node/NotifyNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/NotifyNodeConfigForm.tsx @@ -4,7 +4,7 @@ import { Link } from "react-router"; import { PlusOutlined as PlusOutlinedIcon, RightOutlined as RightOutlinedIcon } from "@ant-design/icons"; import { Button, Divider, Flex, Form, type FormInstance, Input, Select, Switch, Typography } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import AccessEditModal from "@/components/access/AccessEditModal"; import AccessSelect from "@/components/access/AccessSelect"; @@ -61,17 +61,17 @@ const NotifyNodeConfigForm = forwardRef { const { t } = useTranslation(); - const formSchema = z - .object({ - trigger: z.string({ message: t("workflow_node.start.form.trigger.placeholder") }).min(1, t("workflow_node.start.form.trigger.placeholder")), - triggerCron: z.string().nullish(), - }) - .superRefine((data, ctx) => { - if (data.trigger !== WORKFLOW_TRIGGERS.AUTO) { - return; - } - - if (!validCronExpression(data.triggerCron!)) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: t("workflow_node.start.form.trigger_cron.errmsg.invalid"), - path: ["triggerCron"], - }); - } - }); + const formSchema = z.object({ + trigger: z.string(t("workflow_node.start.form.trigger.placeholder")).min(1, t("workflow_node.start.form.trigger.placeholder")), + triggerCron: z + .string() + .nullish() + .refine((v) => { + if (fieldTrigger !== WORKFLOW_TRIGGERS.AUTO) return true; + return validCronExpression(v!); + }, t("workflow_node.start.form.trigger_cron.errmsg.invalid")), + }); const formRule = createSchemaFieldRule(formSchema); const { form: formInst, formProps } = useAntdForm({ name: "workflowNodeStartConfigForm", diff --git a/ui/src/components/workflow/node/UploadNodeConfigForm.tsx b/ui/src/components/workflow/node/UploadNodeConfigForm.tsx index 27898401..810391a6 100644 --- a/ui/src/components/workflow/node/UploadNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/UploadNodeConfigForm.tsx @@ -2,7 +2,7 @@ import { forwardRef, memo, useImperativeHandle } from "react"; import { useTranslation } from "react-i18next"; import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { validateCertificate, validatePrivateKey } from "@/api/certificates"; import TextFileInput from "@/components/TextFileInput"; @@ -37,11 +37,11 @@ const UploadNodeConfigForm = forwardRef { const [notificationApi, NotificationContextHolder] = notification.useNotification(); const formSchema = z.object({ - username: z.string().email(t("login.username.errmsg.invalid")), + username: z.email(t("login.username.errmsg.invalid")), password: z.string().min(10, t("login.password.errmsg.invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/pages/settings/SettingsAccount.tsx b/ui/src/pages/settings/SettingsAccount.tsx index 734e8bce..fccacd25 100644 --- a/ui/src/pages/settings/SettingsAccount.tsx +++ b/ui/src/pages/settings/SettingsAccount.tsx @@ -3,7 +3,7 @@ import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; import { Button, Form, Input, message, notification } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { useAntdForm } from "@/hooks"; import { getAuthStore, save as saveAdmin } from "@/repository/admin"; @@ -18,7 +18,7 @@ const SettingsAccount = () => { const [notificationApi, NotificationContextHolder] = notification.useNotification(); const formSchema = z.object({ - username: z.string({ message: t("settings.account.form.email.placeholder") }).email({ message: t("common.errmsg.email_invalid") }), + username: z.email(t("common.errmsg.email_invalid")), }); const formRule = createSchemaFieldRule(formSchema); const { diff --git a/ui/src/pages/settings/SettingsPassword.tsx b/ui/src/pages/settings/SettingsPassword.tsx index de1cb5ef..7d9d5abb 100644 --- a/ui/src/pages/settings/SettingsPassword.tsx +++ b/ui/src/pages/settings/SettingsPassword.tsx @@ -3,7 +3,7 @@ import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; import { Button, Form, Input, message, notification } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import { useAntdForm } from "@/hooks"; import { authWithPassword, getAuthStore, save as saveAdmin } from "@/repository/admin"; @@ -18,10 +18,10 @@ const SettingsPassword = () => { const [notificationApi, NotificationContextHolder] = notification.useNotification(); const formSchema = z.object({ - oldPassword: z.string({ message: t("settings.password.form.old_password.placeholder") }).min(10, t("settings.password.form.password.errmsg.invalid")), - newPassword: z.string({ message: t("settings.password.form.new_password.placeholder") }).min(10, t("settings.password.form.password.errmsg.invalid")), + oldPassword: z.string(t("settings.password.form.old_password.placeholder")).min(10, t("settings.password.form.password.errmsg.invalid")), + newPassword: z.string(t("settings.password.form.new_password.placeholder")).min(10, t("settings.password.form.password.errmsg.invalid")), confirmPassword: z - .string({ message: t("settings.password.form.confirm_password.placeholder") }) + .string(t("settings.password.form.confirm_password.placeholder")) .min(10, t("settings.password.form.password.errmsg.invalid")) .refine((v) => v === formInst.getFieldValue("newPassword"), t("settings.password.form.password.errmsg.not_matched")), }); diff --git a/ui/src/pages/settings/SettingsPersistence.tsx b/ui/src/pages/settings/SettingsPersistence.tsx index e75ed8a3..fa68ea50 100644 --- a/ui/src/pages/settings/SettingsPersistence.tsx +++ b/ui/src/pages/settings/SettingsPersistence.tsx @@ -3,7 +3,7 @@ import { useTranslation } from "react-i18next"; import { Button, Form, InputNumber, Skeleton, message, notification } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { produce } from "immer"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; import { type PersistenceSettingsContent, SETTINGS_NAMES, type SettingsModel } from "@/domain/settings"; @@ -34,10 +34,10 @@ const SettingsPersistence = () => { const formSchema = z.object({ workflowRunsMaxDaysRetention: z - .number({ message: t("settings.persistence.form.workflow_runs_max_days.placeholder") }) + .number(t("settings.persistence.form.workflow_runs_max_days.placeholder")) .gte(0, t("settings.persistence.form.workflow_runs_max_days.placeholder")), expiredCertificatesMaxDaysRetention: z - .number({ message: t("settings.persistence.form.expired_certificates_max_days.placeholder") }) + .number(t("settings.persistence.form.expired_certificates_max_days.placeholder")) .gte(0, t("settings.persistence.form.expired_certificates_max_days.placeholder")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/pages/settings/SettingsSSLProvider.tsx b/ui/src/pages/settings/SettingsSSLProvider.tsx index 2be6162f..02be893d 100644 --- a/ui/src/pages/settings/SettingsSSLProvider.tsx +++ b/ui/src/pages/settings/SettingsSSLProvider.tsx @@ -4,7 +4,7 @@ import { CheckCard } from "@ant-design/pro-components"; import { Alert, Button, Form, Input, Skeleton, message, notification } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { produce } from "immer"; -import { z } from "zod"; +import { z } from "zod/v4"; import Show from "@/components/Show"; import { type CAProviderType, CA_PROVIDERS } from "@/domain/provider"; @@ -155,11 +155,11 @@ const SSLProviderEditFormGoogleTrustServicesConfig = () => { const formSchema = z.object({ eabKid: z - .string({ message: t("settings.sslprovider.form.googletrustservices_eab_kid.placeholder") }) + .string(t("settings.sslprovider.form.googletrustservices_eab_kid.placeholder")) .min(1, t("settings.sslprovider.form.googletrustservices_eab_kid.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), eabHmacKey: z - .string({ message: t("settings.sslprovider.form.googletrustservices_eab_hmac_key.placeholder") }) + .string(t("settings.sslprovider.form.googletrustservices_eab_hmac_key.placeholder")) .min(1, t("settings.sslprovider.form.googletrustservices_eab_hmac_key.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), }); @@ -225,11 +225,11 @@ const SSLProviderEditFormSSLComConfig = () => { const formSchema = z.object({ eabKid: z - .string({ message: t("settings.sslprovider.form.sslcom_eab_kid.placeholder") }) + .string(t("settings.sslprovider.form.sslcom_eab_kid.placeholder")) .min(1, t("settings.sslprovider.form.sslcom_eab_kid.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), eabHmacKey: z - .string({ message: t("settings.sslprovider.form.sslcom_eab_hmac_key.placeholder") }) + .string(t("settings.sslprovider.form.sslcom_eab_hmac_key.placeholder")) .min(1, t("settings.sslprovider.form.sslcom_eab_hmac_key.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), }); @@ -295,11 +295,11 @@ const SSLProviderEditFormZeroSSLConfig = () => { const formSchema = z.object({ eabKid: z - .string({ message: t("settings.sslprovider.form.zerossl_eab_kid.placeholder") }) + .string(t("settings.sslprovider.form.zerossl_eab_kid.placeholder")) .min(1, t("settings.sslprovider.form.zerossl_eab_kid.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), eabHmacKey: z - .string({ message: t("settings.sslprovider.form.zerossl_eab_hmac_key.placeholder") }) + .string(t("settings.sslprovider.form.zerossl_eab_hmac_key.placeholder")) .min(1, t("settings.sslprovider.form.zerossl_eab_hmac_key.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), }); diff --git a/ui/src/pages/workflows/WorkflowDetail.tsx b/ui/src/pages/workflows/WorkflowDetail.tsx index 549bc311..1ca2d5a7 100644 --- a/ui/src/pages/workflows/WorkflowDetail.tsx +++ b/ui/src/pages/workflows/WorkflowDetail.tsx @@ -14,7 +14,7 @@ import { PageHeader } from "@ant-design/pro-components"; import { Alert, Button, Card, Dropdown, Form, Input, Modal, Space, Tabs, Typography, message, notification } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { isEqual } from "radash"; -import { z } from "zod"; +import { z } from "zod/v4"; import { startRun as startWorkflowRun } from "@/api/workflows"; import ModalForm from "@/components/ModalForm"; @@ -333,11 +333,11 @@ const WorkflowBaseInfoModal = ({ trigger }: { trigger?: React.ReactNode }) => { const formSchema = z.object({ name: z - .string({ message: t("workflow.detail.baseinfo.form.name.placeholder") }) + .string(t("workflow.detail.baseinfo.form.name.placeholder")) .min(1, t("workflow.detail.baseinfo.form.name.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), description: z - .string({ message: t("workflow.detail.baseinfo.form.description.placeholder") }) + .string(t("workflow.detail.baseinfo.form.description.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })) .nullish(), }); diff --git a/ui/src/pages/workflows/WorkflowNew.tsx b/ui/src/pages/workflows/WorkflowNew.tsx index 1da27939..f0ec81ef 100644 --- a/ui/src/pages/workflows/WorkflowNew.tsx +++ b/ui/src/pages/workflows/WorkflowNew.tsx @@ -4,7 +4,7 @@ import { useNavigate } from "react-router-dom"; import { PageHeader } from "@ant-design/pro-components"; import { Card, Col, Form, Input, type InputRef, Row, Spin, Typography, notification } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; +import { z } from "zod/v4"; import ModalForm from "@/components/ModalForm"; import { type WorkflowModel, initWorkflow } from "@/domain/workflow"; @@ -35,11 +35,11 @@ const WorkflowNew = () => { const formSchema = z.object({ name: z - .string({ message: t("workflow.new.modal.form.name.placeholder") }) + .string(t("workflow.new.modal.form.name.placeholder")) .min(1, t("workflow.new.modal.form.name.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), description: z - .string({ message: t("workflow.new.modal.form.description.placeholder") }) + .string(t("workflow.new.modal.form.description.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })) .nullish(), }); diff --git a/ui/src/utils/validators.ts b/ui/src/utils/validators.ts index c170ce40..92aacbd4 100644 --- a/ui/src/utils/validators.ts +++ b/ui/src/utils/validators.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { validCronExpression as _validCronExpression } from "./cron"; @@ -13,7 +13,7 @@ export const validDomainName = (value: string, { allowWildcard = false }: { allo export const validEmailAddress = (value: string) => { try { - z.string().email().parse(value); + z.email().parse(value); return true; } catch (_) { return false; @@ -22,7 +22,7 @@ export const validEmailAddress = (value: string) => { export const validIPv4Address = (value: string) => { try { - z.string().ip({ version: "v4" }).parse(value); + z.ipv4().parse(value); return true; } catch (_) { return false; @@ -31,7 +31,7 @@ export const validIPv4Address = (value: string) => { export const validIPv6Address = (value: string) => { try { - z.string().ip({ version: "v6" }).parse(value); + z.ipv6().parse(value); return true; } catch (_) { return false; From d272b64329488236597cafa017d0d1563af7afff Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Mon, 23 Jun 2025 21:25:11 +0800 Subject: [PATCH 07/16] feat: new deployment provider: tencentcloud ssludpate --- internal/deployer/providers.go | 15 +- internal/domain/provider.go | 1 + .../tencentcloud_ssl_update.go | 304 ++++++++++++++++++ .../workflow/node/DeployNodeConfigForm.tsx | 3 + ...loyNodeConfigFormAliyunCASDeployConfig.tsx | 8 +- ...eConfigFormTencentCloudSSLDeployConfig.tsx | 8 +- ...eConfigFormTencentCloudSSLUpdateConfig.tsx | 130 ++++++++ ui/src/domain/provider.ts | 2 + ui/src/i18n/locales/en/nls.provider.json | 5 +- .../i18n/locales/en/nls.workflow.nodes.json | 18 ++ ui/src/i18n/locales/zh/nls.provider.json | 5 +- .../i18n/locales/zh/nls.workflow.nodes.json | 22 +- 12 files changed, 506 insertions(+), 15 deletions(-) create mode 100644 pkg/core/ssl-deployer/providers/tencentcloud-ssl-update/tencentcloud_ssl_update.go create mode 100644 ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLUpdateConfig.tsx diff --git a/internal/deployer/providers.go b/internal/deployer/providers.go index 708dc6d0..dac425f9 100644 --- a/internal/deployer/providers.go +++ b/internal/deployer/providers.go @@ -84,6 +84,7 @@ import ( pTencentCloudSCF "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/tencentcloud-scf" pTencentCloudSSL "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/tencentcloud-ssl" pTencentCloudSSLDeploy "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/tencentcloud-ssl-deploy" + pTencentCloudSSLUpdate "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/tencentcloud-ssl-update" pTencentCloudVOD "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/tencentcloud-vod" pTencentCloudWAF "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/tencentcloud-waf" pUCloudUCDN "github.com/certimate-go/certimate/pkg/core/ssl-deployer/providers/ucloud-ucdn" @@ -1118,7 +1119,7 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy return deployer, err } - case domain.DeploymentProviderTypeTencentCloudCDN, domain.DeploymentProviderTypeTencentCloudCLB, domain.DeploymentProviderTypeTencentCloudCOS, domain.DeploymentProviderTypeTencentCloudCSS, domain.DeploymentProviderTypeTencentCloudECDN, domain.DeploymentProviderTypeTencentCloudEO, domain.DeploymentProviderTypeTencentCloudGAAP, domain.DeploymentProviderTypeTencentCloudSCF, domain.DeploymentProviderTypeTencentCloudSSL, domain.DeploymentProviderTypeTencentCloudSSLDeploy, domain.DeploymentProviderTypeTencentCloudVOD, domain.DeploymentProviderTypeTencentCloudWAF: + case domain.DeploymentProviderTypeTencentCloudCDN, domain.DeploymentProviderTypeTencentCloudCLB, domain.DeploymentProviderTypeTencentCloudCOS, domain.DeploymentProviderTypeTencentCloudCSS, domain.DeploymentProviderTypeTencentCloudECDN, domain.DeploymentProviderTypeTencentCloudEO, domain.DeploymentProviderTypeTencentCloudGAAP, domain.DeploymentProviderTypeTencentCloudSCF, domain.DeploymentProviderTypeTencentCloudSSL, domain.DeploymentProviderTypeTencentCloudSSLDeploy, domain.DeploymentProviderTypeTencentCloudSSLUpdate, domain.DeploymentProviderTypeTencentCloudVOD, domain.DeploymentProviderTypeTencentCloudWAF: { access := domain.AccessConfigForTencentCloud{} if err := xmaps.Populate(options.ProviderAccessConfig, &access); err != nil { @@ -1226,6 +1227,18 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy }) return deployer, err + case domain.DeploymentProviderTypeTencentCloudSSLUpdate: + deployer, err := pTencentCloudSSLUpdate.NewSSLDeployerProvider(&pTencentCloudSSLUpdate.SSLDeployerProviderConfig{ + SecretId: access.SecretId, + SecretKey: access.SecretKey, + Endpoint: xmaps.GetString(options.ProviderServiceConfig, "endpoint"), + CertificiateId: xmaps.GetString(options.ProviderServiceConfig, "certificiateId"), + IsReplaced: xmaps.GetBool(options.ProviderServiceConfig, "isReplaced"), + ResourceRegions: xslices.Filter(strings.Split(xmaps.GetString(options.ProviderServiceConfig, "resourceRegions"), ";"), func(s string) bool { return s != "" }), + ResourceTypes: xslices.Filter(strings.Split(xmaps.GetString(options.ProviderServiceConfig, "resourceTypes"), ";"), func(s string) bool { return s != "" }), + }) + return deployer, err + case domain.DeploymentProviderTypeTencentCloudVOD: deployer, err := pTencentCloudVOD.NewSSLDeployerProvider(&pTencentCloudVOD.SSLDeployerProviderConfig{ SecretId: access.SecretId, diff --git a/internal/domain/provider.go b/internal/domain/provider.go index 47ba0e72..3688d5e3 100644 --- a/internal/domain/provider.go +++ b/internal/domain/provider.go @@ -257,6 +257,7 @@ const ( DeploymentProviderTypeTencentCloudSCF = DeploymentProviderType(AccessProviderTypeTencentCloud + "-scf") DeploymentProviderTypeTencentCloudSSL = DeploymentProviderType(AccessProviderTypeTencentCloud + "-ssl") DeploymentProviderTypeTencentCloudSSLDeploy = DeploymentProviderType(AccessProviderTypeTencentCloud + "-ssldeploy") + DeploymentProviderTypeTencentCloudSSLUpdate = DeploymentProviderType(AccessProviderTypeTencentCloud + "-sslupdate") DeploymentProviderTypeTencentCloudVOD = DeploymentProviderType(AccessProviderTypeTencentCloud + "-vod") DeploymentProviderTypeTencentCloudWAF = DeploymentProviderType(AccessProviderTypeTencentCloud + "-waf") DeploymentProviderTypeUCloudUCDN = DeploymentProviderType(AccessProviderTypeUCloud + "-ucdn") diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-ssl-update/tencentcloud_ssl_update.go b/pkg/core/ssl-deployer/providers/tencentcloud-ssl-update/tencentcloud_ssl_update.go new file mode 100644 index 00000000..e12f894f --- /dev/null +++ b/pkg/core/ssl-deployer/providers/tencentcloud-ssl-update/tencentcloud_ssl_update.go @@ -0,0 +1,304 @@ +package tencentcloudsslupdate + +import ( + "context" + "errors" + "fmt" + "log/slog" + "slices" + "time" + + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" + tcssl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205" + + "github.com/certimate-go/certimate/pkg/core" + sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/tencentcloud-ssl" +) + +type SSLDeployerProviderConfig struct { + // 腾讯云 SecretId。 + SecretId string `json:"secretId"` + // 腾讯云 SecretKey。 + SecretKey string `json:"secretKey"` + // 腾讯云接口端点。 + Endpoint string `json:"endpoint,omitempty"` + // 原证书 ID。 + CertificiateId string `json:"certificateId"` + // 是否替换原有证书(即保持原证书 ID 不变)。 + IsReplaced bool `json:"isReplaced,omitempty"` + // 云资源类型数组。 + ResourceTypes []string `json:"resourceTypes"` + // 云资源地域数组。 + ResourceRegions []string `json:"resourceRegions"` +} + +type SSLDeployerProvider struct { + config *SSLDeployerProviderConfig + logger *slog.Logger + sdkClient *tcssl.Client + sslManager core.SSLManager +} + +var _ core.SSLDeployer = (*SSLDeployerProvider)(nil) + +func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProvider, error) { + if config == nil { + return nil, errors.New("the configuration of the ssl deployer provider is nil") + } + + client, err := createSDKClient(config.SecretId, config.SecretKey, config.Endpoint) + if err != nil { + return nil, fmt.Errorf("could not create sdk client: %w", err) + } + + sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ + SecretId: config.SecretId, + SecretKey: config.SecretKey, + Endpoint: config.Endpoint, + }) + if err != nil { + return nil, fmt.Errorf("could not create ssl manager: %w", err) + } + + return &SSLDeployerProvider{ + config: config, + logger: slog.Default(), + sdkClient: client, + sslManager: sslmgr, + }, nil +} + +func (d *SSLDeployerProvider) SetLogger(logger *slog.Logger) { + if logger == nil { + d.logger = slog.New(slog.DiscardHandler) + } else { + d.logger = logger + } + + d.sslManager.SetLogger(logger) +} + +func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*core.SSLDeployResult, error) { + if d.config.CertificiateId == "" { + return nil, errors.New("config `certificateId` is required") + } + if len(d.config.ResourceTypes) == 0 { + return nil, errors.New("config `resourceTypes` is required") + } + + if d.config.IsReplaced { + if err := d.executeUploadUpdateCertificateInstance(ctx, certPEM, privkeyPEM); err != nil { + return nil, err + } + } else { + if err := d.executeUpdateCertificateInstance(ctx, certPEM, privkeyPEM); err != nil { + return nil, err + } + } + + return &core.SSLDeployResult{}, nil +} + +func (d *SSLDeployerProvider) executeUpdateCertificateInstance(ctx context.Context, certPEM string, privkeyPEM string) error { + // 上传证书 + upres, err := d.sslManager.Upload(ctx, certPEM, privkeyPEM) + if err != nil { + return fmt.Errorf("failed to upload certificate file: %w", err) + } else { + d.logger.Info("ssl certificate uploaded", slog.Any("result", upres)) + } + + // 一键更新新旧证书资源 + // REF: https://cloud.tencent.com/document/product/400/91649 + var deployRecordId string + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + updateCertificateInstanceReq := tcssl.NewUpdateCertificateInstanceRequest() + updateCertificateInstanceReq.OldCertificateId = common.StringPtr(d.config.CertificiateId) + updateCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId) + updateCertificateInstanceReq.ResourceTypes = common.StringPtrs(d.config.ResourceTypes) + updateCertificateInstanceReq.ResourceTypesRegions = wrapResourceTypeRegions(d.config.ResourceTypes, d.config.ResourceRegions) + updateCertificateInstanceResp, err := d.sdkClient.UpdateCertificateInstance(updateCertificateInstanceReq) + d.logger.Debug("sdk request 'ssl.UpdateCertificateInstance'", slog.Any("request", updateCertificateInstanceReq), slog.Any("response", updateCertificateInstanceResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request 'ssl.UpdateCertificateInstance': %w", err) + } + + if updateCertificateInstanceResp.Response.DeployStatus == nil { + return errors.New("unexpected deployment job status") + } else if *updateCertificateInstanceResp.Response.DeployStatus == 1 { + deployRecordId = fmt.Sprintf("%d", *updateCertificateInstanceResp.Response.DeployRecordId) + break + } + + time.Sleep(time.Second * 5) + } + + // 循环查询证书云资源更新记录详情,等待任务状态变更 + // REF: https://cloud.tencent.com/document/api/400/91652 + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + describeHostUpdateRecordDetailReq := tcssl.NewDescribeHostUpdateRecordDetailRequest() + describeHostUpdateRecordDetailReq.DeployRecordId = common.StringPtr(deployRecordId) + describeHostUpdateRecordDetailResp, err := d.sdkClient.DescribeHostUpdateRecordDetail(describeHostUpdateRecordDetailReq) + d.logger.Debug("sdk request 'ssl.DescribeHostUpdateRecordDetail'", slog.Any("request", describeHostUpdateRecordDetailReq), slog.Any("response", describeHostUpdateRecordDetailResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostUpdateRecordDetail': %w", err) + } + + var runningCount, succeededCount, failedCount, totalCount int64 + if describeHostUpdateRecordDetailResp.Response.TotalCount == nil { + return errors.New("unexpected deployment job status") + } else { + if describeHostUpdateRecordDetailResp.Response.RunningTotalCount != nil { + runningCount = *describeHostUpdateRecordDetailResp.Response.RunningTotalCount + } + if describeHostUpdateRecordDetailResp.Response.SuccessTotalCount != nil { + succeededCount = *describeHostUpdateRecordDetailResp.Response.SuccessTotalCount + } + if describeHostUpdateRecordDetailResp.Response.FailedTotalCount != nil { + failedCount = *describeHostUpdateRecordDetailResp.Response.FailedTotalCount + } + if describeHostUpdateRecordDetailResp.Response.TotalCount != nil { + totalCount = *describeHostUpdateRecordDetailResp.Response.TotalCount + } + + if succeededCount+failedCount == totalCount { + break + } + } + + d.logger.Info(fmt.Sprintf("waiting for deployment job completion (running: %d, succeeded: %d, failed: %d, total: %d) ...", runningCount, succeededCount, failedCount, totalCount)) + time.Sleep(time.Second * 5) + } + + return nil +} + +func (d *SSLDeployerProvider) executeUploadUpdateCertificateInstance(ctx context.Context, certPEM string, privkeyPEM string) error { + // 更新证书内容并更新关联的云资源 + // REF: https://cloud.tencent.com/document/product/400/119791 + // var deployRecordId string + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + uploadUpdateCertificateInstanceReq := tcssl.NewUploadUpdateCertificateInstanceRequest() + uploadUpdateCertificateInstanceReq.OldCertificateId = common.StringPtr(d.config.CertificiateId) + uploadUpdateCertificateInstanceReq.CertificatePublicKey = common.StringPtr(certPEM) + uploadUpdateCertificateInstanceReq.CertificatePrivateKey = common.StringPtr(privkeyPEM) + uploadUpdateCertificateInstanceReq.ResourceTypes = common.StringPtrs(d.config.ResourceTypes) + uploadUpdateCertificateInstanceReq.ResourceTypesRegions = wrapResourceTypeRegions(d.config.ResourceTypes, d.config.ResourceRegions) + uploadUpdateCertificateInstanceResp, err := d.sdkClient.UploadUpdateCertificateInstance(uploadUpdateCertificateInstanceReq) + d.logger.Debug("sdk request 'ssl.UploadUpdateCertificateInstance'", slog.Any("request", uploadUpdateCertificateInstanceReq), slog.Any("response", uploadUpdateCertificateInstanceResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request 'ssl.UploadUpdateCertificateInstance': %w", err) + } + + if uploadUpdateCertificateInstanceResp.Response.DeployStatus == nil { + return errors.New("unexpected deployment job status") + } else if *uploadUpdateCertificateInstanceResp.Response.DeployStatus == 1 { + // deployRecordId = fmt.Sprintf("%d", *uploadUpdateCertificateInstanceResp.Response.DeployRecordId) + break + } + + time.Sleep(time.Second * 5) + } + + // // 循环查询证书云资源更新记录详情,等待任务状态变更 + // for { + // select { + // case <-ctx.Done(): + // return ctx.Err() + // default: + // } + + // describeHostUploadUpdateRecordDetailReq := tcssl.NewDescribeHostUploadUpdateRecordDetailRequest() + // describeHostUploadUpdateRecordDetailReq.DeployRecordId = common.StringPtr(deployRecordId) + // describeHostUploadUpdateRecordDetailResp, err := d.sdkClient.DescribeHostUpdateRecord(describeHostUploadUpdateRecordDetailReq) + // d.logger.Debug("sdk request 'ssl.DescribeHostUploadUpdateRecordDetail'", slog.Any("request", describeHostUploadUpdateRecordDetailReq), slog.Any("response", describeHostUploadUpdateRecordDetailResp)) + // if err != nil { + // return fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostUploadUpdateRecordDetail': %w", err) + // } + + // var runningCount, succeededCount, failedCount, totalCount int64 + // if describeHostUploadUpdateRecordDetailResp.Response.TotalCount == nil { + // return errors.New("unexpected deployment job status") + // } else { + // for _, record := range describeHostUploadUpdateRecordDetailResp.Response.DeployRecordDetail { + // if record.RunningTotalCount != nil { + // runningCount = *record.RunningTotalCount + // } + // if record.SuccessTotalCount != nil { + // succeededCount = *record.SuccessTotalCount + // } + // if record.FailedTotalCount != nil { + // failedCount = *record.FailedTotalCount + // } + // if record.TotalCount != nil { + // totalCount = *record.TotalCount + // } + // } + + // if succeededCount+failedCount == totalCount { + // break + // } + // } + + // d.logger.Info(fmt.Sprintf("waiting for deployment job completion (running: %d, succeeded: %d, failed: %d, total: %d) ...", runningCount, succeededCount, failedCount, totalCount)) + // time.Sleep(time.Second * 5) + // } + + return nil +} + +func createSDKClient(secretId, secretKey, endpoint string) (*tcssl.Client, error) { + credential := common.NewCredential(secretId, secretKey) + + cpf := profile.NewClientProfile() + if endpoint != "" { + cpf.HttpProfile.Endpoint = endpoint + } + + client, err := tcssl.NewClient(credential, "", cpf) + if err != nil { + return nil, err + } + + return client, nil +} + +func wrapResourceTypeRegions(resourceTypes, resourceRegions []string) []*tcssl.ResourceTypeRegions { + if len(resourceTypes) == 0 || len(resourceRegions) == 0 { + return nil + } + + // 仅以下云资源类型支持地域 + resourceTypesRequireRegion := []string{"apigateway", "clb", "cos", "tcb", "tke", "tse", "waf"} + + temp := make([]*tcssl.ResourceTypeRegions, 0) + for _, resourceType := range resourceTypes { + if slices.Contains(resourceTypesRequireRegion, resourceType) { + temp = append(temp, &tcssl.ResourceTypeRegions{ + ResourceType: common.StringPtr(resourceType), + Regions: common.StringPtrs(resourceRegions), + }) + } + } + + return temp +} diff --git a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx index 16e587ea..baf4dcf4 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx @@ -87,6 +87,7 @@ import DeployNodeConfigFormTencentCloudGAAPConfig from "./DeployNodeConfigFormTe import DeployNodeConfigFormTencentCloudSCFConfig from "./DeployNodeConfigFormTencentCloudSCFConfig"; import DeployNodeConfigFormTencentCloudSSLConfig from "./DeployNodeConfigFormTencentCloudSSLConfig"; import DeployNodeConfigFormTencentCloudSSLDeployConfig from "./DeployNodeConfigFormTencentCloudSSLDeployConfig"; +import DeployNodeConfigFormTencentCloudSSLUpdateConfig from "./DeployNodeConfigFormTencentCloudSSLUpdateConfig"; import DeployNodeConfigFormTencentCloudVODConfig from "./DeployNodeConfigFormTencentCloudVODConfig"; import DeployNodeConfigFormTencentCloudWAFConfig from "./DeployNodeConfigFormTencentCloudWAFConfig"; import DeployNodeConfigFormUCloudUCDNConfig from "./DeployNodeConfigFormUCloudUCDNConfig.tsx"; @@ -347,6 +348,8 @@ const DeployNodeConfigForm = forwardRef; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SSL_DEPLOY: return ; + case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SSL_UPDATE: + return ; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_VOD: return ; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_WAF: diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCASDeployConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCASDeployConfig.tsx index f16a0c79..be1747e8 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCASDeployConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCASDeployConfig.tsx @@ -69,6 +69,10 @@ const DeployNodeConfigFormAliyunCASDeployConfig = ({ name={formName} onValuesChange={handleFormChange} > + + } /> + + - - - } /> - ); }; diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLDeployConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLDeployConfig.tsx index 37c82584..1a104bf2 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLDeployConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLDeployConfig.tsx @@ -65,6 +65,10 @@ const DeployNodeConfigFormTencentCloudSSLDeployConfig = ({ name={formName} onValuesChange={handleFormChange} > + + } /> + + - - - } /> - ); }; diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLUpdateConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLUpdateConfig.tsx new file mode 100644 index 00000000..6c0fe497 --- /dev/null +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLUpdateConfig.tsx @@ -0,0 +1,130 @@ +import { useTranslation } from "react-i18next"; +import { Alert, Form, type FormInstance, Input, Switch } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod/v4"; + +import MultipleSplitValueInput from "@/components/MultipleSplitValueInput"; + +type DeployNodeConfigFormTencentCloudSSLUpdateConfigFieldValues = Nullish<{ + endpoint?: string; + certificateId: string; + resourceTypes: string; + resourceRegions?: string; + isReplaced?: boolean; +}>; + +export type DeployNodeConfigFormTencentCloudSSLUpdateConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: DeployNodeConfigFormTencentCloudSSLUpdateConfigFieldValues; + onValuesChange?: (values: DeployNodeConfigFormTencentCloudSSLUpdateConfigFieldValues) => void; +}; + +const MULTIPLE_INPUT_SEPARATOR = ";"; + +const initFormModel = (): DeployNodeConfigFormTencentCloudSSLUpdateConfigFieldValues => { + return {}; +}; + +const DeployNodeConfigFormTencentCloudSSLUpdateConfig = ({ + form: formInst, + formName, + disabled, + initialValues, + onValuesChange, +}: DeployNodeConfigFormTencentCloudSSLUpdateConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + endpoint: z.string().nullish(), + certificateId: z + .string(t("workflow_node.deploy.form.tencentcloud_ssl_update_certificate_id.placeholder")) + .nonempty(t("workflow_node.deploy.form.tencentcloud_ssl_update_certificate_id.placeholder")), + resourceTypes: z.string(t("workflow_node.deploy.form.tencentcloud_ssl_update_resource_types.placeholder")).refine((v) => { + if (!v) return false; + return String(v) + .split(MULTIPLE_INPUT_SEPARATOR) + .every((e) => !!e.trim()); + }, t("workflow_node.deploy.form.tencentcloud_ssl_update_resource_types.placeholder")), + resourceRegions: z.string(t("workflow_node.deploy.form.tencentcloud_ssl_update_resource_regions.placeholder")).refine((v) => { + if (!v) return false; + return String(v) + .split(MULTIPLE_INPUT_SEPARATOR) + .every((e) => !!e.trim()); + }, t("workflow_node.deploy.form.tencentcloud_ssl_update_resource_regions.placeholder")), + isReplaced: z.boolean().nullish(), + }); + const formRule = createSchemaFieldRule(formSchema); + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( +
+ + } /> + + + } + > + + + + } + > + + + + } + > + + + + } + > + + + + + + +
+ ); +}; + +export default DeployNodeConfigFormTencentCloudSSLUpdateConfig; diff --git a/ui/src/domain/provider.ts b/ui/src/domain/provider.ts index 1100e797..fb1e2e12 100644 --- a/ui/src/domain/provider.ts +++ b/ui/src/domain/provider.ts @@ -455,6 +455,7 @@ export const DEPLOYMENT_PROVIDERS = Object.freeze({ TENCENTCLOUD_SCF: `${ACCESS_PROVIDERS.TENCENTCLOUD}-scf`, TENCENTCLOUD_SSL: `${ACCESS_PROVIDERS.TENCENTCLOUD}-ssl`, TENCENTCLOUD_SSL_DEPLOY: `${ACCESS_PROVIDERS.TENCENTCLOUD}-ssldeploy`, + TENCENTCLOUD_SSL_UPDATE: `${ACCESS_PROVIDERS.TENCENTCLOUD}-sslupdate`, TENCENTCLOUD_VOD: `${ACCESS_PROVIDERS.TENCENTCLOUD}-vod`, TENCENTCLOUD_WAF: `${ACCESS_PROVIDERS.TENCENTCLOUD}-waf`, UCLOUD_UCDN: `${ACCESS_PROVIDERS.UCLOUD}-ucdn`, @@ -543,6 +544,7 @@ export const deploymentProvidersMap: Maphttps://cloud.tencent.com/document/product/400/91667", "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.title": "Change Tencent Cloud resource IDs", "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.placeholder": "Please enter Tencent Cloud resouce ID", + "workflow_node.deploy.form.tencentcloud_ssl_update.guide": "TIPS: You need to go to the Tencent Cloud console to check the actual deployment results by yourself, because Tencent Cloud deployment tasks are running asynchronously.", + "workflow_node.deploy.form.tencentcloud_ssl_update_endpoint.label": "Tencent Cloud SSL API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_ssl_update_endpoint.placeholder": "Please enter Tencent Cloud SSL API endpoint (e.g. ssl.intl.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_ssl_update_endpoint.tooltip": "
  • ssl.intl.tencentcloudapi.com for Tencent Cloud International
  • ssl.tencentcloudapi.com for Tencent Cloud in China
", + "workflow_node.deploy.form.tencentcloud_ssl_update_certificate_id.label": "Tencent Cloud SSL certificate ID", + "workflow_node.deploy.form.tencentcloud_ssl_update_certificate_id.placeholder": "Please enter Tencent Cloud SSL certificate ID", + "workflow_node.deploy.form.tencentcloud_ssl_update_certificate_id.tooltip": "For more information, see https://console.cloud.tencent.com/certoverview", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_types.label": "Tencent Cloud resource types", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_types.placeholder": "Please enter Tencent Cloud resource types (separated by semicolons)", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_types.tooltip": "For more information, see https://www.tencentcloud.com/document/product/1007/57981", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_types.multiple_input_modal.title": "Change Tencent Cloud resource types", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_types.multiple_input_modal.placeholder": "Please enter Tencent Cloud resource type", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_regions.label": "Tencent Cloud resource regions (Optional)", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_regions.placeholder": "Please enter Tencent Cloud resource regions (separated by semicolons)", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_regions.tooltip": "For more information, see https://www.tencentcloud.com/document/product/1007/57981", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_regions.multiple_input_modal.title": "Change Tencent Cloud resource regions", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_regions.multiple_input_modal.placeholder": "Please enter Tencent Cloud resource region", + "workflow_node.deploy.form.tencentcloud_ssl_update_is_replaced.label": "Renewal certificate (certificate ID unchanged)", "workflow_node.deploy.form.tencentcloud_vod_endpoint.label": "Tencent Cloud VOD API endpoint (Optional)", "workflow_node.deploy.form.tencentcloud_vod_endpoint.placeholder": "Please enter Tencent Cloud VOD API endpoint (e.g. vod.intl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_vod_endpoint.tooltip": "
  • vod.intl.tencentcloudapi.com for Tencent Cloud International
  • vod.tencentcloudapi.com for Tencent Cloud in China
", diff --git a/ui/src/i18n/locales/zh/nls.provider.json b/ui/src/i18n/locales/zh/nls.provider.json index 865f5b48..36e01d37 100644 --- a/ui/src/i18n/locales/zh/nls.provider.json +++ b/ui/src/i18n/locales/zh/nls.provider.json @@ -7,8 +7,8 @@ "provider.aliyun": "阿里云", "provider.aliyun.alb": "阿里云 - 应用型负载均衡 ALB", "provider.aliyun.apigw": "阿里云 - API 网关", - "provider.aliyun.cas_upload": "阿里云 - 上传到数字证书管理服务 CAS", "provider.aliyun.cas_deploy": "阿里云 - 通过数字证书管理服务 CAS 创建部署任务", + "provider.aliyun.cas_upload": "阿里云 - 上传到数字证书管理服务 CAS", "provider.aliyun.cdn": "阿里云 - 内容分发网络 CDN", "provider.aliyun.clb": "阿里云 - 传统型负载均衡 CLB", "provider.aliyun.dcdn": "阿里云 - 全站加速 DCDN", @@ -143,8 +143,9 @@ "provider.tencentcloud.eo": "腾讯云 - 边缘安全加速平台 EdgeOne", "provider.tencentcloud.gaap": "腾讯云 - 全球应用加速 GAAP", "provider.tencentcloud.scf": "腾讯云 - 云函数 SCF", - "provider.tencentcloud.ssl_upload": "腾讯云 - 上传到 SSL 证书服务", "provider.tencentcloud.ssl_deploy": "腾讯云 - 通过 SSL 证书服务创建部署任务", + "provider.tencentcloud.ssl_update": "腾讯云 - 通过 SSL 证书服务更新云资源证书", + "provider.tencentcloud.ssl_upload": "腾讯云 - 上传到 SSL 证书服务", "provider.tencentcloud.vod": "腾讯云 - 云点播 VOD", "provider.tencentcloud.waf": "腾讯云 - Web 应用防火墙 WAF", "provider.ucloud": "优刻得", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index 1639339a..28c0176c 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -168,7 +168,7 @@ "workflow_node.deploy.form.aliyun_cas_region.label": "阿里云 CAS 服务地域", "workflow_node.deploy.form.aliyun_cas_region.placeholder": "请输入阿里云 CAS 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_cas_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/ssl-certificate/developer-reference/endpoints", - "workflow_node.deploy.form.aliyun_cas_deploy.guide": "小贴士:由于阿里云证书部署任务是异步的,此节点若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往阿里云控制台查询。", + "workflow_node.deploy.form.aliyun_cas_deploy.guide": "小贴士:由于阿里云证书部署任务是异步的,此部署目标若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往阿里云控制台查询。", "workflow_node.deploy.form.aliyun_cas_deploy_region.label": "阿里云 CAS 服务地域", "workflow_node.deploy.form.aliyun_cas_deploy_region.placeholder": "请输入阿里云 CAS 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_cas_deploy_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/ssl-certificate/developer-reference/endpoints", @@ -740,7 +740,7 @@ "workflow_node.deploy.form.tencentcloud_ssl_endpoint.label": "腾讯云 SSL 接口端点(可选)", "workflow_node.deploy.form.tencentcloud_ssl_endpoint.placeholder": "请输入腾讯云 SSL 接口端点(例如:ssl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_ssl_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/41659", - "workflow_node.deploy.form.tencentcloud_ssl_deploy.guide": "小贴士:由于腾讯云证书部署任务是异步的,此节点若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往腾讯云控制台查询。", + "workflow_node.deploy.form.tencentcloud_ssl_deploy.guide": "小贴士:由于腾讯云证书部署任务是异步的,此部署目标若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往腾讯云控制台查询。", "workflow_node.deploy.form.tencentcloud_ssl_deploy_endpoint.label": "腾讯云 SSL 接口端点(可选)", "workflow_node.deploy.form.tencentcloud_ssl_deploy_endpoint.placeholder": "请输入腾讯云 SSL 接口端点(例如:ssl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_ssl_deploy_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/41659", @@ -756,6 +756,24 @@ "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/91667

注意与各产品本身的实例 ID 区分。", "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.title": "修改腾讯云云产品资源 ID", "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.placeholder": "请输入腾讯云云产品资源 ID", + "workflow_node.deploy.form.tencentcloud_ssl_update.guide": "小贴士:由于腾讯云证书部署任务是异步的,此部署目标若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往腾讯云控制台查询。", + "workflow_node.deploy.form.tencentcloud_ssl_update_endpoint.label": "腾讯云 SSL 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_ssl_update_endpoint.placeholder": "请输入腾讯云 SSL 接口端点(例如:ssl.tencentcloudapi.com)", + "workflow_node.deploy.form.tencentcloud_ssl_update_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/41659", + "workflow_node.deploy.form.tencentcloud_ssl_update_certificate_id.label": "腾讯云原证书 ID", + "workflow_node.deploy.form.tencentcloud_ssl_update_certificate_id.placeholder": "请输入腾讯云原证书 ID", + "workflow_node.deploy.form.tencentcloud_ssl_update_certificate_id.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/certoverview", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_types.label": "腾讯云云产品资源类型", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_types.placeholder": "请输入腾讯云云产品资源类型(多个值请用半角分号隔开)", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_types.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/91649", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_types.multiple_input_modal.title": "修改腾讯云云产品资源类型", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_types.multiple_input_modal.placeholder": "请输入腾讯云云产品资源类型", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_regions.label": "腾讯云云产品部署地域(可选)", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_regions.placeholder": "请输入腾讯云云产品部署地域(多个值请用半角分号隔开)", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_regions.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/91649", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_regions.multiple_input_modal.title": "修改腾讯云云产品资源类型", + "workflow_node.deploy.form.tencentcloud_ssl_update_resource_regions.multiple_input_modal.placeholder": "请输入腾讯云云产品资源类型", + "workflow_node.deploy.form.tencentcloud_ssl_update_is_replaced.label": "是否更新原证书(即证书 ID 保持不变)", "workflow_node.deploy.form.tencentcloud_vod_endpoint.label": "腾讯云云点播接口端点(可选)", "workflow_node.deploy.form.tencentcloud_vod_endpoint.placeholder": "请输入腾讯云云点播接口端点(例如:vod.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_vod_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/266/31755", From 928a0443cc3b8fcffa0798c85c0a0a040f79a4ed Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Mon, 23 Jun 2025 21:43:01 +0800 Subject: [PATCH 08/16] feat: new acme dns-01 provider: spaceship --- internal/applicant/providers.go | 17 +++++ internal/domain/access.go | 5 ++ internal/domain/provider.go | 2 + .../providers/spaceship/spaceship.go | 40 +++++++++++ ui/public/imgs/providers/spaceship.png | Bin 0 -> 6623 bytes ui/src/components/access/AccessForm.tsx | 3 + .../access/AccessFormSpaceshipConfig.tsx | 68 ++++++++++++++++++ ui/src/domain/access.ts | 6 ++ ui/src/domain/provider.ts | 4 ++ ui/src/i18n/locales/en/nls.access.json | 6 ++ ui/src/i18n/locales/en/nls.provider.json | 1 + ui/src/i18n/locales/zh/nls.access.json | 6 ++ ui/src/i18n/locales/zh/nls.provider.json | 1 + 13 files changed, 159 insertions(+) create mode 100644 pkg/core/ssl-applicator/acme-dns01/providers/spaceship/spaceship.go create mode 100644 ui/public/imgs/providers/spaceship.png create mode 100644 ui/src/components/access/AccessFormSpaceshipConfig.tsx diff --git a/internal/applicant/providers.go b/internal/applicant/providers.go index 1d5177bf..c5de24ef 100644 --- a/internal/applicant/providers.go +++ b/internal/applicant/providers.go @@ -38,6 +38,7 @@ import ( pPorkbun "github.com/certimate-go/certimate/pkg/core/ssl-applicator/acme-dns01/providers/porkbun" pPowerDNS "github.com/certimate-go/certimate/pkg/core/ssl-applicator/acme-dns01/providers/powerdns" pRainYun "github.com/certimate-go/certimate/pkg/core/ssl-applicator/acme-dns01/providers/rainyun" + pSpaceship "github.com/certimate-go/certimate/pkg/core/ssl-applicator/acme-dns01/providers/spaceship" pTencentCloud "github.com/certimate-go/certimate/pkg/core/ssl-applicator/acme-dns01/providers/tencentcloud" pTencentCloudEO "github.com/certimate-go/certimate/pkg/core/ssl-applicator/acme-dns01/providers/tencentcloud-eo" pUCloudUDNR "github.com/certimate-go/certimate/pkg/core/ssl-applicator/acme-dns01/providers/ucloud-udnr" @@ -582,6 +583,22 @@ func createApplicantProvider(options *applicantProviderOptions) (challenge.Provi return applicant, err } + case domain.ACMEDns01ProviderTypeSpaceship: + { + access := domain.AccessConfigForSpaceship{} + if err := xmaps.Populate(options.ProviderAccessConfig, &access); err != nil { + return nil, fmt.Errorf("failed to populate provider access config: %w", err) + } + + applicant, err := pSpaceship.NewChallengeProvider(&pSpaceship.ChallengeProviderConfig{ + ApiKey: access.ApiKey, + ApiSecret: access.ApiSecret, + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, + }) + return applicant, err + } + case domain.ACMEDns01ProviderTypeTencentCloud, domain.ACMEDns01ProviderTypeTencentCloudDNS, domain.ACMEDns01ProviderTypeTencentCloudEO: { access := domain.AccessConfigForTencentCloud{} diff --git a/internal/domain/access.go b/internal/domain/access.go index 29d07513..178a9d57 100644 --- a/internal/domain/access.go +++ b/internal/domain/access.go @@ -324,6 +324,11 @@ type AccessConfigForSlackBot struct { DefaultChannelId string `json:"defaultChannelId,omitempty"` } +type AccessConfigForSpaceship struct { + ApiKey string `json:"apiKey"` + ApiSecret string `json:"apiSecret"` +} + type AccessConfigForSSH struct { Host string `json:"host"` Port int32 `json:"port"` diff --git a/internal/domain/provider.go b/internal/domain/provider.go index 3688d5e3..6deedee8 100644 --- a/internal/domain/provider.go +++ b/internal/domain/provider.go @@ -74,6 +74,7 @@ const ( AccessProviderTypeRatPanel = AccessProviderType("ratpanel") AccessProviderTypeSafeLine = AccessProviderType("safeline") AccessProviderTypeSlackBot = AccessProviderType("slackbot") + AccessProviderTypeSpaceship = AccessProviderType("spaceship") AccessProviderTypeSSH = AccessProviderType("ssh") AccessProviderTypeSSLCOM = AccessProviderType("sslcom") AccessProviderTypeTelegramBot = AccessProviderType("telegrambot") @@ -159,6 +160,7 @@ const ( ACMEDns01ProviderTypePorkbun = ACMEDns01ProviderType(AccessProviderTypePorkbun) ACMEDns01ProviderTypePowerDNS = ACMEDns01ProviderType(AccessProviderTypePowerDNS) ACMEDns01ProviderTypeRainYun = ACMEDns01ProviderType(AccessProviderTypeRainYun) + ACMEDns01ProviderTypeSpaceship = ACMEDns01ProviderType(AccessProviderTypeSpaceship) ACMEDns01ProviderTypeTencentCloud = ACMEDns01ProviderType(AccessProviderTypeTencentCloud) // 兼容旧值,等同于 [ACMEDns01ProviderTypeTencentCloudDNS] ACMEDns01ProviderTypeTencentCloudDNS = ACMEDns01ProviderType(AccessProviderTypeTencentCloud + "-dns") ACMEDns01ProviderTypeTencentCloudEO = ACMEDns01ProviderType(AccessProviderTypeTencentCloud + "-eo") diff --git a/pkg/core/ssl-applicator/acme-dns01/providers/spaceship/spaceship.go b/pkg/core/ssl-applicator/acme-dns01/providers/spaceship/spaceship.go new file mode 100644 index 00000000..c739c11c --- /dev/null +++ b/pkg/core/ssl-applicator/acme-dns01/providers/spaceship/spaceship.go @@ -0,0 +1,40 @@ +package spaceship + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/providers/dns/spaceship" + + "github.com/certimate-go/certimate/pkg/core" +) + +type ChallengeProviderConfig struct { + ApiKey string `json:"apiKey"` + ApiSecret string `json:"apiSecret"` + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int32 `json:"dnsTTL,omitempty"` +} + +func NewChallengeProvider(config *ChallengeProviderConfig) (core.ACMEChallenger, error) { + if config == nil { + return nil, errors.New("the configuration of the acme challenge provider is nil") + } + + providerConfig := spaceship.NewDefaultConfig() + providerConfig.APIKey = config.ApiKey + providerConfig.APISecret = config.ApiSecret + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = int(config.DnsTTL) + } + + provider, err := spaceship.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/ui/public/imgs/providers/spaceship.png b/ui/public/imgs/providers/spaceship.png new file mode 100644 index 0000000000000000000000000000000000000000..79d6fe2ae65d07e1a94e6b155ce5d1b1878b516b GIT binary patch literal 6623 zcmV<586f6~P)uHL9$%*W>&% zM0pYwC2MVWEi{WrN>?^YgxK5ZDKBF-I%zC0St~F^E-*eSE>kctIV><$^!Ds7FGKkM z|1v#={r>m1#q8_y{Kd%FF+H>@Hj?xD{x2{xFFTkpJfr*l@Gde*^Yrv8FJC7vcPcMU z|Ns9gGjn-?o;5spL{@_(E^RVItnu{zFFA@tWS57FmoYV5CoNquOPnk&I~gBJ0|XT( zFmt%O#wsf_Hd2Q!ID{=UYcMlHF-oH@JFqS}p)_HfFg>X=TAVOKoHJph`1$yBb$~KV zsuC7L{Qv(kL!>Y?QP@_$DuDD=$eaM29alVx_6XEHs5KIh7nBF)KHk zGgFi^Q>xY2-!fdJSX*Z@O_MJ?rdC>fE;)TeM`$oJO)Wd6VP%9aIFKnWYV`Q@DKdJT zqs1mKW~aI0Dl&c^C~Y%jrywCJKtfWryxCM~r{Lr4pP{TWLXb04rC(uf?eXg)B{4Kv zsx(@b`~Cm^{r~Ol?J-B0mYlgXXsQ1G`zkG1CM!KHHi0}oNrQ={G&xHxIczF2g+oYo z{QUfagN!*kMJz8__xb-gajGjdeRFn`GHa#4!pki-ekC$*CNO0#REkPccq=r4E{|<{~9aFfctYXQ3e^L87YJ zKU18Jk)1C;u+GukEiXtbFI+EPl;r5=Cnz*7H+4BpoJL!pFFlVYJ%lVXf;()XA~$*` zIczL2cpW2IU}upmH=rgjQZ6q|BQ<~>K5-~2S|uxJD?45(J$)rKQ79`WbNgpSQ^@&H@Z0^9|fhT@G_kWN$__^Syg|}GlJaUK555q0AujIF-`4$YO}}H@3l1VK6KDWG%Wh==(lg53}m&xtl6m@M4D_DR}VM!EuAl z@H$FPU7L!A6Je+<;2?|3B5x34`-g2NUPClGbrQk|In@Xw#~SY8J{N2=@dNHHE(D%5 z+H}G&%0ZUR?FCcrizj}-1(%%E2u|&pxL^0h6R%mr!yk~AkK=4|$cT+*EI6fhkMqB&TBfKBjvrl*+iP7OF zn9FSlT`ML^AUIB=L1vrqRm;3Dk@yhWCb;3@6@oj7M;E>IZg+|JJ}roVdmM54aC^f8 zNxbJ4;ilrd-nGv%bokHP86}9Vx?{SV`hqQ|)e9$HcPkj&I~B*@&C1LSJL%7KUllK? ziZ$KG1A+%Mt8YzeXy~dCe|SPt6d33$VKR^16L?ky1(_0O6PI}(>UkTP;eQc{jqXT* z9Z=%Mix+=N!EqG)fV`Qw4YV$Set|)9EzQ?=>ounT=@QSY73c;g#yGntY<>Tl;D7xK zSQ9+*&m+&AIRi3+SFfga;|p=$e6w!d1ESU^O&YyRAfB6<+2M=oY#P%&S)7eF`s@kB zmuy65Q!ZK^eRf-b7Vu>#Q{a&lym$nHNf*YLg1OuW#lZ~?9^z#8%uHXhwsNxOHj5um zxI;umEKw%dDrw&^1Sa4S4kL)fs|T;{0YBhAV6A6`iksifG$sc4lzpPO>uNSNxGx0v zm3Xx!jC$>yDn4y5L9l|5(+pXQN(I?>CS09h4*ar-Eynl(DF+vG#U&e=!!t9pIy%4} zqDXs^74{*Pednrigo!e4f4$%kvieO-$nVENVk$DLQM}4uas=QkpnX46bX+qSChyM9 zz7qtQv#nvD=Yo4DHo|d6nA;#eIFHGU=*U7<<{J^ANQ;n!T?#?4*&QHkV^&)xzWY?X zlgV7}OTlG|?Fz+b27`T*7fk7^{lg*F@C+zo0da6Z@Q4v+nOM4lS?hz7)`T`Z!oOoO z)6V)T4B#3hWiZeR-?FT%jm-jD*PY|Xv%Rt{U)FP~H*9ByN!J8lKqsGXf~N)-7q5T7 z6&(MWDJfH&rC|69urDmz8G`1nuH&BBJ!M<&b0jA6ev|W{_(2jEVElD|W>}dbLXl-4 z;ZrDbN2XzsOt6~Q;e4l!d@D>0Q9;0A6|iB0fW$}Q$5aTkV*-I!r#&vMeXbGBz8SYl4BfXK(n>uS9E zgQLmI4qP~a*v&AmA0y8I4G+iU<}`Nj*r`*Kij#_qbJjl!#Wf2ghO#n)Wn~dl%wXW; zr*RYocxkg|^KOk#O*I0&ZX>t{9c?VT%P8>-yBS7z*r_=H?>Q7a z^--gEXV|GML*JFp$^w_~u zA#u*090+_@oOt3?pbZy>ofF9M{TOR{997fo=~ZHey+ZngQQ{ewiNqt#iOEhQ7bVWg zIaD0X5;y*Q%8+Ig&gZ1%bB?&Gn|NN$JYI9Zi6QW7m#G;|xM++WjPO)QoRfoK)^Flf zVUq0%TQKD1Z0B&C)as_FW}j*T4zZkDMv+b@UI>Q72&Mv`Azcbam6H>fQyeM?|2Z@B znnGa{&gX1TGZZD1*F`nA_>gdj88*3;Y)82>j9X$4crYo)#T6IdZQL0qc@p7kGjc~D z#}LTL@=MmIG?n|bSiwExni5;OW_T=>cq#;L5YXmjKH2KKRbg{-Z8yMz7MK;OkBVwZ zvA%h&^3v&cV@#1jb^sQgKZu)&f`cE84Q7Sj!hg>6&nz2dO3X1tz+~b?81g&7>&Q2L zfK&Dfc)dp7gfMHD5UGOOX$)d#%pe1gfEPM`5bRi((^LPs`I~jDr-H-<2LCeOA*M0r zP!&NGd=9EICF$k5(&px-Xfxa+tq}&7kf}~Pj5tHi>BUsw9M;re)>yG%o z2{0eo2K2iT4$L|ksUBKd-c)atExK$`(CRT%U@9?n(7Qg?2pg%hiRwwN# z&Us((U8cl$)TmKqlAD ztm5KZw;I1Y1@Mp|z8o`ra&Li5D(rSzZs24V<)>vypvuZ%`lU&h%i`q)Y#-(G#=V5L=0$(;|=#{4F)DH~uoS7&xaz|V@ zjWEou2G-rsP=V$XdkI=4iu@M6o=~Y4V=X1kK0F@JCz`E{$1tTVa{S~?gw5PEUXHQZ zB+TeP@f_6ZnIllAk$c?;vl>E2b0PA<*ZsnZPNaWW?NcMD@zEqVd-0+?;fY9H9#tyK zRqC;LRmP>g_RLMkTo@R=w46%Jcs4wTNPK4Ixic1>MmJMV@ekZk?!wSen)ps~Vxp#5 zz}xMGp2&PWdDTA6&CNcg?7F&;+!T5)T^+9$xh5nO#>cZ|QSmlg%^=Gn@tK)3N%tI? zm>A+>?mm|Dq=np2TI_@hLB*Xe8jThkyZd;Jr;kqv?0uC{DJ|u7q2TdSOF2Efg*q?M}tW zxM((NzLKtHE7e+&Qu_=T=xNB^aen3w)M_NNSO|v5WZ=B;JSs52sMY4fqY-8+bLsKy z+}svAJB6-np)0kyd^%kudKNr}km0oh1vPbsiNsJiIEFf)Q(+Rz_H)%+=|~%S3Xz2yP?HB_Uqf z-xw3@G?aJ;nV4i*EOLZtd9mSD7Kwd)nnIe4_bHv)W!se^Is?mPcIWEawea@wCr^mt zRedD(CNBb>M#wu*&HU=WU;T44>j&rk;gf>D{Oz~U(C|Bg*j>9SJa$!xE3#{nvo%ec zD6CwaQXlWC)M9!imYXYb<;&ys@hXNAlN4ZjT*y~RYhC#&m7Xue^q5@KT8Pzplb5kf z@I(^cF%dGqy-%?3kItdL1+%_u#KRL4X=1^uSX{j8pr#3Xyi1Q`Q3qxCP?-$JwB4>E zImTDw@ven@9ahUPl1g0?R5+Zxcm8-W^nOePL;aJo_Q)P(>+BEA7W$vsjSJT)i{6d$tU(F3iMKb;bci> zk)KS*&!0TGDD32TX)ESb;4O988<`cDb*-Qi)7gX}GXZ}Y^N%0)eLrm2y@UVxB3wL= z`NiwWr-yx#D2V@XrzXC@-7gtW{KW5cX?NCKJvP_xW0lLXD+w4sGE=9Gbn3?Rk|zb- z8Iw23F#QoHIsS3h-i+1^rz-{e*52?kxQJFyB;>C)Z~i4FX4qfr#Nxcz37;?zdSc>4 z`$gruFkBgryBJ#VMNd{?n6@+p<1e2p#c`Q?x?X-M6TXv6GiPh>)HrC;ZZ)Gwk zUy-ou?EP?^Os&`IYYmeloi3#tuE_NT?wkBvRJdLxagnylTZ=OE_>puWR&Y`-cNOAJ z`KnGU7vN>fW^b9jW!jdBMD6%$$Mt`Hy*_W;ut9@{X~gpumFzkwz!%J`sk5KAD#OL; zWD|B`5iaZ2Gemk({*m-6e(96P3o)sy(-rsS37AllA#K%54KA(t$+=RjAWSapZpG8H z0_1(d%cg-lA4OidWAlx#Z?N|5zgKeqsQp1~_({QSo;AP9UY}qnx zKFYgt$CoQ(+}6MS*FVOW?;Mnf4`;rm!9xZuNW@mz&&Bc9W1M<@hWlPQj$OGV$I`DA z;JC{b7rk)&cno)SPscl<)sC3V;3CDh9}B=EIqvY8oQ@O-9j(ibav?F~g~Ty#Km6kS z_5%MwgBA?aVD6JQ4rdnG?}Ue-jqX?6{g#)N#;07`l+}@Me@TdSJ6(%N+dkP|7z=`fvZS;683E6q50NLv%!ifhhMV&gx5I9aZXR6}RB@H&S*798(9tqExl~;@ zRHS9pY8kK<3ALTxBG_s4e66=kt1T?76{&=sI+;)|>@1WERno}4ot*)~0LOp;v-mq% zJ>dBeI3{Mx+h4By)y>WMW|G@)2c46vVrexs@T-F6Ra057ho=UXXXqfKJYLRM@jHd8PF-iKx0J8Kgb7%iqfjX9?UL}8cPM!N#HF)hZU7$R=IreD z=xgVL_j$LyG#X7*jmGD3ow~BLw7eY>YYVk-(%|!TIxTz#6<;MP6y>V4g({Jh?=AH9 z7Q!x6+u5p<2FMZH+WNb^Pxu{E;`u9MmR?-B(hcClzZ`ZB-*t}%XZPli>gwteO=)$C zdT8#@cCA*ZBgUl`snYnD;o2K2TAP*bK%A!c+ek(UQ<6q|$@3^VKaJY~DpsMoVrOb7PO zZD!Z)Fzp`9EP$({j1wBM42JhW*k>jtGEZOe=0kwDZTmX`yB)q+6ELnJi7jyxBkA$aBClenya1q?R{Z+*H zMnxGLP2}Y>98E0x*KKXR;kKUjOn3uwrxTGc67FG=aBz|@9Pe1*%;q%Ww|91MrZR5s`gZt=S6_1!$#)U&9B7cJ7NG7&4ez$nr z0IRYE8vowzy`O&i2;k{|e>iU3*U;yCvDHYeCf%qM%JpVAI<`4N;{M+7`C&qy{`cwQ z#$B9p7{-@aox!E1GzG(L1abL}uMqx-sOjI1`xU0u&AciquyJM?6T`X@0GVGM3~@jD z=!0*+9fziKUS3rdkLom)7>zNb7Fz8czz6!(!5{oYxDO9Fe}D6^GcAb9YYc2o46`}F z@m0bfeel5tA00UG{r7o!=!f9EYO`#DA+b0A*_*(?VN~COd-E{t`!r1~1xHo(Ow4e6 dwebH7FaTFL&=(M$y*2;<002ovPDHLkV1gFws=NRI literal 0 HcmV?d00001 diff --git a/ui/src/components/access/AccessForm.tsx b/ui/src/components/access/AccessForm.tsx index 09553347..d49fe661 100644 --- a/ui/src/components/access/AccessForm.tsx +++ b/ui/src/components/access/AccessForm.tsx @@ -68,6 +68,7 @@ import AccessFormRainYunConfig from "./AccessFormRainYunConfig"; import AccessFormRatPanelConfig from "./AccessFormRatPanelConfig"; import AccessFormSafeLineConfig from "./AccessFormSafeLineConfig"; import AccessFormSlackBotConfig from "./AccessFormSlackBotConfig"; +import AccessFormSpaceshipConfig from "./AccessFormSpaceshipConfig"; import AccessFormSSHConfig from "./AccessFormSSHConfig"; import AccessFormSSLComConfig from "./AccessFormSSLComConfig"; import AccessFormTelegramBotConfig from "./AccessFormTelegramBotConfig"; @@ -301,6 +302,8 @@ const AccessForm = forwardRef(({ className, return ; case ACCESS_PROVIDERS.SLACKBOT: return ; + case ACCESS_PROVIDERS.SPACESHIP: + return ; case ACCESS_PROVIDERS.SSH: return ; case ACCESS_PROVIDERS.TELEGRAMBOT: diff --git a/ui/src/components/access/AccessFormSpaceshipConfig.tsx b/ui/src/components/access/AccessFormSpaceshipConfig.tsx new file mode 100644 index 00000000..7437a2f6 --- /dev/null +++ b/ui/src/components/access/AccessFormSpaceshipConfig.tsx @@ -0,0 +1,68 @@ +import { useTranslation } from "react-i18next"; +import { Form, type FormInstance, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod/v4"; + +import { type AccessConfigForSpaceship } from "@/domain/access"; + +type AccessFormSpaceshipConfigFieldValues = Nullish; + +export type AccessFormSpaceshipConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: AccessFormSpaceshipConfigFieldValues; + onValuesChange?: (values: AccessFormSpaceshipConfigFieldValues) => void; +}; + +const initFormModel = (): AccessFormSpaceshipConfigFieldValues => { + return { + apiKey: "", + apiSecret: "", + }; +}; + +const AccessFormSpaceshipConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormSpaceshipConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + apiKey: z.string().nonempty(t("access.form.spaceship_api_key.placeholder")), + apiSecret: z.string().nonempty(t("access.form.spaceship_api_secret.placeholder")), + }); + const formRule = createSchemaFieldRule(formSchema); + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( +
+ } + > + + + + } + > + + +
+ ); +}; + +export default AccessFormSpaceshipConfig; diff --git a/ui/src/domain/access.ts b/ui/src/domain/access.ts index a2dbde73..df0e8a06 100644 --- a/ui/src/domain/access.ts +++ b/ui/src/domain/access.ts @@ -62,6 +62,7 @@ export interface AccessModel extends BaseModel { | AccessConfigForRatPanel | AccessConfigForSafeLine | AccessConfigForSlackBot + | AccessConfigForSpaceship | AccessConfigForSSH | AccessConfigForSSLCom | AccessConfigForTelegramBot @@ -389,6 +390,11 @@ export type AccessConfigForSlackBot = { defaultChannelId?: string; }; +export type AccessConfigForSpaceship = { + apiKey: string; + apiSecret: string; +}; + export type AccessConfigForSSH = { host: string; port: number; diff --git a/ui/src/domain/provider.ts b/ui/src/domain/provider.ts index fb1e2e12..12511f81 100644 --- a/ui/src/domain/provider.ts +++ b/ui/src/domain/provider.ts @@ -65,6 +65,7 @@ export const ACCESS_PROVIDERS = Object.freeze({ RATPANEL: "ratpanel", SAFELINE: "safeline", SLACKBOT: "slackbot", + SPACESHIP: "spaceship", SSH: "ssh", SSLCOM: "sslcom", TELEGRAMBOT: "telegrambot", @@ -164,6 +165,7 @@ export const accessProvidersMap: Maphttps://www.youtube.com/watch?v=Uz5Yi5C2pwQ", + "access.form.spaceship_api_key.label": "Spaceship API key", + "access.form.spaceship_api_key.placeholder": "Please enter Spaceship API key", + "access.form.spaceship_api_key.tooltip": "For more information, see https://www.spaceship.com/application/api-manager/", + "access.form.spaceship_api_secret.label": "Spaceship API secret", + "access.form.spaceship_api_secret.placeholder": "Please enter Spaceship API secret", + "access.form.spaceship_api_secret.tooltip": "For more information, see https://www.spaceship.com/application/api-manager/", "access.form.ssh_host.label": "Server host", "access.form.ssh_host.placeholder": "Please enter server host", "access.form.ssh_port.label": "Server port", diff --git a/ui/src/i18n/locales/en/nls.provider.json b/ui/src/i18n/locales/en/nls.provider.json index f2a07351..fe76a727 100644 --- a/ui/src/i18n/locales/en/nls.provider.json +++ b/ui/src/i18n/locales/en/nls.provider.json @@ -130,6 +130,7 @@ "provider.ratpanel.site": "RatPanel - Website", "provider.safeline": "SafeLine", "provider.slackbot": "Slack Bot", + "provider.spaceship": "Spaceship", "provider.ssh": "Remote host (SSH)", "provider.sslcom": "SSL.com", "provider.telegrambot": "Telegram Bot", diff --git a/ui/src/i18n/locales/zh/nls.access.json b/ui/src/i18n/locales/zh/nls.access.json index a3852926..837ccc17 100644 --- a/ui/src/i18n/locales/zh/nls.access.json +++ b/ui/src/i18n/locales/zh/nls.access.json @@ -387,6 +387,12 @@ "access.form.slackbot_default_channel_id.label": "默认的 Slack 频道 ID(可选)", "access.form.slackbot_default_channel_id.placeholder": "请输入默认的 Slack 频道 ID", "access.form.slackbot_default_channel_id.tooltip": "如何获取此参数?请参阅 https://www.youtube.com/watch?v=Uz5Yi5C2pwQ", + "access.form.spaceship_api_key.label": "Spaceship API Key", + "access.form.spaceship_api_key.placeholder": "请输入 Spaceship API Key", + "access.form.spaceship_api_key.tooltip": "这是什么?请参阅 https://www.spaceship.com/application/api-manager/", + "access.form.spaceship_api_secret.label": "Spaceship API Secret", + "access.form.spaceship_api_secret.placeholder": "请输入 Spaceship API Secret", + "access.form.spaceship_api_secret.tooltip": "这是什么?请参阅 https://www.spaceship.com/application/api-manager/", "access.form.ssh_host.label": "服务器地址", "access.form.ssh_host.placeholder": "请输入服务器地址", "access.form.ssh_port.label": "服务器端口", diff --git a/ui/src/i18n/locales/zh/nls.provider.json b/ui/src/i18n/locales/zh/nls.provider.json index 36e01d37..fa16398a 100644 --- a/ui/src/i18n/locales/zh/nls.provider.json +++ b/ui/src/i18n/locales/zh/nls.provider.json @@ -130,6 +130,7 @@ "provider.ratpanel.site": "耗子面板 - 网站", "provider.safeline": "雷池", "provider.slackbot": "Slack 机器人", + "provider.spaceship": "Spaceship", "provider.ssh": "远程主机(SSH)", "provider.sslcom": "SSL.com", "provider.telegrambot": "Telegram 机器人", From a239a9cd1d7a882d5ddc2a1f554f4045e18d31b0 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Mon, 23 Jun 2025 21:45:24 +0800 Subject: [PATCH 09/16] build: inject tag version to .env --- .github/workflows/push_image.yml | 4 ++++ .github/workflows/push_image_next.yml | 4 ++++ .github/workflows/release.yml | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/push_image.yml b/.github/workflows/push_image.yml index 30351163..0b5cb04a 100644 --- a/.github/workflows/push_image.yml +++ b/.github/workflows/push_image.yml @@ -53,6 +53,10 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} + - name: Inject tag version of UI + run: | + echo "VITE_APP_VERSION=${GITHUB_REF#refs/tags/}" > ./ui/.env + - name: Build and push Docker image uses: docker/build-push-action@v6 with: diff --git a/.github/workflows/push_image_next.yml b/.github/workflows/push_image_next.yml index 635c238a..0afe2b01 100644 --- a/.github/workflows/push_image_next.yml +++ b/.github/workflows/push_image_next.yml @@ -51,6 +51,10 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} + - name: Inject tag version of UI + run: | + echo "VITE_APP_VERSION=${GITHUB_REF#refs/tags/}" > ./ui/.env + - name: Build and push Docker image uses: docker/build-push-action@v6 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d08fa380..249d6b3c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,8 +19,9 @@ jobs: with: node-version: 20.11.0 - - name: Build WebUI + - name: Build UI run: | + echo "VITE_APP_VERSION=${GITHUB_REF#refs/tags/}" > ./ui/.env npm --prefix=./ui ci npm --prefix=./ui run build From 66479b019d215159b6629e10845970c230e34a64 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Mon, 23 Jun 2025 22:34:31 +0800 Subject: [PATCH 10/16] feat: db index --- migrations/1750687200_upgrade.go | 93 ++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 migrations/1750687200_upgrade.go diff --git a/migrations/1750687200_upgrade.go b/migrations/1750687200_upgrade.go new file mode 100644 index 00000000..f1b283b4 --- /dev/null +++ b/migrations/1750687200_upgrade.go @@ -0,0 +1,93 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/pocketbase/core" + m "github.com/pocketbase/pocketbase/migrations" +) + +func init() { + m.Register(func(app core.App) error { + tracer := NewTracer("(v0.3)1750687200") + tracer.Printf("go ...") + + // update collection `workflow_run` + { + collection, err := app.FindCollectionByNameOrId("qjp8lygssgwyqyz") + if err != nil { + return err + } + + // update collection data + if err := json.Unmarshal([]byte(`{ + "indexes": [ + "CREATE INDEX `+"`"+`idx_7ZpfjTFsD2`+"`"+` ON `+"`"+`workflow_run`+"`"+` (`+"`"+`workflowId`+"`"+`)" + ] + }`), &collection); err != nil { + return err + } + + if err := app.Save(collection); err != nil { + return err + } + + tracer.Printf("collection '%s' updated", collection.Name) + } + + // update collection `workflow_output` + { + collection, err := app.FindCollectionByNameOrId("bqnxb95f2cooowp") + if err != nil { + return err + } + + // update collection data + if err := json.Unmarshal([]byte(`{ + "indexes": [ + "CREATE INDEX `+"`"+`idx_BYoQPsz4my`+"`"+` ON `+"`"+`workflow_output`+"`"+` (`+"`"+`workflowId`+"`"+`)", + "CREATE INDEX `+"`"+`idx_O9zxLETuxJ`+"`"+` ON `+"`"+`workflow_output`+"`"+` (`+"`"+`runId`+"`"+`)", + "CREATE INDEX `+"`"+`idx_luac8Ul34G`+"`"+` ON `+"`"+`workflow_output`+"`"+` (`+"`"+`nodeId`+"`"+`)" + ] + }`), &collection); err != nil { + return err + } + + if err := app.Save(collection); err != nil { + return err + } + + tracer.Printf("collection '%s' updated", collection.Name) + } + + // update collection `workflow_logs` + { + collection, err := app.FindCollectionByNameOrId("pbc_1682296116") + if err != nil { + return err + } + + // update collection data + if err := json.Unmarshal([]byte(`{ + "indexes": [ + "CREATE INDEX `+"`"+`idx_IOlpy6XuJ2`+"`"+` ON `+"`"+`workflow_logs`+"`"+` (`+"`"+`workflowId`+"`"+`)", + "CREATE INDEX `+"`"+`idx_qVlTb2yl7v`+"`"+` ON `+"`"+`workflow_logs`+"`"+` (`+"`"+`runId`+"`"+`)", + "CREATE INDEX `+"`"+`idx_UL4tdCXNlA`+"`"+` ON `+"`"+`workflow_logs`+"`"+` (`+"`"+`nodeId`+"`"+`)" + ] + }`), &collection); err != nil { + return err + } + + if err := app.Save(collection); err != nil { + return err + } + + tracer.Printf("collection '%s' updated", collection.Name) + } + + tracer.Printf("done") + return nil + }, func(app core.App) error { + return nil + }) +} From 2a498edef7031eff5ef06c9bcda504a3af420eee Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Tue, 24 Jun 2025 10:26:58 +0800 Subject: [PATCH 11/16] chore(deps): upgrade gomod dependencies --- go.mod | 8 +- go.sum | 8 ++ .../tencentcloud_ssl_update.go | 84 ++++++++++--------- 3 files changed, 55 insertions(+), 45 deletions(-) diff --git a/go.mod b/go.mod index 489284dc..f9bd4fb6 100644 --- a/go.mod +++ b/go.mod @@ -49,13 +49,13 @@ require ( github.com/pocketbase/pocketbase v0.28.4 github.com/povsister/scp v0.0.0-20250504051308-e467f71ea63c github.com/qiniu/go-sdk/v7 v7.25.4 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1187 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1193 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1188 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1192 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1193 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.0.1163 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1192 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1193 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1172 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1189 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1193 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1191 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1183 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1182 diff --git a/go.sum b/go.sum index 7da97356..e574635c 100644 --- a/go.sum +++ b/go.sum @@ -831,6 +831,8 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1187 h1:x2q6BAFm2f+9YaE7/lGPWXL7HzRkovjoqOMbdtRdpBw= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1187/go.mod h1:GoIHP0ayv0QOWN4c9aUEaKi74lY/tbeJz7h5i8y2gdU= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1193 h1:zOWZKDVA3kvA5/b+AwKzDtz5ewdiibeKxVqtCFJSTNI= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1193/go.mod h1:ufxDBGyS3X/9QKkZzuOFKLNra9FmSfgAHBO/FlFZaTU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1188 h1:zzaIE12soTfyAgRvBYhb5bYxFXRCelvYXDEfvtkT5Y4= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1188/go.mod h1:qIWFhWbmMuUaWCCKVSkdJ1BzKEOqkMeo+uKYS6jJimQ= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1128/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= @@ -844,16 +846,22 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1189/go.mod github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1191/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1192 h1:3K6aJXXkjBLxqFYnBqAqFW5YqxmwMT0HR2F4gxQiNMU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1192/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1193 h1:anxhOjL4WrQDqUcX7eT8VEaQITiKWllKwsH1fEt6lBw= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1193/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1128 h1:mrJ5Fbkd7sZIJ5F6oRfh5zebPQaudPH9Y0+GUmFytYU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1128/go.mod h1:zbsYIBT+VTX4z4ocjTAdLBIWyNYj3z0BRqd0iPdnjsk= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.0.1163 h1:putqrH5n1SVRqFWHOylVqYI5yLQUjRTkHqZPLT2yeVY= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.0.1163/go.mod h1:aEWRXlAvovPUUoS3kVB/LVWEQ19WqzTj2lXGvR1YArY= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1192 h1:2430drceaOXASJZyVZ+e7QSzgBfgwSjDEDM5rh4046M= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1192/go.mod h1:JHZLo95Fde/0et2Ag2E5P6VmCZQIq74MClUtanJ4JcY= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1193 h1:VtXqRnzGz3KheXu2msNPvA/fUYQGsVVRC30WgyAUEqg= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1193/go.mod h1:42I1OwaedHR6Yvg7J6UYoOjNYUYfFqwaeEkvx3x+NZc= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1172 h1:6SUO0hTie3zxnUEMxmhnS1iRIXpAukSZV27Nrx4NwIk= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1172/go.mod h1:tmN4zfu70SD0iee3qfpc09NRLel30zGoAuzIs4X0Kfs= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1189 h1:Db7gmkey7On70PAohvrna6RMLZzLHRjbALxPlH5JC3c= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1189/go.mod h1:x+WlMCjbePO7M3R0qzKmrpmieUWrtsRpcKBDpxJNQ5A= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1193 h1:tmACSthp5JLjrdxzng6XFs4gfQcZHBTTVlXR0tO6hSk= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1193/go.mod h1:LWf5UPUl41EQICrq0jswgQEO/BtRQY+CxAI6X+i709o= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1191 h1:4l1Db+yFh9HgqNynYbG93khxLtXSBwnXZgNmc88jOE0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1191/go.mod h1:y8if4wInFJoO6PU0/741VEYREHPtfxljhJ5HFD2ZkEA= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1183 h1:3fvxkF/R1WaO937Wrx5ZCYoIof1X9sqSDXL218uRfJY= diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-ssl-update/tencentcloud_ssl_update.go b/pkg/core/ssl-deployer/providers/tencentcloud-ssl-update/tencentcloud_ssl_update.go index e12f894f..2fff2992 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-ssl-update/tencentcloud_ssl_update.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-ssl-update/tencentcloud_ssl_update.go @@ -189,7 +189,7 @@ func (d *SSLDeployerProvider) executeUpdateCertificateInstance(ctx context.Conte func (d *SSLDeployerProvider) executeUploadUpdateCertificateInstance(ctx context.Context, certPEM string, privkeyPEM string) error { // 更新证书内容并更新关联的云资源 // REF: https://cloud.tencent.com/document/product/400/119791 - // var deployRecordId string + var deployRecordId int64 for { select { case <-ctx.Done(): @@ -212,56 +212,58 @@ func (d *SSLDeployerProvider) executeUploadUpdateCertificateInstance(ctx context if uploadUpdateCertificateInstanceResp.Response.DeployStatus == nil { return errors.New("unexpected deployment job status") } else if *uploadUpdateCertificateInstanceResp.Response.DeployStatus == 1 { - // deployRecordId = fmt.Sprintf("%d", *uploadUpdateCertificateInstanceResp.Response.DeployRecordId) + deployRecordId = int64(*uploadUpdateCertificateInstanceResp.Response.DeployRecordId) break } time.Sleep(time.Second * 5) } - // // 循环查询证书云资源更新记录详情,等待任务状态变更 - // for { - // select { - // case <-ctx.Done(): - // return ctx.Err() - // default: - // } + // 循环查询证书云资源更新记录详情,等待任务状态变更 + // REF: https://cloud.tencent.com/document/product/400/120056 + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } - // describeHostUploadUpdateRecordDetailReq := tcssl.NewDescribeHostUploadUpdateRecordDetailRequest() - // describeHostUploadUpdateRecordDetailReq.DeployRecordId = common.StringPtr(deployRecordId) - // describeHostUploadUpdateRecordDetailResp, err := d.sdkClient.DescribeHostUpdateRecord(describeHostUploadUpdateRecordDetailReq) - // d.logger.Debug("sdk request 'ssl.DescribeHostUploadUpdateRecordDetail'", slog.Any("request", describeHostUploadUpdateRecordDetailReq), slog.Any("response", describeHostUploadUpdateRecordDetailResp)) - // if err != nil { - // return fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostUploadUpdateRecordDetail': %w", err) - // } + describeHostUploadUpdateRecordDetailReq := tcssl.NewDescribeHostUploadUpdateRecordDetailRequest() + describeHostUploadUpdateRecordDetailReq.DeployRecordId = common.Int64Ptr(deployRecordId) + describeHostUploadUpdateRecordDetailReq.Limit = common.Int64Ptr(200) + describeHostUploadUpdateRecordDetailResp, err := d.sdkClient.DescribeHostUploadUpdateRecordDetail(describeHostUploadUpdateRecordDetailReq) + d.logger.Debug("sdk request 'ssl.DescribeHostUploadUpdateRecordDetail'", slog.Any("request", describeHostUploadUpdateRecordDetailReq), slog.Any("response", describeHostUploadUpdateRecordDetailResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostUploadUpdateRecordDetail': %w", err) + } - // var runningCount, succeededCount, failedCount, totalCount int64 - // if describeHostUploadUpdateRecordDetailResp.Response.TotalCount == nil { - // return errors.New("unexpected deployment job status") - // } else { - // for _, record := range describeHostUploadUpdateRecordDetailResp.Response.DeployRecordDetail { - // if record.RunningTotalCount != nil { - // runningCount = *record.RunningTotalCount - // } - // if record.SuccessTotalCount != nil { - // succeededCount = *record.SuccessTotalCount - // } - // if record.FailedTotalCount != nil { - // failedCount = *record.FailedTotalCount - // } - // if record.TotalCount != nil { - // totalCount = *record.TotalCount - // } - // } + var runningCount, succeededCount, failedCount, totalCount int64 + if describeHostUploadUpdateRecordDetailResp.Response.DeployRecordDetail == nil { + return errors.New("unexpected deployment job status") + } else { + for _, record := range describeHostUploadUpdateRecordDetailResp.Response.DeployRecordDetail { + if record.RunningTotalCount != nil { + runningCount = *record.RunningTotalCount + } + if record.SuccessTotalCount != nil { + succeededCount = *record.SuccessTotalCount + } + if record.FailedTotalCount != nil { + failedCount = *record.FailedTotalCount + } + if record.TotalCount != nil { + totalCount = *record.TotalCount + } + } - // if succeededCount+failedCount == totalCount { - // break - // } - // } + if succeededCount+failedCount == totalCount { + break + } + } - // d.logger.Info(fmt.Sprintf("waiting for deployment job completion (running: %d, succeeded: %d, failed: %d, total: %d) ...", runningCount, succeededCount, failedCount, totalCount)) - // time.Sleep(time.Second * 5) - // } + d.logger.Info(fmt.Sprintf("waiting for deployment job completion (running: %d, succeeded: %d, failed: %d, total: %d) ...", runningCount, succeededCount, failedCount, totalCount)) + time.Sleep(time.Second * 5) + } return nil } From 4d42b06572b37c9eb1d5f864590de2aa60b53b59 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Tue, 24 Jun 2025 10:38:27 +0800 Subject: [PATCH 12/16] fix: #812 --- ui/src/domain/workflow.ts | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/ui/src/domain/workflow.ts b/ui/src/domain/workflow.ts index 415123c4..5304fe77 100644 --- a/ui/src/domain/workflow.ts +++ b/ui/src/domain/workflow.ts @@ -511,20 +511,40 @@ export const newNode = (nodeType: WorkflowNodeType, options: NewNodeOptions = {} type CloneNodeOptions = { withCopySuffix?: boolean; + nodeIdMap?: Map; }; -export const cloneNode = (sourceNode: WorkflowNode, { withCopySuffix }: CloneNodeOptions = { withCopySuffix: true }): WorkflowNode => { +export const cloneNode = (sourceNode: WorkflowNode, { withCopySuffix, nodeIdMap }: CloneNodeOptions = { withCopySuffix: true }): WorkflowNode => { const { produce } = new Immer({ autoFreeze: false }); const deepClone = (node: WorkflowNode): WorkflowNode => { return produce(node, (draft) => { draft.id = nanoid(); + nodeIdMap ??= new Map(); // 原节点 ID 映射到新节点 ID + nodeIdMap.set(node.id, draft.id); + if (draft.next) { - draft.next = cloneNode(draft.next, { withCopySuffix }); + draft.next = cloneNode(draft.next, { withCopySuffix, nodeIdMap }); } if (draft.branches) { - draft.branches = draft.branches.map((branch) => cloneNode(branch, { withCopySuffix })); + draft.branches = draft.branches.map((branch) => cloneNode(branch, { withCopySuffix, nodeIdMap })); + } + + if (draft.config) { + switch (draft.type) { + case WorkflowNodeType.Deploy: + { + const prevNodeId = (draft.config as WorkflowNodeConfigForDeploy).certificate?.split("#")?.[0]; + if (nodeIdMap.has(prevNodeId)) { + draft.config = { + ...draft.config, + certificate: `${nodeIdMap.get(prevNodeId)}#certificate`, + } as WorkflowNodeConfigForDeploy; + } + } + break; + } } return draft; From b2b9576d4e8d2c875c04442201b96f862ad083bd Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Tue, 24 Jun 2025 16:30:27 +0800 Subject: [PATCH 13/16] feat(ui): improve i18n --- internal/deployer/providers.go | 2 +- .../providers/aliyun-cas-deploy/aliyun_cas_deploy.go | 4 ++-- .../DeployNodeConfigFormTencentCloudSSLUpdateConfig.tsx | 4 +++- ui/src/i18n/locales/en/nls.workflow.nodes.json | 6 +++--- ui/src/i18n/locales/zh/nls.workflow.nodes.json | 6 +++--- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/internal/deployer/providers.go b/internal/deployer/providers.go index dac425f9..0b2a77bd 100644 --- a/internal/deployer/providers.go +++ b/internal/deployer/providers.go @@ -1234,8 +1234,8 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy Endpoint: xmaps.GetString(options.ProviderServiceConfig, "endpoint"), CertificiateId: xmaps.GetString(options.ProviderServiceConfig, "certificiateId"), IsReplaced: xmaps.GetBool(options.ProviderServiceConfig, "isReplaced"), - ResourceRegions: xslices.Filter(strings.Split(xmaps.GetString(options.ProviderServiceConfig, "resourceRegions"), ";"), func(s string) bool { return s != "" }), ResourceTypes: xslices.Filter(strings.Split(xmaps.GetString(options.ProviderServiceConfig, "resourceTypes"), ";"), func(s string) bool { return s != "" }), + ResourceRegions: xslices.Filter(strings.Split(xmaps.GetString(options.ProviderServiceConfig, "resourceRegions"), ";"), func(s string) bool { return s != "" }), }) return deployer, err diff --git a/pkg/core/ssl-deployer/providers/aliyun-cas-deploy/aliyun_cas_deploy.go b/pkg/core/ssl-deployer/providers/aliyun-cas-deploy/aliyun_cas_deploy.go index 0d410d28..53fa88d2 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-cas-deploy/aliyun_cas_deploy.go +++ b/pkg/core/ssl-deployer/providers/aliyun-cas-deploy/aliyun_cas_deploy.go @@ -25,9 +25,9 @@ type SSLDeployerProviderConfig struct { ResourceGroupId string `json:"resourceGroupId,omitempty"` // 阿里云地域。 Region string `json:"region"` - // 阿里云云产品资源 ID 数组。 + // 云产品资源 ID 数组。 ResourceIds []string `json:"resourceIds"` - // 阿里云云联系人 ID 数组。 + // 云联系人 ID 数组。 // 零值时使用账号下第一个联系人。 ContactIds []string `json:"contactIds"` } diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLUpdateConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLUpdateConfig.tsx index 6c0fe497..4faa9272 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLUpdateConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSSLUpdateConfig.tsx @@ -24,7 +24,9 @@ export type DeployNodeConfigFormTencentCloudSSLUpdateConfigProps = { const MULTIPLE_INPUT_SEPARATOR = ";"; const initFormModel = (): DeployNodeConfigFormTencentCloudSSLUpdateConfigFieldValues => { - return {}; + return { + isReplaced: true, + }; }; const DeployNodeConfigFormTencentCloudSSLUpdateConfig = ({ diff --git a/ui/src/i18n/locales/en/nls.workflow.nodes.json b/ui/src/i18n/locales/en/nls.workflow.nodes.json index b11b32db..47724678 100644 --- a/ui/src/i18n/locales/en/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/en/nls.workflow.nodes.json @@ -169,7 +169,7 @@ "workflow_node.deploy.form.aliyun_cas_region.label": "Alibaba Cloud CAS region", "workflow_node.deploy.form.aliyun_cas_region.placeholder": "Please enter Alibaba Cloud CAS region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_cas_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/ssl-certificate/developer-reference/endpoints", - "workflow_node.deploy.form.aliyun_cas_deploy.guide": "TIPS: You need to go to the Alibaba Cloud console to check the actual deployment results by yourself, because Alibaba Cloud deployment tasks are running asynchronously.", + "workflow_node.deploy.form.aliyun_cas_deploy.guide": "TIPS: This will invoke Alibaba Cloud OpenAPI CreateDeploymentJob to create an asynchronously deployment task. You need to go to the Alibaba Cloud console to check the actual deployment results by yourself.", "workflow_node.deploy.form.aliyun_cas_deploy_region.label": "Alibaba Cloud CAS region", "workflow_node.deploy.form.aliyun_cas_deploy_region.placeholder": "Please enter Alibaba Cloud CAS region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_cas_deploy_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/ssl-certificate/developer-reference/endpoints", @@ -742,7 +742,7 @@ "workflow_node.deploy.form.tencentcloud_ssl_endpoint.label": "Tencent Cloud SSL API endpoint (Optional)", "workflow_node.deploy.form.tencentcloud_ssl_endpoint.placeholder": "Please enter Tencent Cloud SSL API endpoint (e.g. ssl.intl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_ssl_endpoint.tooltip": "
  • ssl.intl.tencentcloudapi.com for Tencent Cloud International
  • ssl.tencentcloudapi.com for Tencent Cloud in China
", - "workflow_node.deploy.form.tencentcloud_ssl_deploy.guide": "TIPS: You need to go to the Tencent Cloud console to check the actual deployment results by yourself, because Tencent Cloud deployment tasks are running asynchronously.", + "workflow_node.deploy.form.tencentcloud_ssl_deploy.guide": "TIPS: This will invoke Tencent Cloud OpenAPI DeployCertificateInstance to create an asynchronously deployment task. You need to go to the Tencent Cloud console to check the actual deployment results by yourself.", "workflow_node.deploy.form.tencentcloud_ssl_deploy_endpoint.label": "Tencent Cloud SSL API endpoint (Optional)", "workflow_node.deploy.form.tencentcloud_ssl_deploy_endpoint.placeholder": "Please enter Tencent Cloud SSL API endpoint (e.g. ssl.intl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_ssl_deploy_endpoint.tooltip": "
  • ssl.intl.tencentcloudapi.com for Tencent Cloud International
  • ssl.tencentcloudapi.com for Tencent Cloud in China
", @@ -758,7 +758,7 @@ "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.tooltip": "For more information, see https://cloud.tencent.com/document/product/400/91667", "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.title": "Change Tencent Cloud resource IDs", "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.placeholder": "Please enter Tencent Cloud resouce ID", - "workflow_node.deploy.form.tencentcloud_ssl_update.guide": "TIPS: You need to go to the Tencent Cloud console to check the actual deployment results by yourself, because Tencent Cloud deployment tasks are running asynchronously.", + "workflow_node.deploy.form.tencentcloud_ssl_update.guide": "TIPS: This will invoke Tencent Cloud OpenAPI UpdateCertificateInstance or UploadUpdateCertificateInstance to create an asynchronously deployment task. You need to go to the Tencent Cloud console to check the actual deployment results by yourself.", "workflow_node.deploy.form.tencentcloud_ssl_update_endpoint.label": "Tencent Cloud SSL API endpoint (Optional)", "workflow_node.deploy.form.tencentcloud_ssl_update_endpoint.placeholder": "Please enter Tencent Cloud SSL API endpoint (e.g. ssl.intl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_ssl_update_endpoint.tooltip": "
  • ssl.intl.tencentcloudapi.com for Tencent Cloud International
  • ssl.tencentcloudapi.com for Tencent Cloud in China
", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index 28c0176c..93805dac 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -168,7 +168,7 @@ "workflow_node.deploy.form.aliyun_cas_region.label": "阿里云 CAS 服务地域", "workflow_node.deploy.form.aliyun_cas_region.placeholder": "请输入阿里云 CAS 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_cas_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/ssl-certificate/developer-reference/endpoints", - "workflow_node.deploy.form.aliyun_cas_deploy.guide": "小贴士:由于阿里云证书部署任务是异步的,此部署目标若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往阿里云控制台查询。", + "workflow_node.deploy.form.aliyun_cas_deploy.guide": "小贴士:将通过阿里云 OpenAPI CreateDeploymentJob 接口创建异步部署任务。此部署目标若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往阿里云控制台查询。", "workflow_node.deploy.form.aliyun_cas_deploy_region.label": "阿里云 CAS 服务地域", "workflow_node.deploy.form.aliyun_cas_deploy_region.placeholder": "请输入阿里云 CAS 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_cas_deploy_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/ssl-certificate/developer-reference/endpoints", @@ -740,7 +740,7 @@ "workflow_node.deploy.form.tencentcloud_ssl_endpoint.label": "腾讯云 SSL 接口端点(可选)", "workflow_node.deploy.form.tencentcloud_ssl_endpoint.placeholder": "请输入腾讯云 SSL 接口端点(例如:ssl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_ssl_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/41659", - "workflow_node.deploy.form.tencentcloud_ssl_deploy.guide": "小贴士:由于腾讯云证书部署任务是异步的,此部署目标若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往腾讯云控制台查询。", + "workflow_node.deploy.form.tencentcloud_ssl_deploy.guide": "小贴士:将通过腾讯云 OpenAPI DeployCertificateInstance 接口创建异步部署任务。此部署目标若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往腾讯云控制台查询。", "workflow_node.deploy.form.tencentcloud_ssl_deploy_endpoint.label": "腾讯云 SSL 接口端点(可选)", "workflow_node.deploy.form.tencentcloud_ssl_deploy_endpoint.placeholder": "请输入腾讯云 SSL 接口端点(例如:ssl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_ssl_deploy_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/41659", @@ -756,7 +756,7 @@ "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/91667

注意与各产品本身的实例 ID 区分。", "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.title": "修改腾讯云云产品资源 ID", "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.placeholder": "请输入腾讯云云产品资源 ID", - "workflow_node.deploy.form.tencentcloud_ssl_update.guide": "小贴士:由于腾讯云证书部署任务是异步的,此部署目标若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往腾讯云控制台查询。", + "workflow_node.deploy.form.tencentcloud_ssl_update.guide": "小贴士:将通过腾讯云 OpenAPI UpdateCertificateInstanceUploadUpdateCertificateInstance 接口创建异步部署任务。此部署目标若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往腾讯云控制台查询。", "workflow_node.deploy.form.tencentcloud_ssl_update_endpoint.label": "腾讯云 SSL 接口端点(可选)", "workflow_node.deploy.form.tencentcloud_ssl_update_endpoint.placeholder": "请输入腾讯云 SSL 接口端点(例如:ssl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_ssl_update_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/41659", From 17be4879580bc486a73c43bc8d803cfb1e584802 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Tue, 24 Jun 2025 20:26:01 +0800 Subject: [PATCH 14/16] fix: #815 --- ui/src/domain/workflow.ts | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/ui/src/domain/workflow.ts b/ui/src/domain/workflow.ts index 5304fe77..d37a16f5 100644 --- a/ui/src/domain/workflow.ts +++ b/ui/src/domain/workflow.ts @@ -544,6 +544,41 @@ export const cloneNode = (sourceNode: WorkflowNode, { withCopySuffix, nodeIdMap } } break; + + case WorkflowNodeType.Condition: + { + const stack = [] as Expr[]; + + const expr = (draft.config as WorkflowNodeConfigForCondition).expression; + if (expr) { + stack.push(expr); + + while (stack.length > 0) { + const n = stack.pop()!; + + if ("left" in n) { + stack.push(n.left); + + if ("selector" in n.left) { + const prevNodeId = n.left.selector.id; + if (nodeIdMap.has(prevNodeId)) { + n.left.selector.id = nodeIdMap.get(prevNodeId)!; + } + } + } + + if ("right" in n) { + stack.push(n.right); + } + } + + draft.config = { + ...draft.config, + expression: expr, + } as WorkflowNodeConfigForCondition; + } + } + break; } } From 12ef57357945cb0527d2aea3a0c23844b545871a Mon Sep 17 00:00:00 2001 From: imlonghao Date: Wed, 25 Jun 2025 11:26:44 +0800 Subject: [PATCH 15/16] feat: support Profiles Extension --- internal/applicant/applicant.go | 2 ++ internal/applicant/providers.go | 1 + internal/domain/workflow.go | 2 ++ .../workflow/node/ApplyNodeConfigForm.tsx | 15 +++++++++++++++ ui/src/domain/workflow.ts | 1 + ui/src/i18n/locales/en/nls.workflow.nodes.json | 3 +++ ui/src/i18n/locales/zh/nls.workflow.nodes.json | 3 +++ 7 files changed, 27 insertions(+) diff --git a/internal/applicant/applicant.go b/internal/applicant/applicant.go index 6040b902..c6d5608d 100644 --- a/internal/applicant/applicant.go +++ b/internal/applicant/applicant.go @@ -64,6 +64,7 @@ func NewWithWorkflowNode(config ApplicantWithWorkflowNodeConfig) (Applicant, err CAProviderAccessConfig: make(map[string]any), CAProviderServiceConfig: nodeCfg.CAProviderConfig, KeyAlgorithm: nodeCfg.KeyAlgorithm, + ACMEProfile: nodeCfg.ACMEProfile, Nameservers: xslices.Filter(strings.Split(nodeCfg.Nameservers, ";"), func(s string) bool { return s != "" }), DnsPropagationWait: nodeCfg.DnsPropagationWait, DnsPropagationTimeout: nodeCfg.DnsPropagationTimeout, @@ -235,6 +236,7 @@ func applyUseLego(legoProvider challenge.Provider, options *applicantProviderOpt certRequest := certificate.ObtainRequest{ Domains: options.Domains, Bundle: true, + Profile: options.ACMEProfile, } if options.ARIReplaceAcct == user.Registration.URI { certRequest.ReplacesCertID = options.ARIReplaceCert diff --git a/internal/applicant/providers.go b/internal/applicant/providers.go index c5de24ef..7b07997f 100644 --- a/internal/applicant/providers.go +++ b/internal/applicant/providers.go @@ -63,6 +63,7 @@ type applicantProviderOptions struct { DnsPropagationWait int32 DnsPropagationTimeout int32 DnsTTL int32 + ACMEProfile string DisableFollowCNAME bool ARIReplaceAcct string ARIReplaceCert string diff --git a/internal/domain/workflow.go b/internal/domain/workflow.go index 50997019..04ba1e4f 100644 --- a/internal/domain/workflow.go +++ b/internal/domain/workflow.go @@ -75,6 +75,7 @@ type WorkflowNodeConfigForApply struct { CAProviderAccessId string `json:"caProviderAccessId,omitempty"` // CA 提供商授权记录 ID CAProviderConfig map[string]any `json:"caProviderConfig,omitempty"` // CA 提供商额外配置 KeyAlgorithm string `json:"keyAlgorithm"` // 证书算法 + ACMEProfile string `json:"acmeProfile,omitempty"` // ACME Profiles Extension Nameservers string `json:"nameservers,omitempty"` // DNS 服务器列表,以半角分号分隔 DnsPropagationWait int32 `json:"dnsPropagationWait,omitempty"` // DNS 传播等待时间,等同于 lego 的 `--dns-propagation-wait` 参数 DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` // DNS 传播检查超时时间(零值时使用提供商的默认值) @@ -130,6 +131,7 @@ func (n *WorkflowNode) GetConfigForApply() WorkflowNodeConfigForApply { CAProviderAccessId: xmaps.GetString(n.Config, "caProviderAccessId"), CAProviderConfig: xmaps.GetKVMapAny(n.Config, "caProviderConfig"), KeyAlgorithm: xmaps.GetOrDefaultString(n.Config, "keyAlgorithm", string(CertificateKeyAlgorithmTypeRSA2048)), + ACMEProfile: xmaps.GetString(n.Config, "acmeProfile"), Nameservers: xmaps.GetString(n.Config, "nameservers"), DnsPropagationWait: xmaps.GetInt32(n.Config, "dnsPropagationWait"), DnsPropagationTimeout: xmaps.GetInt32(n.Config, "dnsPropagationTimeout"), diff --git a/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx b/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx index 0edd6a4a..cdcb689c 100644 --- a/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx @@ -113,6 +113,7 @@ const ApplyNodeConfigForm = forwardRef (v == null || v === "" ? undefined : Number(v)), z.number().int(t("workflow_node.apply.form.dns_ttl.placeholder")).gte(1, t("workflow_node.apply.form.dns_ttl.placeholder")).nullish() ), + acmeProfile: z.string().nullish(), disableFollowCNAME: z.boolean().nullish(), disableARI: z.boolean().nullish(), skipBeforeExpiryDays: z.preprocess( @@ -454,6 +455,20 @@ const ApplyNodeConfigForm = forwardRef
+ + } + > + ({ value }))} + placeholder={t("workflow_node.apply.form.acme_profile.placeholder")} + filterOption={(inputValue, option) => option!.value.toLowerCase().includes(inputValue.toLowerCase())} + /> + diff --git a/ui/src/domain/workflow.ts b/ui/src/domain/workflow.ts index d37a16f5..689d3488 100644 --- a/ui/src/domain/workflow.ts +++ b/ui/src/domain/workflow.ts @@ -151,6 +151,7 @@ export type WorkflowNodeConfigForApply = { caProviderAccessId?: string; caProviderConfig?: Record; keyAlgorithm: string; + acmeProfile?: string; nameservers?: string; dnsPropagationTimeout?: number; dnsTTL?: number; diff --git a/ui/src/i18n/locales/en/nls.workflow.nodes.json b/ui/src/i18n/locales/en/nls.workflow.nodes.json index 47724678..caf55597 100644 --- a/ui/src/i18n/locales/en/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/en/nls.workflow.nodes.json @@ -71,6 +71,9 @@ "workflow_node.apply.form.ca_provider_access.button": "Create", "workflow_node.apply.form.key_algorithm.label": "Certificate key algorithm", "workflow_node.apply.form.key_algorithm.placeholder": "Please select certificate key algorithm", + "workflow_node.apply.form.acme_profile.label": "ACME certificate profile (Optional)", + "workflow_node.apply.form.acme_profile.placeholder": "Please enter ACME certificate profile", + "workflow_node.apply.form.acme_profile.tooltip": "It determines the ACME profile which will be used to affect issuance of the certificate requested. If you don't understand this option, just keep it by default.Learn more.", "workflow_node.apply.form.advanced_config.label": "Advanced settings", "workflow_node.apply.form.nameservers.label": "DNS recursive nameservers (Optional)", "workflow_node.apply.form.nameservers.placeholder": "Please enter DNS recursive nameservers (separated by semicolons)", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index 93805dac..4e20f18c 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -70,6 +70,9 @@ "workflow_node.apply.form.ca_provider_access.button": "新建", "workflow_node.apply.form.key_algorithm.label": "证书算法", "workflow_node.apply.form.key_algorithm.placeholder": "请选择证书算法", + "workflow_node.apply.form.acme_profile.label": "ACME 证书配置(可选)", + "workflow_node.apply.form.acme_profile.placeholder": "请输入 ACME 证书配置", + "workflow_node.apply.form.acme_profile.tooltip": "表示证书颁发时使用的 ACME 证书配置。如果你不了解该选项的用途,保持默认即可。点此了解更多。", "workflow_node.apply.form.advanced_config.label": "高级设置", "workflow_node.apply.form.nameservers.label": "DNS 递归服务器(可选)", "workflow_node.apply.form.nameservers.placeholder": "请输入 DNS 递归服务器(多个值请用半角分号隔开)", From b6307875ddcf813f3051fba8215995bd01ab13fc Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Wed, 25 Jun 2025 11:38:48 +0800 Subject: [PATCH 16/16] fix: #819 --- ui/src/components/access/AccessFormCacheFlyConfig.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ui/src/components/access/AccessFormCacheFlyConfig.tsx b/ui/src/components/access/AccessFormCacheFlyConfig.tsx index 4d5d4862..b8c70f02 100644 --- a/ui/src/components/access/AccessFormCacheFlyConfig.tsx +++ b/ui/src/components/access/AccessFormCacheFlyConfig.tsx @@ -25,10 +25,7 @@ const AccessFormCacheFlyConfig = ({ form: formInst, formName, disabled, initialV const { t } = useTranslation(); const formSchema = z.object({ - apiToken: z - .string() - .min(1, t("access.form.cachefly_api_token.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + apiToken: z.string().nonempty(t("access.form.cachefly_api_token.placeholder")), }); const formRule = createSchemaFieldRule(formSchema);