diff --git a/.vscode/settings.json b/.vscode/settings.json index 47a3060e..cd6a03e0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,10 +11,11 @@ "gopls": { "formatting.gofumpt": true, }, + "typescript.tsdk": "ui/node_modules/typescript/lib", "[go]": { "editor.defaultFormatter": "golang.go" }, "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" } -} \ No newline at end of file +} diff --git a/go.mod b/go.mod index 5238c7c9..8fa0f6a6 100644 --- a/go.mod +++ b/go.mod @@ -1,40 +1,41 @@ module github.com/usual2970/certimate -go 1.22.0 +go 1.23.0 toolchain go1.23.2 require ( - github.com/alibabacloud-go/alb-20200616/v2 v2.2.1 - github.com/alibabacloud-go/cas-20200407/v3 v3.0.1 - github.com/alibabacloud-go/cdn-20180510/v5 v5.0.0 + github.com/alibabacloud-go/alb-20200616/v2 v2.2.6 + github.com/alibabacloud-go/cas-20200407/v3 v3.0.4 + github.com/alibabacloud-go/cdn-20180510/v5 v5.2.2 github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10 github.com/alibabacloud-go/nlb-20220430/v2 v2.0.3 github.com/alibabacloud-go/slb-20140515/v4 v4.0.9 github.com/alibabacloud-go/tea v1.2.2 github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible - github.com/baidubce/bce-sdk-go v0.9.197 - github.com/go-acme/lego/v4 v4.20.2 + github.com/baidubce/bce-sdk-go v0.9.209 + github.com/byteplus-sdk/byteplus-sdk-golang v1.0.35 + github.com/go-acme/lego/v4 v4.21.0 github.com/gojek/heimdall/v7 v7.0.3 - github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.120 + github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.128 github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61 - github.com/nikoksr/notify v1.0.0 + github.com/nikoksr/notify v1.1.0 github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0 - github.com/pkg/sftp v1.13.6 - github.com/pocketbase/dbx v1.10.1 - github.com/pocketbase/pocketbase v0.22.18 - github.com/qiniu/go-sdk/v7 v7.22.0 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1017 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1031 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1034 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.992 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1030 - github.com/volcengine/volc-sdk-golang v1.0.184 - golang.org/x/crypto v0.28.0 - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 - k8s.io/api v0.31.1 - k8s.io/apimachinery v0.31.1 - k8s.io/client-go v0.31.1 + github.com/pkg/sftp v1.13.7 + github.com/pocketbase/dbx v1.11.0 + github.com/pocketbase/pocketbase v0.22.21 + github.com/qiniu/go-sdk/v7 v7.25.1 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1065 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1065 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1065 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1065 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1065 + github.com/volcengine/volc-sdk-golang v1.0.189 + golang.org/x/crypto v0.31.0 + golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 + k8s.io/api v0.32.0 + k8s.io/apimachinery v0.32.0 + k8s.io/client-go v0.32.0 software.sslmate.com/src/go-pkcs12 v0.5.0 ) @@ -44,23 +45,21 @@ require ( github.com/alibabacloud-go/tea-oss-sdk v1.1.3 // indirect github.com/alibabacloud-go/tea-oss-utils v1.1.0 // indirect github.com/alibabacloud-go/tea-utils/v2 v2.0.6 // indirect - github.com/aws/aws-sdk-go-v2/service/route53 v1.46.0 // indirect + github.com/aws/aws-sdk-go-v2/service/route53 v1.46.4 // indirect github.com/blinkbean/dingtalk v1.1.3 // indirect - github.com/byteplus-sdk/byteplus-sdk-golang v1.0.35 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-lark/lark v1.14.1 // indirect + github.com/go-lark/lark v1.15.0 // indirect github.com/go-logr/logr v1.4.2 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/imdario/mergo v0.3.6 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect @@ -69,13 +68,13 @@ require ( github.com/technoweenie/multipartstreamer v1.0.1 // indirect github.com/x448/float16 v0.8.4 // indirect go.mongodb.org/mongo-driver v1.12.0 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect + k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect + sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) @@ -86,50 +85,50 @@ require ( github.com/alibabacloud-go/dcdn-20180115/v3 v3.4.2 github.com/alibabacloud-go/debug v1.0.1 // indirect github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect - github.com/alibabacloud-go/openapi-util v0.1.0 // indirect + github.com/alibabacloud-go/openapi-util v0.1.1 // indirect github.com/alibabacloud-go/tea-utils v1.4.5 // indirect github.com/alibabacloud-go/tea-xml v1.1.3 // indirect - github.com/aliyun/alibaba-cloud-sdk-go v1.63.47 // indirect + github.com/aliyun/alibaba-cloud-sdk-go v1.63.72 // indirect github.com/aliyun/credentials-go v1.3.10 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go-v2 v1.32.3 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect - github.com/aws/aws-sdk-go-v2/config v1.28.1 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.42 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.18 // indirect - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.8 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22 // indirect + github.com/aws/aws-sdk-go-v2 v1.32.7 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect + github.com/aws/aws-sdk-go-v2/config v1.28.7 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.48 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22 // indirect + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.44 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.3 // indirect - github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.24.3 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.3 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.32.3 // indirect - github.com/aws/smithy-go v1.22.0 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 // indirect + github.com/aws/aws-sdk-go-v2/service/s3 v1.71.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.33.3 // indirect + github.com/aws/smithy-go v1.22.1 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/clbanning/mxj/v2 v2.5.6 // indirect - github.com/cloudflare/cloudflare-go v0.108.0 // indirect + github.com/cloudflare/cloudflare-go v0.112.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/disintegration/imaging v1.6.2 // indirect github.com/domodwyer/mailyak/v3 v3.6.2 github.com/dustin/go-humanize v1.0.1 // indirect - github.com/fatih/color v1.17.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.6 // indirect + github.com/fatih/color v1.18.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.7 // indirect github.com/ganigeorgiev/fexpr v0.4.1 // indirect github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect - github.com/goccy/go-json v0.10.3 // indirect + github.com/goccy/go-json v0.10.4 // indirect github.com/gojek/valkyrie v0.0.0-20180215180059-6aee720afcdf // indirect github.com/golang-jwt/jwt/v4 v4.5.1 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/gax-go/v2 v2.13.0 // indirect + github.com/googleapis/gax-go/v2 v2.14.1 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect @@ -148,39 +147,39 @@ require ( github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect github.com/pkg/errors v0.9.1 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/cast v1.7.1 // indirect github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/stretchr/testify v1.9.0 // indirect - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1034 // indirect + github.com/stretchr/testify v1.10.0 // indirect + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1065 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect go.opencensus.io v0.24.0 // indirect - gocloud.dev v0.37.0 // indirect - golang.org/x/image v0.18.0 // indirect - golang.org/x/mod v0.21.0 // indirect - golang.org/x/net v0.30.0 // indirect - golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sync v0.8.0 - golang.org/x/sys v0.26.0 // indirect - golang.org/x/term v0.25.0 // indirect - golang.org/x/text v0.19.0 // indirect - golang.org/x/time v0.7.0 // indirect - golang.org/x/tools v0.25.0 // indirect - golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect - google.golang.org/api v0.204.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect - google.golang.org/grpc v1.67.1 // indirect - google.golang.org/protobuf v1.35.1 // indirect + gocloud.dev v0.40.0 // indirect + golang.org/x/image v0.23.0 // indirect + golang.org/x/mod v0.22.0 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/oauth2 v0.24.0 // indirect + golang.org/x/sync v0.10.0 + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect + golang.org/x/time v0.8.0 // indirect + golang.org/x/tools v0.28.0 // indirect + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect + google.golang.org/api v0.214.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241219192143-6b3ec007d9bb // indirect + google.golang.org/grpc v1.69.2 // indirect + google.golang.org/protobuf v1.36.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - modernc.org/gc/v3 v3.0.0-20240722195230-4a140ff9c08e // indirect - modernc.org/libc v1.55.3 // indirect - modernc.org/mathutil v1.6.0 // indirect + modernc.org/gc/v3 v3.0.0-20241213165251-3bc300f6d0c9 // indirect + modernc.org/libc v1.61.5 // indirect + modernc.org/mathutil v1.7.0 // indirect modernc.org/memory v1.8.0 // indirect - modernc.org/sqlite v1.31.1 // indirect + modernc.org/sqlite v1.34.4 // indirect modernc.org/strutil v1.2.0 // indirect modernc.org/token v1.1.0 // indirect ) diff --git a/go.sum b/go.sum index 7ac225c9..abf63404 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +cel.dev/expr v0.18.0 h1:CJ6drgk+Hf96lkLikr4rFf19WrU0BOWEihyZnI2TAzo= +cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -15,23 +17,24 @@ cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOY cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= -cloud.google.com/go/auth v0.10.0 h1:tWlkvFAh+wwTOzXIjrwM64karR1iTBZ/GRr0S/DULYo= -cloud.google.com/go/auth v0.10.0/go.mod h1:xxA5AqpDrvS+Gkmo9RqrGGRh6WSNKKOXhY3zNOr38tI= -cloud.google.com/go/auth/oauth2adapt v0.2.5 h1:2p29+dePqsCHPP1bqDJcKj4qxRyYCcbzKpFyKGt3MTk= -cloud.google.com/go/auth/oauth2adapt v0.2.5/go.mod h1:AlmsELtlEBnaNTL7jCj8VQFLy6mbZv0s4Q7NGBeQ5E8= +cloud.google.com/go/auth v0.13.0 h1:8Fu8TZy167JkW8Tj3q7dIkr2v4cndv41ouecJx0PAHs= +cloud.google.com/go/auth v0.13.0/go.mod h1:COOjD9gwfKNKz+IIduatIhYJQIc0mG3H102r/EMxX6Q= +cloud.google.com/go/auth/oauth2adapt v0.2.6 h1:V6a6XDu2lTwPZWOawrAa9HUK+DB2zfJyTuciBG5hFkU= +cloud.google.com/go/auth/oauth2adapt v0.2.6/go.mod h1:AlmsELtlEBnaNTL7jCj8VQFLy6mbZv0s4Q7NGBeQ5E8= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.25.0 h1:H1/4SqSUhjPFE7L5ddzHOfY2bCAvjwNRZPNl6Ni5oYU= -cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo= -cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= +cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= +cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw= -cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ= +cloud.google.com/go/iam v1.2.2 h1:ozUSofHUGf/F4tCNy/mu9tHLTaxZFLOUiKzjcgWHGIA= +cloud.google.com/go/iam v1.2.2/go.mod h1:0Ys8ccaZHdI1dEUilwzqng/6ps2YB6vRsjIe00/+6JY= +cloud.google.com/go/monitoring v1.21.2 h1:FChwVtClH19E7pJ+e0xUhJPGksctZNVOk2UhMmblmdU= +cloud.google.com/go/monitoring v1.21.2/go.mod h1:hS3pXvaG8KgWTSz+dAdyzPrGUYmi2Q+WFX8g2hqVEZU= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -41,8 +44,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= -cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= +cloud.google.com/go/storage v1.45.0 h1:5av0QcIVj77t+44mV4gffFC/LscFRUhto6UBMB5SimM= +cloud.google.com/go/storage v1.45.0/go.mod h1:wpPblkIuMP5jCB/E48Pz9zIo2S/zD8g+ITmxKkPCITE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= @@ -56,6 +59,12 @@ github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v3.7.1+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.3 h1:cb3br57K508pQEFgBxn9GDhPS9HefpyMPK1RzmtMNzk= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.3/go.mod h1:itPGVDKf9cC/ov4MdvJ2QZ0khw4bfoo9jzwTJlaxy2k= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.48.3 h1:xir5X8TS8UBVPWg2jHL+cSTf0jZgqYQSA54TscSt1/0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.48.3/go.mod h1:SsdWig2J5PMnfMvfJuEb1uZa8Y+kvNyvrULFo69gTFk= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.3 h1:2vcVkrNdSMJpoOVAWi9ApsQR5iqNeFGt5Qx8Xlt3IoI= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.3/go.mod h1:wRbFgBQUVm1YXrvWKofAEmq9HNJTDphbAaJSSX01KUI= github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= @@ -75,17 +84,17 @@ 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.1 h1:b8ixnrkFhWrmJQd+iEE1UWPD5vdyC3d9l7G0uvkfi2s= -github.com/alibabacloud-go/alb-20200616/v2 v2.2.1/go.mod h1:cPdZwovbqpv+5nM/HnMwZpG5q0/gBuX31hu2H1VoyrM= +github.com/alibabacloud-go/alb-20200616/v2 v2.2.6 h1:lgTuFZSfULbwpotnmE8qguIWTwR+X+F5Xrz6WrHQCaA= +github.com/alibabacloud-go/alb-20200616/v2 v2.2.6/go.mod h1:jU/K+GVb5b0vjiDpkf6E0dH77tsi1jTLGWm4ouCiRxk= github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6 h1:eIf+iGJxdU4U9ypaUfbtOWCsZSbTb8AUHvyPrxu6mAA= github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6/go.mod h1:4EUIoxs/do24zMOGGqYVWgw0s9NtiylnJglOeEB5UJo= github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc= github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 h1:zE8vH9C7JiZLNJJQ5OwjU9mSi4T9ef9u3BURT6LCLC8= github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5/go.mod h1:tWnyE9AjF8J8qqLk645oUmVUnFybApTQWklQmi5tY6g= -github.com/alibabacloud-go/cas-20200407/v3 v3.0.1 h1:kAxd9IkdMaIX9aoBRA34q9WXKnkKTucil/zUlG4/3vo= -github.com/alibabacloud-go/cas-20200407/v3 v3.0.1/go.mod h1:gElMYWcjdjKgqq9/2YxE6BIUMs10ZNGM4PRiRlDXgBs= -github.com/alibabacloud-go/cdn-20180510/v5 v5.0.0 h1:yTKngw4rBR3hdpoo/uCyBffYXfPfjNjlaDL8nTYUIds= -github.com/alibabacloud-go/cdn-20180510/v5 v5.0.0/go.mod h1:HxQrwVKBx3/6bIwmdDcpqBpSQt2tpi/j4LfEhl+QFPk= +github.com/alibabacloud-go/cas-20200407/v3 v3.0.4 h1:ngRlctbt135zoujwX0lXSv9m4h1/bmg/yalQS0z1EWc= +github.com/alibabacloud-go/cas-20200407/v3 v3.0.4/go.mod h1:6n9MZ9SH3HlSzfe2oKwjOqhJx3dxvW2gMDO+lq8t9U4= +github.com/alibabacloud-go/cdn-20180510/v5 v5.2.2 h1:+KJOPukTM+xMyiLOW5qBwYKG2df3Ar7coRsqc1juKO8= +github.com/alibabacloud-go/cdn-20180510/v5 v5.2.2/go.mod h1:GnPiPL3HlzCi8SGiLiVgKrAFkP1vTtcF4yGtjsl4wfo= github.com/alibabacloud-go/darabonba-array v0.1.0 h1:vR8s7b1fWAQIjEjWnuF0JiKsCvclSRTfDzZHTYqfufY= github.com/alibabacloud-go/darabonba-array v0.1.0/go.mod h1:BLKxr0brnggqOJPqT09DFJ8g3fsDshapUD3C3aOEFaI= github.com/alibabacloud-go/darabonba-encode-util v0.0.2 h1:1uJGrbsGEVqWcWxrS9MyC2NG0Ax+GpOM5gtupki31XE= @@ -95,7 +104,6 @@ github.com/alibabacloud-go/darabonba-map v0.0.2/go.mod h1:28AJaX8FOE/ym8OUFWga+M github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.0/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ= github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.5/go.mod h1:kUe8JqFmoVU7lfBauaDD5taFaW7mBI+xVsyHutYtabg= github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.7/go.mod h1:CzQnh+94WDnJOnKZH5YRyouL+OOcdBnXY5VWAf0McgI= -github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.8/go.mod h1:CzQnh+94WDnJOnKZH5YRyouL+OOcdBnXY5VWAf0McgI= github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.9/go.mod h1:bb+Io8Sn2RuM3/Rpme6ll86jMyFSrD1bxeV/+v61KeU= github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10 h1:GEYkMApgpKEVDn6z12DcH1EGYpDYRB8JxsazM4Rywak= github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10/go.mod h1:26a14FGhZVELuz2cc2AolvW4RHmIO3/HRwsdHhaIPDE= @@ -114,8 +122,9 @@ github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudH github.com/alibabacloud-go/nlb-20220430/v2 v2.0.3 h1:LtyUVlgBEKyzWgQJurzXM6MXCt84sQr9cE5OKqYymko= github.com/alibabacloud-go/nlb-20220430/v2 v2.0.3/go.mod h1:4a/RcBYeAhYowHzX+LMgnouz7NradnSKPKl14KS3B1U= github.com/alibabacloud-go/openapi-util v0.0.11/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= -github.com/alibabacloud-go/openapi-util v0.1.0 h1:0z75cIULkDrdEhkLWgi9tnLe+KhAFE/r5Pb3312/eAY= github.com/alibabacloud-go/openapi-util v0.1.0/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= +github.com/alibabacloud-go/openapi-util v0.1.1 h1:ujGErJjG8ncRW6XtBBMphzHTvCxn4DjrVw4m04HsS28= +github.com/alibabacloud-go/openapi-util v0.1.1/go.mod h1:/UehBSE2cf1gYT43GV4E+RxTdLRzURImCYY0aRmlXpw= github.com/alibabacloud-go/openplatform-20191219/v2 v2.0.1 h1:L0TIjr9Qh/SLVc1yPhFkcB9+9SbCNK/jPq4ZKB5zmnc= github.com/alibabacloud-go/openplatform-20191219/v2 v2.0.1/go.mod h1:EKxBRDLcMzwl4VLF/1WJwlByZZECJawPXUvinKMsTTs= github.com/alibabacloud-go/slb-20140515/v4 v4.0.9 h1:nrf9gQth7fONUj7V8i78Yb98eb9NdKl0VdeSjmeYugI= @@ -151,8 +160,8 @@ github.com/alibabacloud-go/tea-xml v1.1.1/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCE github.com/alibabacloud-go/tea-xml v1.1.2/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8= github.com/alibabacloud-go/tea-xml v1.1.3 h1:7LYnm+JbOq2B+T/B0fHC4Ies4/FofC4zHzYtqw7dgt0= github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8= -github.com/aliyun/alibaba-cloud-sdk-go v1.63.47 h1:B8ApNodSpIM5ST9INmhMG4d0rRwNY/63/XjXUDO/XIo= -github.com/aliyun/alibaba-cloud-sdk-go v1.63.47/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ= +github.com/aliyun/alibaba-cloud-sdk-go v1.63.72 h1:HvFZUzEbNvfe8F2Mg0wBGv90bPhWDxgVtDHR5zoBOU0= +github.com/aliyun/alibaba-cloud-sdk-go v1.63.72/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ= github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g= github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw= @@ -171,53 +180,53 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= 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 v1.51.11 h1:El5VypsMIz7sFwAAj/j06JX9UGs4KAbAIEaZ57bNY4s= -github.com/aws/aws-sdk-go v1.51.11/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= +github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= 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.32.3 h1:T0dRlFBKcdaUPGNtkBSwHZxrtis8CQU17UpNBZYd0wk= -github.com/aws/aws-sdk-go-v2 v1.32.3/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6/go.mod h1:j/I2++U0xX+cr44QjHay4Cvxj6FUbnxrgmqN3H1jTZA= -github.com/aws/aws-sdk-go-v2/config v1.28.1 h1:oxIvOUXy8x0U3fR//0eq+RdCKimWI900+SV+10xsCBw= -github.com/aws/aws-sdk-go-v2/config v1.28.1/go.mod h1:bRQcttQJiARbd5JZxw6wG0yIK3eLeSCPdg6uqmmlIiI= -github.com/aws/aws-sdk-go-v2/credentials v1.17.42 h1:sBP0RPjBU4neGpIYyx8mkU2QqLPl5u9cmdTWVzIpHkM= -github.com/aws/aws-sdk-go-v2/credentials v1.17.42/go.mod h1:FwZBfU530dJ26rv9saAbxa9Ej3eF/AK0OAY86k13n4M= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.18 h1:68jFVtt3NulEzojFesM/WVarlFpCaXLKaBxDpzkQ9OQ= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.18/go.mod h1:Fjnn5jQVIo6VyedMc0/EhPpfNlPl7dHV916O6B+49aE= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.8 h1:u1KOU1S15ufyZqmH/rA3POkiRH6EcDANHj2xHRzq+zc= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.8/go.mod h1:WPv2FRnkIOoDv/8j2gSUsI4qDc7392w5anFB/I89GZ8= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22 h1:Jw50LwEkVjuVzE1NzkhNKkBf9cRN7MtE1F/b2cOKTUM= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22/go.mod h1:Y/SmAyPcOTmpeVaWSzSKiILfXTVJwrGmYZhcRbhWuEY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22 h1:981MHwBaRZM7+9QSR6XamDzF/o7ouUGxFzr+nVSIhrs= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22/go.mod h1:1RA1+aBEfn+CAB/Mh0MB6LsdCYCnjZm7tKXtnk499ZQ= +github.com/aws/aws-sdk-go-v2 v1.32.7 h1:ky5o35oENWi0JYWUZkB7WYvVPP+bcRF5/Iq7JWSb5Rw= +github.com/aws/aws-sdk-go-v2 v1.32.7/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc= +github.com/aws/aws-sdk-go-v2/config v1.28.7 h1:GduUnoTXlhkgnxTD93g1nv4tVPILbdNQOzav+Wpg7AE= +github.com/aws/aws-sdk-go-v2/config v1.28.7/go.mod h1:vZGX6GVkIE8uECSUHB6MWAUsd4ZcG2Yq/dMa4refR3M= +github.com/aws/aws-sdk-go-v2/credentials v1.17.48 h1:IYdLD1qTJ0zanRavulofmqut4afs45mOWEI+MzZtTfQ= +github.com/aws/aws-sdk-go-v2/credentials v1.17.48/go.mod h1:tOscxHN3CGmuX9idQ3+qbkzrjVIx32lqDSU1/0d/qXs= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22 h1:kqOrpojG71DxJm/KDPO+Z/y1phm1JlC8/iT+5XRmAn8= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22/go.mod h1:NtSFajXVVL8TA2QNngagVZmUtXciyrHOt7xgz4faS/M= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.44 h1:2zxMLXLedpB4K1ilbJFxtMKsVKaexOqDttOhc0QGm3Q= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.44/go.mod h1:VuLHdqwjSvgftNC7yqPWyGVhEwPmJpeRi07gOgOfHF8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 h1:I/5wmGMffY4happ8NOCuIUEWGUvvFp5NSeQcXl9RHcI= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26/go.mod h1:FR8f4turZtNy6baO0KJ5FJUmXH/cSkI9fOngs0yl6mA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 h1:zXFLuEuMMUOvEARXFUVJdfqZ4bvvSgdGRq/ATcrQxzM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26/go.mod h1:3o2Wpy0bogG1kyOPrgkXA8pgIfEEv0+m19O9D5+W8y8= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22 h1:yV+hCAHZZYJQcwAaszoBNwLbPItHvApxT0kVIw6jRgs= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22/go.mod h1:kbR1TL8llqB1eGnVbybcA4/wgScxdylOdyAd51yxPdw= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26 h1:GeNJsIFHB+WW5ap2Tec4K6dzcVTsRbsT1Lra46Hv9ME= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26/go.mod h1:zfgMpwHDXX2WGoG84xG2H+ZlPTkJUU4YUvx2svLQYWo= 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/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.3 h1:kT6BcZsmMtNkP/iYMcRG+mIEA/IbeiUimXtGmqF39y0= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.3/go.mod h1:Z8uGua2k4PPaGOYn66pK02rhMrot3Xk3tpBuUFPomZU= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3 h1:qcxX0JYlgWH3hpPUnd6U0ikcl6LLA9sLkXE2w1fpMvY= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3/go.mod h1:cLSNEmI45soc+Ef8K/L+8sEA3A3pYFEYf5B5UI+6bH4= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.3 h1:ZC7Y/XgKUxwqcdhO5LE8P6oGP1eh6xlQReWNKfhvJno= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.3/go.mod h1:WqfO7M9l9yUAw0HcHaikwRd/H6gzYdz7vjejCA5e2oY= -github.com/aws/aws-sdk-go-v2/service/route53 v1.46.0 h1:AaOWmXBSDSIEsTzx8Y2nYAxckgmBPNiRU5mjn/a9ynI= -github.com/aws/aws-sdk-go-v2/service/route53 v1.46.0/go.mod h1:IN9bx4yLAa3a3J7A41skQefcYObNv6ARAd2i5WxvGKg= -github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2 h1:p9TNFL8bFUMd+38YIpTAXpoxyz0MxC7FlbFEH4P4E1U= -github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2/go.mod h1:fNjyo0Coen9QTwQLWeV6WO2Nytwiu+cCcWaTdKCAqqE= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.3 h1:UTpsIf0loCIWEbrqdLb+0RxnTXfWh2vhw4nQmFi4nPc= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.3/go.mod h1:FZ9j3PFHHAR+w0BSEjK955w5YD2UwB/l/H0yAK3MJvI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.3 h1:2YCmIXv3tmiItw0LlYf6v7gEHebLY45kBEnPezbUKyU= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.3/go.mod h1:u19stRyNPxGhj6dRm+Cdgu6N75qnbW7+QN0q0dsAk58= -github.com/aws/aws-sdk-go-v2/service/sts v1.32.3 h1:wVnQ6tigGsRqSWDEEyH6lSAJ9OyFUsSnbaUWChuSGzs= -github.com/aws/aws-sdk-go-v2/service/sts v1.32.3/go.mod h1:VZa9yTFyj4o10YGsmDO4gbQJUvvhY72fhumT8W4LqsE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7 h1:tB4tNw83KcajNAzaIMhkhVI2Nt8fAZd5A5ro113FEMY= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7/go.mod h1:lvpyBGkZ3tZ9iSsUIcC2EWp+0ywa7aK3BLT+FwZi+mQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7 h1:8eUsivBQzZHqe/3FE+cqwfH+0p5Jo8PFM/QYQSmeZ+M= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7/go.mod h1:kLPQvGUmxn/fqiCrDeohwG33bq2pQpGeY62yRO6Nrh0= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 h1:Hi0KGbrnr57bEHWM0bJ1QcBzxLrL/k2DHvGYhb8+W1w= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7/go.mod h1:wKNgWgExdjjrm4qvfbTorkvocEstaoDl4WCvGfeCy9c= +github.com/aws/aws-sdk-go-v2/service/route53 v1.46.4 h1:0jMtawybbfpFEIMy4wvfyW2Z4YLr7mnuzT0fhR67Nrc= +github.com/aws/aws-sdk-go-v2/service/route53 v1.46.4/go.mod h1:xlMODgumb0Pp8bzfpojqelDrf8SL9rb5ovwmwKJl+oU= +github.com/aws/aws-sdk-go-v2/service/s3 v1.71.1 h1:aOVVZJgWbaH+EJYPvEgkNhCEbXXvH7+oML36oaPK3zE= +github.com/aws/aws-sdk-go-v2/service/s3 v1.71.1/go.mod h1:r+xl5yzMk9083rMR+sJ5TYj9Tihvf/l1oxzZXDgGj2Q= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 h1:CvuUmnXI7ebaUAhbJcDy9YQx8wHR69eZ9I7q5hszt/g= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.8/go.mod h1:XDeGv1opzwm8ubxddF0cgqkZWsyOtw4lr6dxwmb6YQg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 h1:F2rBfNAL5UyswqoeWv9zs74N/NanhK16ydHW1pahX6E= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7/go.mod h1:JfyQ0g2JG8+Krq0EuZNnRwX0mU0HrwY/tG6JNfcqh4k= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.3 h1:Xgv/hyNgvLda/M9l9qxXc4UFSgppnRczLxlMs5Ae/QY= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.3/go.mod h1:5Gn+d+VaaRgsjewpMvGazt0WfcFO+Md4wLOuBfGR9Bc= github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= -github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM= -github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= -github.com/baidubce/bce-sdk-go v0.9.197 h1:TQqa4J+FTagrywhaTQ707ffE1eG3ix1s06eSZ/K+Wk0= -github.com/baidubce/bce-sdk-go v0.9.197/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg= +github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= +github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/baidubce/bce-sdk-go v0.9.209 h1:2UaYKD5D2kia+8bhLlqhYWZdhhGnx8vgHfHX7YUpXPg= +github.com/baidubce/bce-sdk-go v0.9.209/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= @@ -234,9 +243,14 @@ github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInq github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -247,11 +261,13 @@ github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn github.com/clbanning/mxj/v2 v2.5.6 h1:Jm4VaCI/+Ug5Q57IzEoZbwx4iQFA6wkXv72juUSeK+g= github.com/clbanning/mxj/v2 v2.5.6/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cloudflare-go v0.108.0 h1:C4Skfjd8I8X3uEOGmQUT4/iGyZcWdkIU7HwvMoLkEE0= -github.com/cloudflare/cloudflare-go v0.108.0/go.mod h1:m492eNahT/9MsN7Ppnoge8AaI7QhVFtEgVm3I9HJFeU= +github.com/cloudflare/cloudflare-go v0.112.0 h1:caFwqXdGJCl3rjVMgbPEn8iCYAg9JsRYV3dIVQE5d7g= +github.com/cloudflare/cloudflare-go v0.112.0/go.mod h1:QB55kuJ5ZTeLNFcLJePfMuBilhu/LDKpLBmKFQIoSZ0= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI= +github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -286,12 +302,16 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE= +github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM= +github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= -github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= @@ -305,14 +325,14 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc= -github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc= +github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= +github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/gammazero/toposort v0.1.1/go.mod h1:H2cozTnNpMw0hg2VHAYsAxmkHXBYroNangj2NTBQDvw= github.com/ganigeorgiev/fexpr v0.4.1 h1:hpUgbUEEWIZhSDBtf4M9aUNfQQ0BZkGRaMePy7Gcx5k= github.com/ganigeorgiev/fexpr v0.4.1/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-acme/lego/v4 v4.20.2 h1:ZwO3oLZb8fL6up1OZVJP3yHuvqhozzlEmyqKmhrPchQ= -github.com/go-acme/lego/v4 v4.20.2/go.mod h1:foauPlhnhoq8WUphaWx5U04uDc+JGhk4ZZtPz/Vqsjg= +github.com/go-acme/lego/v4 v4.21.0 h1:arEW+8o5p7VI8Bk1kr/PDlgD1DrxtTH1gJ4b7mehL8o= +github.com/go-acme/lego/v4 v4.21.0/go.mod h1:HrSWzm3Ckj45Ie3i+p1zKVobbQoMOaGu9m4up0dUeDI= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -323,8 +343,8 @@ github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-lark/lark v1.14.1 h1:qWYQTk6wLwf/08u8WbdNAHNmfqavdOvmsENlQ+Cb8aY= -github.com/go-lark/lark v1.14.1/go.mod h1:6ltbSztPZRT6IaO9ZIQyVaY5pVp/KeMizDYtfZkU+vM= +github.com/go-lark/lark v1.15.0 h1:wzfzK9j85BrbFYcjxGZSjJiXbOxHQYkKjIClUwyT9XU= +github.com/go-lark/lark v1.15.0/go.mod h1:6ltbSztPZRT6IaO9ZIQyVaY5pVp/KeMizDYtfZkU+vM= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= @@ -333,13 +353,14 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead57VkAEY4V+Es= github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -349,8 +370,8 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/validator/v10 v10.7.0/go.mod h1:xm76BBt941f7yWdGnI2DVPFFg1UK3YY04qifoXU3lOk= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.8.0 h1:UtktXaU2Nb64z/pLiGIxY4431SJ4/dR5cjMmlVHgnT4= -github.com/go-sql-driver/mysql v1.8.0/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= @@ -359,8 +380,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZ github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU= github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM= github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= -github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= -github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= +github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -371,6 +392,7 @@ github.com/gojek/heimdall/v7 v7.0.3/go.mod h1:Z43HtMid7ysSjmsedPTXAki6jcdcNVnjn5 github.com/gojek/valkyrie v0.0.0-20180215180059-6aee720afcdf h1:5xRGbUdOmZKoDXkGx5evVLehuCMpuO1hl701bEQqXOM= github.com/gojek/valkyrie v0.0.0-20180215180059-6aee720afcdf/go.mod h1:QzhUKaYKJmcbTnCYCAVQrroCOY7vOOI8cSQ4NbuhYf0= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= @@ -379,8 +401,9 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -444,8 +467,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20240625030939-27f56978b8b0 h1:e+8XbKB6IMn8A4OAyZccO4pYfB3s7bt6azNIPE7AnPg= -github.com/google/pprof v0.0.0-20240625030939-27f56978b8b0/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= @@ -459,8 +482,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gT github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s= -github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A= +github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= +github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -503,13 +526,11 @@ github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKEN github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.120 h1:i+rlH2xzkEMGbol86Fq/ioxgAaOnX2vkH4i/bLptc5s= -github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.120/go.mod h1:JWz2ujO9X3oU5wb6kXp+DpR2UuDj2SldDbX8T0FSuhI= +github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.128 h1:kQ2Agpfy7Ze1ajn9xCQG9G6T7XIbqv+FBDS/U98W9Mk= +github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.128/go.mod h1:JWz2ujO9X3oU5wb6kXp+DpR2UuDj2SldDbX8T0FSuhI= 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= -github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -572,7 +593,6 @@ github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgx github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/matishsiao/goInfo v0.0.0-20210923090445-da2e3fa8d45f/go.mod h1:aEt7p9Rvh67BYApmZwNDPpgircTO2kgdmDUoF/1QmwA= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -632,8 +652,8 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nikoksr/notify v1.0.0 h1:qe9/6FRsWdxBgQgWcpvQ0sv8LRGJZDpRB4TkL2uNdO8= -github.com/nikoksr/notify v1.0.0/go.mod h1:hPaaDt30d6LAA7/5nb0e48Bp/MctDfycCSs8VEgN29I= +github.com/nikoksr/notify v1.1.0 h1:IMw9p5ARDtKzZQmQSUy2+2LU/PPwBCdwQg2lCZh9EvY= +github.com/nikoksr/notify v1.1.0/go.mod h1:joe1r6qqAznTHzkC734Li8hxxVAYxzO6phBtMLfOVuo= github.com/nrdcg/namesilo v0.2.1 h1:kLjCjsufdW/IlC+iSfAqj0iQGgKjlbUUeDJio5Y6eMg= github.com/nrdcg/namesilo v0.2.1/go.mod h1:lwMvfQTyYq+BbjJd30ylEG4GPSS6PII0Tia4rRpRiyw= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -643,14 +663,14 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.2 h1:HFB2fbVIlhIfCfOW81bZFbiC/RvnpXSdhbF2/DJr134= github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= -github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= -github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= +github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= +github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A= @@ -669,15 +689,19 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= -github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= +github.com/pkg/sftp v1.13.7 h1:uv+I3nNJvlKZIQGSr8JVQLNHFU9YhhNpvC14Y6KgmSM= +github.com/pkg/sftp v1.13.7/go.mod h1:KMKI0t3T6hfA+lTR/ssZdunHo+uwq7ghoN09/FSu3DY= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pocketbase/dbx v1.10.1 h1:cw+vsyfCJD8YObOVeqb93YErnlxwYMkNZ4rwN0G0AaA= -github.com/pocketbase/dbx v1.10.1/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs= -github.com/pocketbase/pocketbase v0.22.18 h1:yVckUhi5GDORqCb0BbtlvRB1CVxHY9HO9btEaeZHVJU= -github.com/pocketbase/pocketbase v0.22.18/go.mod h1:0QFvDOOW7ANId78ChZSagyHbmP6CgMxDQrQFXzeaDpA= +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.22.21 h1:DGPCxn6co8VuTV0mton4NFO/ON49XiFMszRr+Mysy48= +github.com/pocketbase/pocketbase v0.22.21/go.mod h1:Cw5E4uoGhKItBIE2lJL3NfmiUr9Syk2xaNJ2G7Dssow= +github.com/pocketbase/pocketbase v0.23.12 h1:HB4THFbzaliF0C3wvpx+kNOZxIwCEMDqN3/17gn5N7E= +github.com/pocketbase/pocketbase v0.23.12/go.mod h1:OcFJNMO0Vzt3f9+lweMbup6iL7V13ckxu1pdEY6FeM0= 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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -702,8 +726,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdkk= -github.com/qiniu/go-sdk/v7 v7.22.0 h1:NiRj6+beSkKsPBr4XN9OdjPJQKhERtOwOwu3HJtzcWQ= -github.com/qiniu/go-sdk/v7 v7.22.0/go.mod h1:44lnyCs6gflCxMUV1yTBlZhPEB4ZO6LIDHkMV8Rofms= +github.com/qiniu/go-sdk/v7 v7.25.1 h1:fynXKE2RP9XYkispAI3YI+eML39JFEx2+PLYP46ephA= +github.com/qiniu/go-sdk/v7 v7.25.1/go.mod h1:uZE85Pi0ftIHT/UNLShosdzwsovqpdas0LwAGO7cPao= 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= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -729,8 +753,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.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= +github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -757,26 +781,22 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +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/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM= github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1017 h1:OymmfmyFkvHirY3WHsoRT3cdTEsqygLbMn8jM41erK4= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1017/go.mod h1:gnLxGXlLmF+jDqWR1/RVoF/UUwxQxomQhkc0oN7KeuI= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1031 h1:/eVMCl+jadCex6HxNN6/hFbC0iWl+e8s4PSIcI8aqS4= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1031/go.mod h1:8Km0fRIaDS7PssuyxDFvRRFBUFmECqG+ICpViCs/Vak= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.992/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1017/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1030/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1031/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1034 h1:T7ewuO2DD+5R2LRpD2kTRy25aCkVDVdYkmmyUS63i08= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1034/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1034 h1:hXxv58/eSlDj80n0P0ISXh91pC/2vqurJNwn5SpXFPI= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1034/go.mod h1:hwTIplwF9IYWz5HQcyw0+R8aqJB0lEZB8sI0pIA5Htw= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.992 h1:A6O89OlCJQUpNxGqC/E5By04UNKBryIt5olQIGOx8mg= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.992/go.mod h1:BcvC7ZPdSlhRggVq4J1ToJlgv8bmODIAuSo0naFZOLo= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1030 h1:tlHbfQlAfL12J/5XF4indKl0cAA3vEn6TDiGZVsr050= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1030/go.mod h1:8dW6JByZKNDAPnjlXxBk9yDc+QGbldpa0tBRfi1kG+U= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1065 h1:q0Op2QlMmag0R2vZX08GvOh0T29dcUqc+aIHF6a1sIE= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1065/go.mod h1:UiS7HMWbxGhO/y7nmnHuBMyP4qEDmJeooK6YKWNMuEw= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1065 h1:Kb/l5yh9M6Ow59ZRAMcdIBxsNT3uy8fZYh8xy2rM+xQ= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1065/go.mod h1:bgwicHdrBXLcgB4mQd8pWbSNuM7fIAjhxHfdZ/Hb7p4= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1065 h1:krcqtAmexnHHBm/4ge4tr2b1cn/a7JGBESVGoZYXQAE= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1065/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1065 h1:aEFtLD1ceyeljQXB1S2BjN0zjTkf0X3XmpuxFIiC29w= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1065/go.mod h1:HWvwy09hFSMXrj9SMvVRWV4U7rZO3l+WuogyNuxiT3M= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1065 h1:rHI/2WYmEBfnqVNo5iUy0gu0J7ekFBE/NDV/oKZv448= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1065/go.mod h1:nnd6/G8xfl7RMsm2XYdQT5SfjdxG/U09QaC6qO89JJg= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1065 h1:gDuqak8/kNgF99+ksk70JHjI1Poa5pmrgYDW6xYya8I= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1065/go.mod h1:r6yv70O5CZLsVhz6z05ZTGVUYxKQtGE2p90mopsR014= 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= @@ -790,8 +810,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/volcengine/volc-sdk-golang v1.0.184 h1:vSpr4nuKAbiAmGkOJAupkHIvd3oM08JNMyHJU/21loQ= -github.com/volcengine/volc-sdk-golang v1.0.184/go.mod h1:u0VtPvlXWpXDTmc9IHkaW1q+5Jjwus4oAqRhNMDRInE= +github.com/volcengine/volc-sdk-golang v1.0.189 h1:VMDTHWYXakXJtZqPYn0As/h4eB0c4imvyru6mIp+o60= +github.com/volcengine/volc-sdk-golang v1.0.189/go.mod h1:u0VtPvlXWpXDTmc9IHkaW1q+5Jjwus4oAqRhNMDRInE= 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= @@ -821,16 +841,22 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= -go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= -go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= -go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= -go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= -go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= -go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= +go.opentelemetry.io/contrib/detectors/gcp v1.31.0 h1:G1JQOreVrfhRkner+l4mrGxmfqYCAuy76asTDAo0xsA= +go.opentelemetry.io/contrib/detectors/gcp v1.31.0/go.mod h1:tzQL6E1l+iV44YFTkcAeNQqzXUiekSYP9jjJjXwEd00= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 h1:yMkBS9yViCc7U7yeLzJPM2XizlfdVvBRSmsQDWu6qc0= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0/go.mod h1:n8MR6/liuGB5EmTETUBeU5ZgqMOlqKRxUaqPQBOANZ8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= +go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= +go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= @@ -840,8 +866,8 @@ go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9i go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -gocloud.dev v0.37.0 h1:XF1rN6R0qZI/9DYjN16Uy0durAmSlf58DHOcb28GPro= -gocloud.dev v0.37.0/go.mod h1:7/O4kqdInCNsc6LqgmuFnS0GRew4XNNYWpA44yQnwco= +gocloud.dev v0.40.0 h1:f8LgP+4WDqOG/RXoUcyLpeIAGOcAbZrZbDQCUee10ng= +gocloud.dev v0.40.0/go.mod h1:drz+VyYNBvrMTW0KZiBAYEdl8lbNZx+OQ7oQvdrFmSQ= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -861,16 +887,16 @@ golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= 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= @@ -884,14 +910,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-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo= +golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= 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.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ= -golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E= +golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68= +golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY= 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= @@ -912,11 +938,10 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= 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= @@ -960,7 +985,6 @@ golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= @@ -970,16 +994,16 @@ golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= 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.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= -golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= 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= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= -golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= +golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -993,8 +1017,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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= @@ -1058,33 +1082,33 @@ golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= -golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1102,15 +1126,15 @@ golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 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.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= 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= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= -golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= +golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1163,14 +1187,14 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 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.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= -golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= +golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= +golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= 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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= -golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= @@ -1191,8 +1215,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.204.0 h1:3PjmQQEDkR/ENVZZwIYB4W/KzYtN8OrqnNcHWpeR8E4= -google.golang.org/api v0.204.0/go.mod h1:69y8QSoKIbL9F94bWgWAq6wGqGwyjBgi2y8rAK8zLag= +google.golang.org/api v0.214.0 h1:h2Gkq07OYi6kusGOaT/9rnNljuXmqPnaig7WGPmKbwA= +google.golang.org/api v0.214.0/go.mod h1:bYPpLG8AyeMWwDU6NXoB00xC0DFkikVvd5MfwoxjLqE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1233,10 +1257,10 @@ google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxH google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 h1:Q3nlH8iSQSRUwOskjbcSMcF2jiYMNiQYZ0c2KEJLKKU= google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38/go.mod h1:xBI+tzfqGGN2JBeSebfKXFSdBpWVQ7sLW40PTupVRm4= -google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 h1:fVoAXEKA4+yufmbdVYv+SE73+cPZbbbe8paLsHfkK+U= -google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 h1:zciRKQ4kBpFgpfC5QQCVtnnNAcLIqweL7plyZRQHVpI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q= +google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241219192143-6b3ec007d9bb h1:3oy2tynMOP1QbTC0MsNNAV+Se8M2Bd0A5+x1QHyw+pI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241219192143-6b3ec007d9bb/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1254,8 +1278,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU= +google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1271,8 +1295,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ= +google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1281,6 +1305,8 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= @@ -1313,40 +1339,41 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt 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= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= -k8s.io/api v0.31.1 h1:Xe1hX/fPW3PXYYv8BlozYqw63ytA92snr96zMW9gWTU= -k8s.io/api v0.31.1/go.mod h1:sbN1g6eY6XVLeqNsZGLnI5FwVseTrZX7Fv3O26rhAaI= -k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U= -k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -k8s.io/client-go v0.31.1 h1:f0ugtWSbWpxHR7sjVpQwuvw9a3ZKLXX0u0itkFXufb0= -k8s.io/client-go v0.31.1/go.mod h1:sKI8871MJN2OyeqRlmA4W4KM9KBdBUpDLu/43eGemCg= +k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE= +k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0= +k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg= +k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8= +k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8= 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-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= -modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= -modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y= -modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s= +k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= +k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +modernc.org/cc/v4 v4.24.1 h1:mLykA8iIlZ/SZbwI2JgYIURXQMSgmOb/+5jaielxPi4= +modernc.org/cc/v4 v4.24.1/go.mod h1:T1lKJZhXIi2VSqGBiB4LIbKs9NsKTbUXj4IDrmGqtTI= +modernc.org/ccgo/v4 v4.23.5 h1:6uAwu8u3pnla3l/+UVUrDDO1HIGxHTYmFH6w+X9nsyw= +modernc.org/ccgo/v4 v4.23.5/go.mod h1:FogrWfBdzqLWm1ku6cfr4IzEFouq2fSAPf6aSAHdAJQ= +modernc.org/fileutil v1.0.0/go.mod h1:JHsWpkrk/CnVV1H/eGlFf85BEpfkrp56ro8nojIq9Q8= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= -modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= -modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= -modernc.org/gc/v3 v3.0.0-20240722195230-4a140ff9c08e h1:WPC4v0rNIFb2PY+nBBEEKyugPPRHPzUgyN3xZPpGK58= -modernc.org/gc/v3 v3.0.0-20240722195230-4a140ff9c08e/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= -modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= -modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= -modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= -modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/gc/v2 v2.6.0 h1:Tiw3pezQj7PfV8k4Dzyu/vhRHR2e92kOXtTFU8pbCl4= +modernc.org/gc/v2 v2.6.0/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= +modernc.org/gc/v3 v3.0.0-20241213165251-3bc300f6d0c9 h1:ovz6yUKX71igz2yvk4NpiCL5fvdjZAI+DhuDEGx1xyU= +modernc.org/gc/v3 v3.0.0-20241213165251-3bc300f6d0c9/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/libc v1.61.5 h1:WzsPUvWl2CvsRmk2foyWWHUEUmQ2iW4oFyWOVR0O5ho= +modernc.org/libc v1.61.5/go.mod h1:llBdEGIywhnRgAFuTF+CWaKV8/2bFgACcQZTXhkAuAM= +modernc.org/mathutil v1.7.0 h1:KPlMfpLMs4EXAo8T8JJEkmCT9KP/B4vU1+GaBnDhHQY= +modernc.org/mathutil v1.7.0/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.34.4 h1:sjdARozcL5KJBvYQvLlZEmctRgW9xqIZc2ncN7PU0P8= +modernc.org/sqlite v1.34.4/go.mod h1:3QQFCG2SEMtc2nv+Wq4cQCH7Hjcg+p/RMlS1XK+zwbk= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= @@ -1355,10 +1382,10 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/internal/utils/app/app.go b/internal/app/app.go similarity index 80% rename from internal/utils/app/app.go rename to internal/app/app.go index 65952c38..7a13e2ea 100644 --- a/internal/utils/app/app.go +++ b/internal/app/app.go @@ -1,6 +1,7 @@ package app import ( + "log/slog" "sync" "github.com/pocketbase/pocketbase" @@ -19,3 +20,7 @@ func GetApp() *pocketbase.PocketBase { return instance } + +func GetLogger() *slog.Logger { + return GetApp().Logger() +} diff --git a/internal/utils/app/schedule.go b/internal/app/scheduler.go similarity index 85% rename from internal/utils/app/schedule.go rename to internal/app/scheduler.go index 2361ccab..6b274302 100644 --- a/internal/utils/app/schedule.go +++ b/internal/app/scheduler.go @@ -7,14 +7,14 @@ import ( "github.com/pocketbase/pocketbase/tools/cron" ) -var schedulerOnce sync.Once - var scheduler *cron.Cron +var schedulerOnce sync.Once + func GetScheduler() *cron.Cron { schedulerOnce.Do(func() { scheduler = cron.New() - location, err := time.LoadLocation("Asia/Shanghai") + location, err := time.LoadLocation("Local") if err == nil { scheduler.SetTimezone(location) } diff --git a/internal/applicant/acme-ca.go b/internal/applicant/acme-ca.go new file mode 100644 index 00000000..57f24b6e --- /dev/null +++ b/internal/applicant/acme-ca.go @@ -0,0 +1,38 @@ +package applicant + +const ( + sslProviderLetsEncrypt = "letsencrypt" + sslProviderLetsEncryptStaging = "letsencrypt_staging" + sslProviderZeroSSL = "zerossl" + sslProviderGoogleTrustServices = "gts" +) +const defaultSSLProvider = sslProviderLetsEncrypt + +const ( + letsencryptUrl = "https://acme-v02.api.letsencrypt.org/directory" + letsencryptStagingUrl = "https://acme-staging-v02.api.letsencrypt.org/directory" + zerosslUrl = "https://acme.zerossl.com/v2/DV90" + gtsUrl = "https://dv.acme-v02.api.pki.goog/directory" +) + +var sslProviderUrls = map[string]string{ + sslProviderLetsEncrypt: letsencryptUrl, + sslProviderLetsEncryptStaging: letsencryptStagingUrl, + sslProviderZeroSSL: zerosslUrl, + sslProviderGoogleTrustServices: gtsUrl, +} + +type acmeSSLProviderConfig struct { + Config acmeSSLProviderConfigContent `json:"config"` + Provider string `json:"provider"` +} + +type acmeSSLProviderConfigContent struct { + ZeroSSL acmeSSLProviderEabConfig `json:"zerossl"` + GoogleTrustServices acmeSSLProviderEabConfig `json:"gts"` +} + +type acmeSSLProviderEabConfig struct { + EabHmacKey string `json:"eabHmacKey"` + EabKid string `json:"eabKid"` +} diff --git a/internal/applicant/acme-user.go b/internal/applicant/acme-user.go new file mode 100644 index 00000000..11aa1fff --- /dev/null +++ b/internal/applicant/acme-user.go @@ -0,0 +1,125 @@ +package applicant + +import ( + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "fmt" + + "github.com/go-acme/lego/v4/lego" + "github.com/go-acme/lego/v4/registration" + + "github.com/usual2970/certimate/internal/domain" + "github.com/usual2970/certimate/internal/pkg/utils/x509" + "github.com/usual2970/certimate/internal/repository" +) + +type acmeUser struct { + CA string + Email string + Registration *registration.Resource + + privkey string +} + +func newAcmeUser(ca, email string) (*acmeUser, error) { + repo := repository.NewAcmeAccountRepository() + + applyUser := &acmeUser{ + CA: ca, + Email: email, + } + + acmeAccount, err := repo.GetByCAAndEmail(ca, email) + if err != nil { + key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return nil, err + } + + keyPEM, err := x509.ConvertECPrivateKeyToPEM(key) + if err != nil { + return nil, err + } + + applyUser.privkey = keyPEM + return applyUser, nil + } + + applyUser.Registration = acmeAccount.Resource + applyUser.privkey = acmeAccount.Key + + return applyUser, nil +} + +func (u *acmeUser) GetEmail() string { + return u.Email +} + +func (u acmeUser) GetRegistration() *registration.Resource { + return u.Registration +} + +func (u *acmeUser) GetPrivateKey() crypto.PrivateKey { + rs, _ := x509.ParseECPrivateKeyFromPEM(u.privkey) + return rs +} + +func (u *acmeUser) hasRegistration() bool { + return u.Registration != nil +} + +func (u *acmeUser) getPrivateKeyPEM() string { + return u.privkey +} + +type acmeAccountRepository interface { + GetByCAAndEmail(ca, email string) (*domain.AcmeAccount, error) + Save(ca, email, key string, resource *registration.Resource) error +} + +func registerAcmeUser(client *lego.Client, sslProviderConfig *acmeSSLProviderConfig, user *acmeUser) (*registration.Resource, error) { + // TODO: fix 潜在的并发问题 + + var reg *registration.Resource + var err error + switch sslProviderConfig.Provider { + case sslProviderZeroSSL: + reg, err = client.Registration.RegisterWithExternalAccountBinding(registration.RegisterEABOptions{ + TermsOfServiceAgreed: true, + Kid: sslProviderConfig.Config.ZeroSSL.EabKid, + HmacEncoded: sslProviderConfig.Config.ZeroSSL.EabHmacKey, + }) + case sslProviderGoogleTrustServices: + reg, err = client.Registration.RegisterWithExternalAccountBinding(registration.RegisterEABOptions{ + TermsOfServiceAgreed: true, + Kid: sslProviderConfig.Config.GoogleTrustServices.EabKid, + HmacEncoded: sslProviderConfig.Config.GoogleTrustServices.EabHmacKey, + }) + + case sslProviderLetsEncrypt, sslProviderLetsEncryptStaging: + reg, err = client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true}) + + default: + err = fmt.Errorf("unsupported ssl provider: %s", sslProviderConfig.Provider) + } + + if err != nil { + return nil, err + } + + repo := repository.NewAcmeAccountRepository() + + resp, err := repo.GetByCAAndEmail(sslProviderConfig.Provider, user.GetEmail()) + if err == nil { + user.privkey = resp.Key + return resp.Resource, nil + } + + if err := repo.Save(sslProviderConfig.Provider, user.GetEmail(), user.getPrivateKeyPEM(), reg); err != nil { + return nil, fmt.Errorf("failed to save registration: %w", err) + } + + return reg, nil +} diff --git a/internal/applicant/aliyun.go b/internal/applicant/aliyun.go deleted file mode 100644 index 40adf960..00000000 --- a/internal/applicant/aliyun.go +++ /dev/null @@ -1,36 +0,0 @@ -package applicant - -import ( - "encoding/json" - "fmt" - "os" - - "github.com/go-acme/lego/v4/providers/dns/alidns" - - "github.com/usual2970/certimate/internal/domain" -) - -type aliyun struct { - option *ApplyOption -} - -func NewAliyun(option *ApplyOption) Applicant { - return &aliyun{ - option: option, - } -} - -func (a *aliyun) Apply() (*Certificate, error) { - access := &domain.AliyunAccess{} - json.Unmarshal([]byte(a.option.Access), access) - - os.Setenv("ALICLOUD_ACCESS_KEY", access.AccessKeyId) - os.Setenv("ALICLOUD_SECRET_KEY", access.AccessKeySecret) - os.Setenv("ALICLOUD_PROPAGATION_TIMEOUT", fmt.Sprintf("%d", a.option.Timeout)) - dnsProvider, err := alidns.NewDNSProvider() - if err != nil { - return nil, err - } - - return apply(a.option, dnsProvider) -} diff --git a/internal/applicant/applicant.go b/internal/applicant/applicant.go index ddfbe60f..2f2f411f 100644 --- a/internal/applicant/applicant.go +++ b/internal/applicant/applicant.go @@ -2,283 +2,110 @@ package applicant import ( "context" - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "errors" + "encoding/json" "fmt" "os" "strconv" "strings" - "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/pkg/utils/x509" - "github.com/usual2970/certimate/internal/repository" - "github.com/usual2970/certimate/internal/utils/app" - "github.com/go-acme/lego/v4/certcrypto" "github.com/go-acme/lego/v4/certificate" "github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge/dns01" "github.com/go-acme/lego/v4/lego" - "github.com/go-acme/lego/v4/registration" - "github.com/pocketbase/pocketbase/models" + + "github.com/usual2970/certimate/internal/domain" + "github.com/usual2970/certimate/internal/repository" ) -/* -提供商类型常量值。 - - 注意:如果追加新的常量值,请保持以 ASCII 排序。 - NOTICE: If you add new constant, please keep ASCII order. -*/ -const ( - configTypeACMEHttpReq = "acmehttpreq" - configTypeAliyun = "aliyun" - configTypeAWS = "aws" - configTypeCloudflare = "cloudflare" - configTypeGoDaddy = "godaddy" - configTypeHuaweiCloud = "huaweicloud" - configTypeNameDotCom = "namedotcom" - configTypeNameSilo = "namesilo" - configTypePowerDNS = "powerdns" - configTypeTencentCloud = "tencentcloud" - configTypeVolcEngine = "volcengine" -) - -const defaultSSLProvider = "letsencrypt" -const ( - sslProviderLetsencrypt = "letsencrypt" - sslProviderZeroSSL = "zerossl" - sslProviderGts = "gts" -) - -const ( - zerosslUrl = "https://acme.zerossl.com/v2/DV90" - letsencryptUrl = "https://acme-v02.api.letsencrypt.org/directory" - gtsUrl = "https://dv.acme-v02.api.pki.goog/directory" -) - -var sslProviderUrls = map[string]string{ - sslProviderLetsencrypt: letsencryptUrl, - sslProviderZeroSSL: zerosslUrl, - sslProviderGts: gtsUrl, +type applyConfig struct { + Domains string + ContactEmail string + AccessConfig string + KeyAlgorithm string + Nameservers string + PropagationTimeout int32 + DisableFollowCNAME bool } -const defaultEmail = "536464346@qq.com" - -const defaultTimeout = 60 - -type Certificate struct { - CertUrl string `json:"certUrl"` - CertStableUrl string `json:"certStableUrl"` - PrivateKey string `json:"privateKey"` - Certificate string `json:"certificate"` - IssuerCertificate string `json:"issuerCertificate"` - Csr string `json:"csr"` -} - -type ApplyOption struct { - Email string `json:"email"` - Domain string `json:"domain"` - Access string `json:"access"` - KeyAlgorithm string `json:"keyAlgorithm"` - Nameservers string `json:"nameservers"` - Timeout int64 `json:"timeout"` - DisableFollowCNAME bool `json:"disableFollowCNAME"` -} - -type ApplyUser struct { - Ca string - Email string - Registration *registration.Resource - key string -} - -func newApplyUser(ca, email string) (*ApplyUser, error) { - repo := getAcmeAccountRepository() - rs := &ApplyUser{ - Ca: ca, - Email: email, - } - resp, err := repo.GetByCAAndEmail(ca, email) - if err != nil { - privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - if err != nil { - return nil, err - } - keyStr, err := x509.ConvertECPrivateKeyToPEM(privateKey) - if err != nil { - return nil, err - } - rs.key = keyStr - - return rs, nil - } - - rs.Registration = resp.Resource - rs.key = resp.Key - - return rs, nil -} - -func (u *ApplyUser) GetEmail() string { - return u.Email -} - -func (u ApplyUser) GetRegistration() *registration.Resource { - return u.Registration -} - -func (u *ApplyUser) GetPrivateKey() crypto.PrivateKey { - rs, _ := x509.ParseECPrivateKeyFromPEM(u.key) - return rs -} - -func (u *ApplyUser) hasRegistration() bool { - return u.Registration != nil -} - -func (u *ApplyUser) getPrivateKeyString() string { - return u.key +type ApplyCertResult struct { + Certificate string + PrivateKey string + IssuerCertificate string + ACMECertUrl string + ACMECertStableUrl string + CSR string } type Applicant interface { - Apply() (*Certificate, error) + Apply() (*ApplyCertResult, error) } -func Get(record *models.Record) (Applicant, error) { - if record.GetString("applyConfig") == "" { - return nil, errors.New("applyConfig is empty") +func NewWithApplyNode(node *domain.WorkflowNode) (Applicant, error) { + if node.Type != domain.WorkflowNodeTypeApply { + return nil, fmt.Errorf("node type is not apply") } - applyConfig := &domain.ApplyConfig{} - record.UnmarshalJSONField("applyConfig", applyConfig) - - access, err := app.GetApp().Dao().FindRecordById("access", applyConfig.Access) - if err != nil { - return nil, fmt.Errorf("access record not found: %w", err) - } - - if applyConfig.Email == "" { - applyConfig.Email = defaultEmail - } - - if applyConfig.Timeout == 0 { - applyConfig.Timeout = defaultTimeout - } - - option := &ApplyOption{ - Email: applyConfig.Email, - Domain: record.GetString("domain"), - Access: access.GetString("config"), - KeyAlgorithm: applyConfig.KeyAlgorithm, - Nameservers: applyConfig.Nameservers, - Timeout: applyConfig.Timeout, - DisableFollowCNAME: applyConfig.DisableFollowCNAME, - } - - return GetWithTypeOption(access.GetString("configType"), option) -} - -func GetWithApplyNode(node *domain.WorkflowNode) (Applicant, error) { - // 获取授权配置 accessRepo := repository.NewAccessRepository() - - access, err := accessRepo.GetById(context.Background(), node.GetConfigString("access")) + accessId := node.GetConfigString("providerAccessId") + access, err := accessRepo.GetById(context.Background(), accessId) if err != nil { - return nil, fmt.Errorf("access record not found: %w", err) + return nil, fmt.Errorf("failed to get access #%s record: %w", accessId, err) } - timeout := node.GetConfigInt64("timeout") - if timeout == 0 { - timeout = defaultTimeout - } - - applyConfig := &ApplyOption{ - Email: node.GetConfigString("email"), - Domain: node.GetConfigString("domain"), - Access: access.Config, + applyConfig := &applyConfig{ + Domains: node.GetConfigString("domains"), + ContactEmail: node.GetConfigString("contactEmail"), + AccessConfig: access.Config, KeyAlgorithm: node.GetConfigString("keyAlgorithm"), Nameservers: node.GetConfigString("nameservers"), - Timeout: timeout, + PropagationTimeout: node.GetConfigInt32("propagationTimeout"), DisableFollowCNAME: node.GetConfigBool("disableFollowCNAME"), } - return GetWithTypeOption(access.ConfigType, applyConfig) -} - -func GetWithTypeOption(t string, option *ApplyOption) (Applicant, error) { - switch t { - case configTypeAliyun: - return NewAliyun(option), nil - case configTypeTencentCloud: - return NewTencent(option), nil - case configTypeHuaweiCloud: - return NewHuaweiCloud(option), nil - case configTypeAWS: - return NewAws(option), nil - case configTypeCloudflare: - return NewCloudflare(option), nil - case configTypeNameDotCom: - return NewNameDotCom(option), nil - case configTypeNameSilo: - return NewNamesilo(option), nil - case configTypeGoDaddy: - return NewGodaddy(option), nil - case configTypePowerDNS: - return NewPdns(option), nil - case configTypeACMEHttpReq: - return NewHttpreq(option), nil - case configTypeVolcEngine: - return NewVolcengine(option), nil - default: - return nil, errors.New("unknown config type") - } -} - -type SSLProviderConfig struct { - Config SSLProviderConfigContent `json:"config"` - Provider string `json:"provider"` -} - -type SSLProviderConfigContent struct { - Zerossl SSLProviderEab `json:"zerossl"` - Gts SSLProviderEab `json:"gts"` -} - -type SSLProviderEab struct { - EabHmacKey string `json:"eabHmacKey"` - EabKid string `json:"eabKid"` -} - -func apply(option *ApplyOption, provider challenge.Provider) (*Certificate, error) { - record, _ := app.GetApp().Dao().FindFirstRecordByFilter("settings", "name='sslProvider'") - - sslProvider := &SSLProviderConfig{ - Config: SSLProviderConfigContent{}, - Provider: defaultSSLProvider, - } - if record != nil { - if err := record.UnmarshalJSONField("content", sslProvider); err != nil { - return nil, err - } - } - - // Some unified lego environment variables are configured here. - // link: https://github.com/go-acme/lego/issues/1867 - os.Setenv("LEGO_DISABLE_CNAME_SUPPORT", strconv.FormatBool(option.DisableFollowCNAME)) - - myUser, err := newApplyUser(sslProvider.Provider, option.Email) + challengeProvider, err := createChallengeProvider(domain.AccessProviderType(access.Provider), access.Config, applyConfig) if err != nil { return nil, err } + return &proxyApplicant{ + applicant: challengeProvider, + applyConfig: applyConfig, + }, nil +} + +func apply(challengeProvider challenge.Provider, applyConfig *applyConfig) (*ApplyCertResult, error) { + settingsRepo := repository.NewSettingsRepository() + settings, _ := settingsRepo.GetByName(context.Background(), "sslProvider") + + sslProviderConfig := &acmeSSLProviderConfig{ + Config: acmeSSLProviderConfigContent{}, + Provider: defaultSSLProvider, + } + if settings != nil { + if err := json.Unmarshal([]byte(settings.Content), sslProviderConfig); err != nil { + return nil, err + } + } + + if sslProviderConfig.Provider == "" { + sslProviderConfig.Provider = defaultSSLProvider + } + + myUser, err := newAcmeUser(sslProviderConfig.Provider, applyConfig.ContactEmail) + if err != nil { + return nil, err + } + + // Some unified lego environment variables are configured here. + // link: https://github.com/go-acme/lego/issues/1867 + os.Setenv("LEGO_DISABLE_CNAME_SUPPORT", strconv.FormatBool(applyConfig.DisableFollowCNAME)) + config := lego.NewConfig(myUser) // This CA URL is configured for a local dev instance of Boulder running in Docker in a VM. - config.CADirURL = sslProviderUrls[sslProvider.Provider] - config.Certificate.KeyType = parseKeyAlgorithm(option.KeyAlgorithm) + config.CADirURL = sslProviderUrls[sslProviderConfig.Provider] + config.Certificate.KeyType = parseKeyAlgorithm(applyConfig.KeyAlgorithm) // A client facilitates communication with the CA server. client, err := lego.NewClient(config) @@ -287,111 +114,41 @@ func apply(option *ApplyOption, provider challenge.Provider) (*Certificate, erro } challengeOptions := make([]dns01.ChallengeOption, 0) - nameservers := parseNameservers(option.Nameservers) - if len(nameservers) > 0 { - challengeOptions = append(challengeOptions, dns01.AddRecursiveNameservers(nameservers)) + if len(applyConfig.Nameservers) > 0 { + challengeOptions = append(challengeOptions, dns01.AddRecursiveNameservers(dns01.ParseNameservers(strings.Split(applyConfig.Nameservers, ";")))) + challengeOptions = append(challengeOptions, dns01.DisableAuthoritativeNssPropagationRequirement()) } - client.Challenge.SetDNS01Provider(provider, challengeOptions...) + client.Challenge.SetDNS01Provider(challengeProvider, challengeOptions...) // New users will need to register if !myUser.hasRegistration() { - reg, err := getReg(client, sslProvider, myUser) + reg, err := registerAcmeUser(client, sslProviderConfig, myUser) if err != nil { return nil, fmt.Errorf("failed to register: %w", err) } myUser.Registration = reg } - domains := strings.Split(option.Domain, ";") - request := certificate.ObtainRequest{ - Domains: domains, + certRequest := certificate.ObtainRequest{ + Domains: strings.Split(applyConfig.Domains, ";"), Bundle: true, } - certificates, err := client.Certificate.Obtain(request) + certResource, err := client.Certificate.Obtain(certRequest) if err != nil { return nil, err } - return &Certificate{ - CertUrl: certificates.CertURL, - CertStableUrl: certificates.CertStableURL, - PrivateKey: string(certificates.PrivateKey), - Certificate: string(certificates.Certificate), - IssuerCertificate: string(certificates.IssuerCertificate), - Csr: string(certificates.CSR), + return &ApplyCertResult{ + PrivateKey: string(certResource.PrivateKey), + Certificate: string(certResource.Certificate), + IssuerCertificate: string(certResource.IssuerCertificate), + CSR: string(certResource.CSR), + ACMECertUrl: certResource.CertURL, + ACMECertStableUrl: certResource.CertStableURL, }, nil } -type AcmeAccountRepository interface { - GetByCAAndEmail(ca, email string) (*domain.AcmeAccount, error) - Save(ca, email, key string, resource *registration.Resource) error -} - -func getAcmeAccountRepository() AcmeAccountRepository { - return repository.NewAcmeAccountRepository() -} - -func getReg(client *lego.Client, sslProvider *SSLProviderConfig, user *ApplyUser) (*registration.Resource, error) { - var reg *registration.Resource - var err error - switch sslProvider.Provider { - case sslProviderZeroSSL: - reg, err = client.Registration.RegisterWithExternalAccountBinding(registration.RegisterEABOptions{ - TermsOfServiceAgreed: true, - Kid: sslProvider.Config.Zerossl.EabKid, - HmacEncoded: sslProvider.Config.Zerossl.EabHmacKey, - }) - case sslProviderGts: - reg, err = client.Registration.RegisterWithExternalAccountBinding(registration.RegisterEABOptions{ - TermsOfServiceAgreed: true, - Kid: sslProvider.Config.Gts.EabKid, - HmacEncoded: sslProvider.Config.Gts.EabHmacKey, - }) - - case sslProviderLetsencrypt: - reg, err = client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true}) - - default: - err = errors.New("unknown ssl provider") - } - - if err != nil { - return nil, err - } - - repo := getAcmeAccountRepository() - - resp, err := repo.GetByCAAndEmail(sslProvider.Provider, user.GetEmail()) - if err == nil { - user.key = resp.Key - return resp.Resource, nil - } - - if err := repo.Save(sslProvider.Provider, user.GetEmail(), user.getPrivateKeyString(), reg); err != nil { - return nil, fmt.Errorf("failed to save registration: %w", err) - } - - return reg, nil -} - -func parseNameservers(ns string) []string { - nameservers := make([]string, 0) - - lines := strings.Split(ns, ";") - - for _, line := range lines { - line = strings.TrimSpace(line) - if line == "" { - continue - } - - nameservers = append(nameservers, line) - } - - return nameservers -} - func parseKeyAlgorithm(algo string) certcrypto.KeyType { switch algo { case "RSA2048": @@ -410,3 +167,13 @@ func parseKeyAlgorithm(algo string) certcrypto.KeyType { return certcrypto.RSA2048 } } + +// TODO: 暂时使用代理模式以兼容之前版本代码,后续重新实现此处逻辑 +type proxyApplicant struct { + applicant challenge.Provider + applyConfig *applyConfig +} + +func (d *proxyApplicant) Apply() (*ApplyCertResult, error) { + return apply(d.applicant, d.applyConfig) +} diff --git a/internal/applicant/aws.go b/internal/applicant/aws.go deleted file mode 100644 index be18d747..00000000 --- a/internal/applicant/aws.go +++ /dev/null @@ -1,39 +0,0 @@ -package applicant - -import ( - "encoding/json" - "fmt" - "os" - - "github.com/go-acme/lego/v4/providers/dns/route53" - - "github.com/usual2970/certimate/internal/domain" -) - -type aws struct { - option *ApplyOption -} - -func NewAws(option *ApplyOption) Applicant { - return &aws{ - option: option, - } -} - -func (t *aws) Apply() (*Certificate, error) { - access := &domain.AwsAccess{} - json.Unmarshal([]byte(t.option.Access), access) - - os.Setenv("AWS_REGION", access.Region) - os.Setenv("AWS_ACCESS_KEY_ID", access.AccessKeyId) - os.Setenv("AWS_SECRET_ACCESS_KEY", access.SecretAccessKey) - os.Setenv("AWS_HOSTED_ZONE_ID", access.HostedZoneId) - os.Setenv("AWS_PROPAGATION_TIMEOUT", fmt.Sprintf("%d", t.option.Timeout)) - - dnsProvider, err := route53.NewDNSProvider() - if err != nil { - return nil, err - } - - return apply(t.option, dnsProvider) -} diff --git a/internal/applicant/cloudflare.go b/internal/applicant/cloudflare.go deleted file mode 100644 index f1c40ebe..00000000 --- a/internal/applicant/cloudflare.go +++ /dev/null @@ -1,36 +0,0 @@ -package applicant - -import ( - "encoding/json" - "fmt" - "os" - - cf "github.com/go-acme/lego/v4/providers/dns/cloudflare" - - "github.com/usual2970/certimate/internal/domain" -) - -type cloudflare struct { - option *ApplyOption -} - -func NewCloudflare(option *ApplyOption) Applicant { - return &cloudflare{ - option: option, - } -} - -func (c *cloudflare) Apply() (*Certificate, error) { - access := &domain.CloudflareAccess{} - json.Unmarshal([]byte(c.option.Access), access) - - os.Setenv("CLOUDFLARE_DNS_API_TOKEN", access.DnsApiToken) - os.Setenv("CLOUDFLARE_PROPAGATION_TIMEOUT", fmt.Sprintf("%d", c.option.Timeout)) - - provider, err := cf.NewDNSProvider() - if err != nil { - return nil, err - } - - return apply(c.option, provider) -} diff --git a/internal/applicant/godaddy.go b/internal/applicant/godaddy.go deleted file mode 100644 index 7ae40a72..00000000 --- a/internal/applicant/godaddy.go +++ /dev/null @@ -1,37 +0,0 @@ -package applicant - -import ( - "encoding/json" - "fmt" - "os" - - godaddyProvider "github.com/go-acme/lego/v4/providers/dns/godaddy" - - "github.com/usual2970/certimate/internal/domain" -) - -type godaddy struct { - option *ApplyOption -} - -func NewGodaddy(option *ApplyOption) Applicant { - return &godaddy{ - option: option, - } -} - -func (a *godaddy) Apply() (*Certificate, error) { - access := &domain.GodaddyAccess{} - json.Unmarshal([]byte(a.option.Access), access) - - os.Setenv("GODADDY_API_KEY", access.ApiKey) - os.Setenv("GODADDY_API_SECRET", access.ApiSecret) - os.Setenv("GODADDY_PROPAGATION_TIMEOUT", fmt.Sprintf("%d", a.option.Timeout)) - - dnsProvider, err := godaddyProvider.NewDNSProvider() - if err != nil { - return nil, err - } - - return apply(a.option, dnsProvider) -} diff --git a/internal/applicant/httpreq.go b/internal/applicant/httpreq.go deleted file mode 100644 index 7972b7ae..00000000 --- a/internal/applicant/httpreq.go +++ /dev/null @@ -1,38 +0,0 @@ -package applicant - -import ( - "encoding/json" - "fmt" - "os" - - "github.com/go-acme/lego/v4/providers/dns/httpreq" - - "github.com/usual2970/certimate/internal/domain" -) - -type httpReq struct { - option *ApplyOption -} - -func NewHttpreq(option *ApplyOption) Applicant { - return &httpReq{ - option: option, - } -} - -func (a *httpReq) Apply() (*Certificate, error) { - access := &domain.HttpreqAccess{} - json.Unmarshal([]byte(a.option.Access), access) - - os.Setenv("HTTPREQ_ENDPOINT", access.Endpoint) - os.Setenv("HTTPREQ_MODE", access.Mode) - os.Setenv("HTTPREQ_USERNAME", access.Username) - os.Setenv("HTTPREQ_PASSWORD", access.Password) - os.Setenv("HTTPREQ_PROPAGATION_TIMEOUT", fmt.Sprintf("%d", a.option.Timeout)) - dnsProvider, err := httpreq.NewDNSProvider() - if err != nil { - return nil, err - } - - return apply(a.option, dnsProvider) -} diff --git a/internal/applicant/huaweicloud.go b/internal/applicant/huaweicloud.go deleted file mode 100644 index 47776400..00000000 --- a/internal/applicant/huaweicloud.go +++ /dev/null @@ -1,43 +0,0 @@ -package applicant - -import ( - "encoding/json" - "fmt" - "os" - - huaweicloudProvider "github.com/go-acme/lego/v4/providers/dns/huaweicloud" - - "github.com/usual2970/certimate/internal/domain" -) - -type huaweicloud struct { - option *ApplyOption -} - -func NewHuaweiCloud(option *ApplyOption) Applicant { - return &huaweicloud{ - option: option, - } -} - -func (t *huaweicloud) Apply() (*Certificate, error) { - access := &domain.HuaweiCloudAccess{} - json.Unmarshal([]byte(t.option.Access), access) - - region := access.Region - if region == "" { - region = "cn-north-1" - } - - os.Setenv("HUAWEICLOUD_REGION", region) // 华为云的 SDK 要求必须传一个区域,实际上 DNS-01 流程里用不到,但不传会报错 - os.Setenv("HUAWEICLOUD_ACCESS_KEY_ID", access.AccessKeyId) - os.Setenv("HUAWEICLOUD_SECRET_ACCESS_KEY", access.SecretAccessKey) - os.Setenv("HUAWEICLOUD_PROPAGATION_TIMEOUT", fmt.Sprintf("%d", t.option.Timeout)) - - dnsProvider, err := huaweicloudProvider.NewDNSProvider() - if err != nil { - return nil, err - } - - return apply(t.option, dnsProvider) -} diff --git a/internal/applicant/namedotcom.go b/internal/applicant/namedotcom.go deleted file mode 100644 index f3b2bf5e..00000000 --- a/internal/applicant/namedotcom.go +++ /dev/null @@ -1,36 +0,0 @@ -package applicant - -import ( - "encoding/json" - "time" - - "github.com/go-acme/lego/v4/providers/dns/namedotcom" - "github.com/usual2970/certimate/internal/domain" -) - -type nameDotCom struct { - option *ApplyOption -} - -func NewNameDotCom(option *ApplyOption) Applicant { - return &nameDotCom{ - option: option, - } -} - -func (n *nameDotCom) Apply() (*Certificate, error) { - access := &domain.NameDotComAccess{} - json.Unmarshal([]byte(n.option.Access), access) - - config := namedotcom.NewDefaultConfig() - config.Username = access.Username - config.APIToken = access.ApiToken - config.PropagationTimeout = time.Duration(n.option.Timeout) * time.Second - - dnsProvider, err := namedotcom.NewDNSProviderConfig(config) - if err != nil { - return nil, err - } - - return apply(n.option, dnsProvider) -} diff --git a/internal/applicant/namesilo.go b/internal/applicant/namesilo.go deleted file mode 100644 index 55fd3b3c..00000000 --- a/internal/applicant/namesilo.go +++ /dev/null @@ -1,36 +0,0 @@ -package applicant - -import ( - "encoding/json" - "fmt" - "os" - - namesiloProvider "github.com/go-acme/lego/v4/providers/dns/namesilo" - - "github.com/usual2970/certimate/internal/domain" -) - -type namesilo struct { - option *ApplyOption -} - -func NewNamesilo(option *ApplyOption) Applicant { - return &namesilo{ - option: option, - } -} - -func (a *namesilo) Apply() (*Certificate, error) { - access := &domain.NameSiloAccess{} - json.Unmarshal([]byte(a.option.Access), access) - - os.Setenv("NAMESILO_API_KEY", access.ApiKey) - os.Setenv("NAMESILO_PROPAGATION_TIMEOUT", fmt.Sprintf("%d", a.option.Timeout)) - - dnsProvider, err := namesiloProvider.NewDNSProvider() - if err != nil { - return nil, err - } - - return apply(a.option, dnsProvider) -} diff --git a/internal/applicant/pdns.go b/internal/applicant/pdns.go deleted file mode 100644 index 2c84c85e..00000000 --- a/internal/applicant/pdns.go +++ /dev/null @@ -1,36 +0,0 @@ -package applicant - -import ( - "encoding/json" - "fmt" - "os" - - "github.com/go-acme/lego/v4/providers/dns/pdns" - - "github.com/usual2970/certimate/internal/domain" -) - -type powerdns struct { - option *ApplyOption -} - -func NewPdns(option *ApplyOption) Applicant { - return &powerdns{ - option: option, - } -} - -func (a *powerdns) Apply() (*Certificate, error) { - access := &domain.PdnsAccess{} - json.Unmarshal([]byte(a.option.Access), access) - - os.Setenv("PDNS_API_URL", access.ApiUrl) - os.Setenv("PDNS_API_KEY", access.ApiKey) - os.Setenv("PDNS_PROPAGATION_TIMEOUT", fmt.Sprintf("%d", a.option.Timeout)) - dnsProvider, err := pdns.NewDNSProvider() - if err != nil { - return nil, err - } - - return apply(a.option, dnsProvider) -} diff --git a/internal/applicant/providers.go b/internal/applicant/providers.go new file mode 100644 index 00000000..c8800093 --- /dev/null +++ b/internal/applicant/providers.go @@ -0,0 +1,199 @@ +package applicant + +import ( + "encoding/json" + "fmt" + + "github.com/go-acme/lego/v4/challenge" + + "github.com/usual2970/certimate/internal/domain" + providerACMEHttpReq "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/acmehttpreq" + providerAliyun "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/aliyun" + providerAWS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/aws" + providerCloudflare "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare" + providerGoDaddy "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy" + providerHuaweiCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud" + providerNameDotCom "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom" + providerNameSilo "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo" + providerPowerDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns" + providerTencentCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud" + providerVolcEngine "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine" +) + +func createChallengeProvider(provider domain.AccessProviderType, accessConfig string, applyConfig *applyConfig) (challenge.Provider, error) { + /* + 注意:如果追加新的常量值,请保持以 ASCII 排序。 + NOTICE: If you add new constant, please keep ASCII order. + */ + switch provider { + case domain.AccessProviderTypeACMEHttpReq: + { + access := &domain.AccessConfigForACMEHttpReq{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerACMEHttpReq.NewChallengeProvider(&providerACMEHttpReq.ACMEHttpReqApplicantConfig{ + Endpoint: access.Endpoint, + Mode: access.Mode, + Username: access.Username, + Password: access.Password, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeAliyun: + { + access := &domain.AccessConfigForAliyun{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerAliyun.NewChallengeProvider(&providerAliyun.AliyunApplicantConfig{ + AccessKeyId: access.AccessKeyId, + AccessKeySecret: access.AccessKeySecret, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeAWS: + { + access := &domain.AccessConfigForAWS{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerAWS.NewChallengeProvider(&providerAWS.AWSApplicantConfig{ + AccessKeyId: access.AccessKeyId, + SecretAccessKey: access.SecretAccessKey, + Region: access.Region, + HostedZoneId: access.HostedZoneId, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeCloudflare: + { + access := &domain.AccessConfigForCloudflare{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerCloudflare.NewChallengeProvider(&providerCloudflare.CloudflareApplicantConfig{ + DnsApiToken: access.DnsApiToken, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeGoDaddy: + { + access := &domain.AccessConfigForGoDaddy{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerGoDaddy.NewChallengeProvider(&providerGoDaddy.GoDaddyApplicantConfig{ + ApiKey: access.ApiKey, + ApiSecret: access.ApiSecret, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeHuaweiCloud: + { + access := &domain.AccessConfigForHuaweiCloud{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerHuaweiCloud.NewChallengeProvider(&providerHuaweiCloud.HuaweiCloudApplicantConfig{ + AccessKeyId: access.AccessKeyId, + SecretAccessKey: access.SecretAccessKey, + Region: access.Region, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeNameDotCom: + { + access := &domain.AccessConfigForNameDotCom{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerNameDotCom.NewChallengeProvider(&providerNameDotCom.NameDotComApplicantConfig{ + Username: access.Username, + ApiToken: access.ApiToken, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeNameSilo: + { + access := &domain.AccessConfigForNameSilo{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerNameSilo.NewChallengeProvider(&providerNameSilo.NameSiloApplicantConfig{ + ApiKey: access.ApiKey, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypePowerDNS: + { + access := &domain.AccessConfigForPowerDNS{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerPowerDNS.NewChallengeProvider(&providerPowerDNS.PowerDNSApplicantConfig{ + ApiUrl: access.ApiUrl, + ApiKey: access.ApiKey, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeTencentCloud: + { + access := &domain.AccessConfigForTencentCloud{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerTencentCloud.NewChallengeProvider(&providerTencentCloud.TencentCloudApplicantConfig{ + SecretId: access.SecretId, + SecretKey: access.SecretKey, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeVolcEngine: + { + access := &domain.AccessConfigForVolcEngine{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerVolcEngine.NewChallengeProvider(&providerVolcEngine.VolcEngineApplicantConfig{ + AccessKeyId: access.AccessKeyId, + SecretAccessKey: access.SecretAccessKey, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + } + + return nil, fmt.Errorf("unsupported applicant provider: %s", provider) +} diff --git a/internal/applicant/tencent.go b/internal/applicant/tencent.go deleted file mode 100644 index 4733e22e..00000000 --- a/internal/applicant/tencent.go +++ /dev/null @@ -1,37 +0,0 @@ -package applicant - -import ( - "encoding/json" - "fmt" - "os" - - "github.com/go-acme/lego/v4/providers/dns/tencentcloud" - - "github.com/usual2970/certimate/internal/domain" -) - -type tencent struct { - option *ApplyOption -} - -func NewTencent(option *ApplyOption) Applicant { - return &tencent{ - option: option, - } -} - -func (t *tencent) Apply() (*Certificate, error) { - access := &domain.TencentAccess{} - json.Unmarshal([]byte(t.option.Access), access) - - os.Setenv("TENCENTCLOUD_SECRET_ID", access.SecretId) - os.Setenv("TENCENTCLOUD_SECRET_KEY", access.SecretKey) - os.Setenv("TENCENTCLOUD_PROPAGATION_TIMEOUT", fmt.Sprintf("%d", t.option.Timeout)) - - dnsProvider, err := tencentcloud.NewDNSProvider() - if err != nil { - return nil, err - } - - return apply(t.option, dnsProvider) -} diff --git a/internal/applicant/volcengine.go b/internal/applicant/volcengine.go deleted file mode 100644 index 3ab91741..00000000 --- a/internal/applicant/volcengine.go +++ /dev/null @@ -1,35 +0,0 @@ -package applicant - -import ( - "encoding/json" - "fmt" - "os" - - volcengineDns "github.com/go-acme/lego/v4/providers/dns/volcengine" - "github.com/usual2970/certimate/internal/domain" -) - -type volcengine struct { - option *ApplyOption -} - -func NewVolcengine(option *ApplyOption) Applicant { - return &volcengine{ - option: option, - } -} - -func (a *volcengine) Apply() (*Certificate, error) { - access := &domain.VolcEngineAccess{} - json.Unmarshal([]byte(a.option.Access), access) - - os.Setenv("VOLC_ACCESSKEY", access.AccessKeyId) - os.Setenv("VOLC_SECRETKEY", access.SecretAccessKey) - os.Setenv("VOLC_PROPAGATION_TIMEOUT", fmt.Sprintf("%d", a.option.Timeout)) - dnsProvider, err := volcengineDns.NewDNSProvider() - if err != nil { - return nil, err - } - - return apply(a.option, dnsProvider) -} diff --git a/internal/certificate/service.go b/internal/certificate/service.go index 8fdf060b..e2bdb0f1 100644 --- a/internal/certificate/service.go +++ b/internal/certificate/service.go @@ -6,19 +6,19 @@ import ( "strconv" "strings" + "github.com/usual2970/certimate/internal/app" "github.com/usual2970/certimate/internal/domain" "github.com/usual2970/certimate/internal/notify" "github.com/usual2970/certimate/internal/repository" - "github.com/usual2970/certimate/internal/utils/app" ) const ( - defaultExpireSubject = "您有 {COUNT} 张证书即将过期" - defaultExpireMessage = "有 {COUNT} 张证书即将过期,域名分别为 {DOMAINS},请保持关注!" + defaultExpireSubject = "您有 ${COUNT} 张证书即将过期" + defaultExpireMessage = "有 ${COUNT} 张证书即将过期,域名分别为 ${DOMAINS},请保持关注!" ) type CertificateRepository interface { - GetExpireSoon(ctx context.Context) ([]domain.Certificate, error) + ListExpireSoon(ctx context.Context) ([]domain.Certificate, error) } type certificateService struct { @@ -33,69 +33,72 @@ func NewCertificateService(repo CertificateRepository) *certificateService { func (s *certificateService) InitSchedule(ctx context.Context) error { scheduler := app.GetScheduler() - err := scheduler.Add("certificate", "0 0 * * *", func() { - certs, err := s.repo.GetExpireSoon(context.Background()) + certs, err := s.repo.ListExpireSoon(context.Background()) if err != nil { - app.GetApp().Logger().Error("failed to get expire soon certificate", "err", err) + app.GetLogger().Error("failed to get expire soon certificate", "err", err) return } - msg := buildMsg(certs) - if err := notify.SendToAllChannels(msg.Subject, msg.Message); err != nil { - app.GetApp().Logger().Error("failed to send expire soon certificate", "err", err) + + notification := buildExpireSoonNotification(certs) + if notification == nil { + return + } + + if err := notify.SendToAllChannels(notification.Subject, notification.Message); err != nil { + app.GetLogger().Error("failed to send expire soon certificate", "err", err) } }) if err != nil { - app.GetApp().Logger().Error("failed to add schedule", "err", err) + app.GetLogger().Error("failed to add schedule", "err", err) return err } scheduler.Start() - app.GetApp().Logger().Info("certificate schedule started") + app.GetLogger().Info("certificate schedule started") return nil } -func buildMsg(records []domain.Certificate) *domain.NotifyMessage { +type certificateNotification struct { + Subject string `json:"subject"` + Message string `json:"message"` +} + +func buildExpireSoonNotification(records []domain.Certificate) *certificateNotification { if len(records) == 0 { return nil } - // 查询模板信息 - settingRepo := repository.NewSettingRepository() - setting, err := settingRepo.GetByName(context.Background(), "notifyTemplates") - subject := defaultExpireSubject message := defaultExpireMessage + // 查询模板信息 + settingRepo := repository.NewSettingsRepository() + setting, err := settingRepo.GetByName(context.Background(), "notifyTemplates") if err == nil { - var templates *domain.NotifyTemplates - + var templates *domain.NotifyTemplatesSettingsContent json.Unmarshal([]byte(setting.Content), &templates) if templates != nil && len(templates.NotifyTemplates) > 0 { - subject = templates.NotifyTemplates[0].Title - message = templates.NotifyTemplates[0].Content + subject = templates.NotifyTemplates[0].Subject + message = templates.NotifyTemplates[0].Message } } // 替换变量 count := len(records) domains := make([]string, count) - for i, record := range records { - domains[i] = record.SAN + domains[i] = record.SubjectAltNames } - countStr := strconv.Itoa(count) domainStr := strings.Join(domains, ";") - - subject = strings.ReplaceAll(subject, "{COUNT}", countStr) - subject = strings.ReplaceAll(subject, "{DOMAINS}", domainStr) - - message = strings.ReplaceAll(message, "{COUNT}", countStr) - message = strings.ReplaceAll(message, "{DOMAINS}", domainStr) + subject = strings.ReplaceAll(subject, "${COUNT}", countStr) + subject = strings.ReplaceAll(subject, "${DOMAINS}", domainStr) + message = strings.ReplaceAll(message, "${COUNT}", countStr) + message = strings.ReplaceAll(message, "${DOMAINS}", domainStr) // 返回消息 - return &domain.NotifyMessage{ + return &certificateNotification{ Subject: subject, Message: message, } diff --git a/internal/deployer/deployer.go b/internal/deployer/deployer.go index 44fb4af6..5ad5d6ce 100644 --- a/internal/deployer/deployer.go +++ b/internal/deployer/deployer.go @@ -4,150 +4,56 @@ import ( "context" "fmt" - "github.com/pocketbase/pocketbase/models" - - "github.com/usual2970/certimate/internal/applicant" "github.com/usual2970/certimate/internal/domain" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/repository" ) -/* -提供商部署目标常量值。 - - 注意:如果追加新的常量值,请保持以 ASCII 排序。 - NOTICE: If you add new constant, please keep ASCII order. -*/ -const ( - targetAliyunALB = "aliyun-alb" - targetAliyunCDN = "aliyun-cdn" - targetAliyunCLB = "aliyun-clb" - targetAliyunDCDN = "aliyun-dcdn" - targetAliyunNLB = "aliyun-nlb" - targetAliyunOSS = "aliyun-oss" - targetBaiduCloudCDN = "baiducloud-cdn" - targetBytePlusCDN = "byteplus-cdn" - targetDogeCloudCDN = "dogecloud-cdn" - targetHuaweiCloudCDN = "huaweicloud-cdn" - targetHuaweiCloudELB = "huaweicloud-elb" - targetK8sSecret = "k8s-secret" - targetLocal = "local" - targetQiniuCDN = "qiniu-cdn" - targetSSH = "ssh" - targetTencentCloudCDN = "tencentcloud-cdn" - targetTencentCloudCLB = "tencentcloud-clb" - targetTencentCloudCOS = "tencentcloud-cos" - targetTencentCloudECDN = "tencentcloud-ecdn" - targetTencentCloudEO = "tencentcloud-eo" - targetVolcEngineCDN = "volcengine-cdn" - targetVolcEngineLive = "volcengine-live" - targetWebhook = "webhook" -) - -type DeployerOption struct { - DomainId string `json:"domainId"` - Domain string `json:"domain"` - Access string `json:"access"` - AccessRecord *domain.Access `json:"-"` - DeployConfig domain.DeployConfig `json:"deployConfig"` - Certificate applicant.Certificate `json:"certificate"` - Variables map[string]string `json:"variables"` -} - type Deployer interface { Deploy(ctx context.Context) error - GetInfos() []string - GetID() string } -func Gets(record *models.Record, cert *applicant.Certificate) ([]Deployer, error) { - rs := make([]Deployer, 0) - if record.GetString("deployConfig") == "" { - return rs, nil +func NewWithDeployNode(node *domain.WorkflowNode, certdata struct { + Certificate string + PrivateKey string +}, +) (Deployer, error) { + if node.Type != domain.WorkflowNodeTypeDeploy { + return nil, fmt.Errorf("node type is not deploy") } - deployConfigs := make([]domain.DeployConfig, 0) - - err := record.UnmarshalJSONField("deployConfig", &deployConfigs) - if err != nil { - return nil, fmt.Errorf("解析部署配置失败: %w", err) - } - - if len(deployConfigs) == 0 { - return rs, nil - } - - for _, deployConfig := range deployConfigs { - deployer, err := newWithDeployConfig(record, cert, deployConfig) - if err != nil { - return nil, err - } - - rs = append(rs, deployer) - } - - return rs, nil -} - -func GetWithTypeAndOption(deployType string, option *DeployerOption) (Deployer, error) { - return newWithTypeAndOption(deployType, option) -} - -func newWithDeployConfig(record *models.Record, cert *applicant.Certificate, deployConfig domain.DeployConfig) (Deployer, error) { accessRepo := repository.NewAccessRepository() - access, err := accessRepo.GetById(context.Background(), deployConfig.Access) + accessId := node.GetConfigString("providerAccessId") + access, err := accessRepo.GetById(context.Background(), accessId) if err != nil { - return nil, fmt.Errorf("获取access失败:%w", err) + return nil, fmt.Errorf("failed to get access #%s record: %w", accessId, err) } - option := &DeployerOption{ - DomainId: record.Id, - Domain: record.GetString("domain"), - Access: access.Config, - AccessRecord: access, - DeployConfig: deployConfig, - } - if cert != nil { - option.Certificate = *cert - } else { - option.Certificate = applicant.Certificate{ - Certificate: record.GetString("certificate"), - PrivateKey: record.GetString("privateKey"), - } - } - - return newWithTypeAndOption(deployConfig.Type, option) -} - -func newWithTypeAndOption(deployType string, option *DeployerOption) (Deployer, error) { - deployer, logger, err := createDeployer(deployType, option.AccessRecord.Config, option.DeployConfig.Config) + deployProvider := node.GetConfigString("provider") + deployConfig := node.GetConfigMap("providerConfig") + deployer, logger, err := createDeployer(domain.DeployProviderType(deployProvider), access.Config, deployConfig) if err != nil { return nil, err } return &proxyDeployer{ - option: option, - logger: logger, - deployer: deployer, + logger: logger, + deployer: deployer, + deployCertificate: certdata.Certificate, + deployPrivateKey: certdata.PrivateKey, }, nil } // TODO: 暂时使用代理模式以兼容之前版本代码,后续重新实现此处逻辑 type proxyDeployer struct { - option *DeployerOption - logger deployer.Logger - deployer deployer.Deployer -} - -func (d *proxyDeployer) GetID() string { - return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id) -} - -func (d *proxyDeployer) GetInfos() []string { - return d.logger.GetRecords() + logger logger.Logger + deployer deployer.Deployer + deployCertificate string + deployPrivateKey string } func (d *proxyDeployer) Deploy(ctx context.Context) error { - _, err := d.deployer.Deploy(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey) + _, err := d.deployer.Deploy(ctx, d.deployCertificate, d.deployPrivateKey) return err } diff --git a/internal/deployer/factory.go b/internal/deployer/providers.go similarity index 82% rename from internal/deployer/factory.go rename to internal/deployer/providers.go index d02800e1..be2feb32 100644 --- a/internal/deployer/factory.go +++ b/internal/deployer/providers.go @@ -30,26 +30,27 @@ import ( providerVolcEngineCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-cdn" providerVolcEngineLive "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-live" providerWebhook "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/webhook" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/utils/maps" ) -func createDeployer(target string, accessConfig string, deployConfig map[string]any) (deployer.Deployer, deployer.Logger, error) { - logger := deployer.NewDefaultLogger() +func createDeployer(provider domain.DeployProviderType, accessConfig string, deployConfig map[string]any) (deployer.Deployer, logger.Logger, error) { + logger := logger.NewDefaultLogger() /* 注意:如果追加新的常量值,请保持以 ASCII 排序。 NOTICE: If you add new constant, please keep ASCII order. */ - switch target { - case targetAliyunALB, targetAliyunCDN, targetAliyunCLB, targetAliyunDCDN, targetAliyunNLB, targetAliyunOSS: + switch provider { + case domain.DeployProviderTypeAliyunALB, domain.DeployProviderTypeAliyunCDN, domain.DeployProviderTypeAliyunCLB, domain.DeployProviderTypeAliyunDCDN, domain.DeployProviderTypeAliyunNLB, domain.DeployProviderTypeAliyunOSS: { - access := &domain.AliyunAccess{} + access := &domain.AccessConfigForAliyun{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } - switch target { - case targetAliyunALB: + switch provider { + case domain.DeployProviderTypeAliyunALB: deployer, err := providerAliyunALB.NewWithLogger(&providerAliyunALB.AliyunALBDeployerConfig{ AccessKeyId: access.AccessKeyId, AccessKeySecret: access.AccessKeySecret, @@ -60,7 +61,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetAliyunCDN: + case domain.DeployProviderTypeAliyunCDN: deployer, err := providerAliyunCDN.NewWithLogger(&providerAliyunCDN.AliyunCDNDeployerConfig{ AccessKeyId: access.AccessKeyId, AccessKeySecret: access.AccessKeySecret, @@ -68,7 +69,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetAliyunCLB: + case domain.DeployProviderTypeAliyunCLB: deployer, err := providerAliyunCLB.NewWithLogger(&providerAliyunCLB.AliyunCLBDeployerConfig{ AccessKeyId: access.AccessKeyId, AccessKeySecret: access.AccessKeySecret, @@ -79,7 +80,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetAliyunDCDN: + case domain.DeployProviderTypeAliyunDCDN: deployer, err := providerAliyunDCDN.NewWithLogger(&providerAliyunDCDN.AliyunDCDNDeployerConfig{ AccessKeyId: access.AccessKeyId, AccessKeySecret: access.AccessKeySecret, @@ -87,7 +88,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetAliyunNLB: + case domain.DeployProviderTypeAliyunNLB: deployer, err := providerAliyunNLB.NewWithLogger(&providerAliyunNLB.AliyunNLBDeployerConfig{ AccessKeyId: access.AccessKeyId, AccessKeySecret: access.AccessKeySecret, @@ -98,7 +99,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetAliyunOSS: + case domain.DeployProviderTypeAliyunOSS: deployer, err := providerAliyunOSS.NewWithLogger(&providerAliyunOSS.AliyunOSSDeployerConfig{ AccessKeyId: access.AccessKeyId, AccessKeySecret: access.AccessKeySecret, @@ -113,9 +114,9 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] } } - case targetBaiduCloudCDN: + case domain.DeployProviderTypeBaiduCloudCDN: { - access := &domain.BaiduCloudAccess{} + access := &domain.AccessConfigForBaiduCloud{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } @@ -128,9 +129,9 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] return deployer, logger, err } - case targetBytePlusCDN: + case domain.DeployProviderTypeBytePlusCDN: { - access := &domain.ByteplusAccess{} + access := &domain.AccessConfigForBytePlus{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } @@ -143,9 +144,9 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] return deployer, logger, err } - case targetDogeCloudCDN: + case domain.DeployProviderTypeDogeCloudCDN: { - access := &domain.DogeCloudAccess{} + access := &domain.AccessConfigForDogeCloud{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } @@ -158,15 +159,15 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] return deployer, logger, err } - case targetHuaweiCloudCDN, targetHuaweiCloudELB: + case domain.DeployProviderTypeHuaweiCloudCDN, domain.DeployProviderTypeHuaweiCloudELB: { - access := &domain.HuaweiCloudAccess{} + access := &domain.AccessConfigForHuaweiCloud{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } - switch target { - case targetHuaweiCloudCDN: + switch provider { + case domain.DeployProviderTypeHuaweiCloudCDN: deployer, err := providerHuaweiCloudCDN.NewWithLogger(&providerHuaweiCloudCDN.HuaweiCloudCDNDeployerConfig{ AccessKeyId: access.AccessKeyId, SecretAccessKey: access.SecretAccessKey, @@ -175,7 +176,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetHuaweiCloudELB: + case domain.DeployProviderTypeHuaweiCloudELB: deployer, err := providerHuaweiCloudELB.NewWithLogger(&providerHuaweiCloudELB.HuaweiCloudELBDeployerConfig{ AccessKeyId: access.AccessKeyId, SecretAccessKey: access.SecretAccessKey, @@ -192,13 +193,13 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] } } - case targetLocal: + case domain.DeployProviderTypeLocal: { deployer, err := providerLocal.NewWithLogger(&providerLocal.LocalDeployerConfig{ ShellEnv: providerLocal.ShellEnvType(maps.GetValueAsString(deployConfig, "shellEnv")), PreCommand: maps.GetValueAsString(deployConfig, "preCommand"), PostCommand: maps.GetValueAsString(deployConfig, "postCommand"), - OutputFormat: providerLocal.OutputFormatType(maps.GetValueOrDefaultAsString(deployConfig, "format", "PEM")), + OutputFormat: providerLocal.OutputFormatType(maps.GetValueOrDefaultAsString(deployConfig, "format", string(providerLocal.OUTPUT_FORMAT_PEM))), OutputCertPath: maps.GetValueAsString(deployConfig, "certPath"), OutputKeyPath: maps.GetValueAsString(deployConfig, "keyPath"), PfxPassword: maps.GetValueAsString(deployConfig, "pfxPassword"), @@ -209,9 +210,9 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] return deployer, logger, err } - case targetK8sSecret: + case domain.DeployProviderTypeK8sSecret: { - access := &domain.KubernetesAccess{} + access := &domain.AccessConfigForKubernetes{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } @@ -220,15 +221,16 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] KubeConfig: access.KubeConfig, Namespace: maps.GetValueOrDefaultAsString(deployConfig, "namespace", "default"), SecretName: maps.GetValueAsString(deployConfig, "secretName"), + SecretType: maps.GetValueOrDefaultAsString(deployConfig, "secretType", "kubernetes.io/tls"), SecretDataKeyForCrt: maps.GetValueOrDefaultAsString(deployConfig, "secretDataKeyForCrt", "tls.crt"), SecretDataKeyForKey: maps.GetValueOrDefaultAsString(deployConfig, "secretDataKeyForKey", "tls.key"), }, logger) return deployer, logger, err } - case targetQiniuCDN: + case domain.DeployProviderTypeQiniuCDN: { - access := &domain.QiniuAccess{} + access := &domain.AccessConfigForQiniu{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } @@ -241,9 +243,9 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] return deployer, logger, err } - case targetSSH: + case domain.DeployProviderTypeSSH: { - access := &domain.SSHAccess{} + access := &domain.AccessConfigForSSH{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } @@ -258,7 +260,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] SshKeyPassphrase: access.KeyPassphrase, PreCommand: maps.GetValueAsString(deployConfig, "preCommand"), PostCommand: maps.GetValueAsString(deployConfig, "postCommand"), - OutputFormat: providerSSH.OutputFormatType(maps.GetValueOrDefaultAsString(deployConfig, "format", "PEM")), + OutputFormat: providerSSH.OutputFormatType(maps.GetValueOrDefaultAsString(deployConfig, "format", string(providerSSH.OUTPUT_FORMAT_PEM))), OutputCertPath: maps.GetValueAsString(deployConfig, "certPath"), OutputKeyPath: maps.GetValueAsString(deployConfig, "keyPath"), PfxPassword: maps.GetValueAsString(deployConfig, "pfxPassword"), @@ -269,15 +271,15 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] return deployer, logger, err } - case targetTencentCloudCDN, targetTencentCloudCLB, targetTencentCloudCOS, targetTencentCloudECDN, targetTencentCloudEO: + case domain.DeployProviderTypeTencentCloudCDN, domain.DeployProviderTypeTencentCloudCLB, domain.DeployProviderTypeTencentCloudCOS, domain.DeployProviderTypeTencentCloudECDN, domain.DeployProviderTypeTencentCloudEO: { - access := &domain.TencentAccess{} + access := &domain.AccessConfigForTencentCloud{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } - switch target { - case targetTencentCloudCDN: + switch provider { + case domain.DeployProviderTypeTencentCloudCDN: deployer, err := providerTencentCloudCDN.NewWithLogger(&providerTencentCloudCDN.TencentCloudCDNDeployerConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, @@ -285,7 +287,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetTencentCloudCLB: + case domain.DeployProviderTypeTencentCloudCLB: deployer, err := providerTencentCloudCLB.NewWithLogger(&providerTencentCloudCLB.TencentCloudCLBDeployerConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, @@ -297,7 +299,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetTencentCloudCOS: + case domain.DeployProviderTypeTencentCloudCOS: deployer, err := providerTencentCloudCOD.NewWithLogger(&providerTencentCloudCOD.TencentCloudCOSDeployerConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, @@ -307,7 +309,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetTencentCloudECDN: + case domain.DeployProviderTypeTencentCloudECDN: deployer, err := providerTencentCloudECDN.NewWithLogger(&providerTencentCloudECDN.TencentCloudECDNDeployerConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, @@ -315,7 +317,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetTencentCloudEO: + case domain.DeployProviderTypeTencentCloudEO: deployer, err := providerTencentCloudEO.NewWithLogger(&providerTencentCloudEO.TencentCloudEODeployerConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, @@ -329,26 +331,26 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] } } - case targetVolcEngineCDN, targetVolcEngineLive: + case domain.DeployProviderTypeVolcEngineCDN, domain.DeployProviderTypeVolcEngineLive: { - access := &domain.VolcEngineAccess{} + access := &domain.AccessConfigForVolcEngine{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } - switch target { - case targetVolcEngineCDN: + switch provider { + case domain.DeployProviderTypeVolcEngineCDN: deployer, err := providerVolcEngineCDN.NewWithLogger(&providerVolcEngineCDN.VolcEngineCDNDeployerConfig{ - AccessKey: access.AccessKey, - SecretKey: access.SecretKey, + AccessKey: access.AccessKeyId, + SecretKey: access.SecretAccessKey, Domain: maps.GetValueAsString(deployConfig, "domain"), }, logger) return deployer, logger, err - case targetVolcEngineLive: + case domain.DeployProviderTypeVolcEngineLive: deployer, err := providerVolcEngineLive.NewWithLogger(&providerVolcEngineLive.VolcEngineLiveDeployerConfig{ - AccessKey: access.AccessKey, - SecretKey: access.SecretKey, + AccessKey: access.AccessKeyId, + SecretKey: access.SecretAccessKey, Domain: maps.GetValueAsString(deployConfig, "domain"), }, logger) return deployer, logger, err @@ -358,34 +360,20 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] } } - case targetWebhook: + case domain.DeployProviderTypeWebhook: { - access := &domain.WebhookAccess{} + access := &domain.AccessConfigForWebhook{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } - variables := make(map[string]string) - if deployConfig != nil { - value, ok := deployConfig["variables"] - if ok { - kvs := make([]domain.KV, 0) - bts, _ := json.Marshal(value) - if err := json.Unmarshal(bts, &kvs); err == nil { - for _, kv := range kvs { - variables[kv.Key] = kv.Value - } - } - } - } - deployer, err := providerWebhook.NewWithLogger(&providerWebhook.WebhookDeployerConfig{ - Url: access.Url, - Variables: variables, + WebhookUrl: access.Url, + WebhookData: maps.GetValueAsString(deployConfig, "webhookData"), }, logger) return deployer, logger, err } } - return nil, nil, fmt.Errorf("unsupported deployer target: %s", target) + return nil, nil, fmt.Errorf("unsupported deployer provider: %s", provider) } diff --git a/internal/domain/access.go b/internal/domain/access.go index 348e6c46..9a2bcb7d 100644 --- a/internal/domain/access.go +++ b/internal/domain/access.go @@ -4,109 +4,88 @@ import "time" type Access struct { Meta - Name string `json:"name"` - Config string `json:"config"` - ConfigType string `json:"configType"` - Deleted time.Time `json:"deleted"` - Usage string `json:"usage"` + Name string `json:"name" db:"name"` + Provider string `json:"provider" db:"provider"` + Config string `json:"config" db:"config"` + Usage string `json:"usage" db:"usage"` + DeletedAt time.Time `json:"deleted" db:"deleted"` } -// 兼容一下原 pocketbase 的 record -func (a *Access) GetString(key string) string { - switch key { - case "name": - return a.Name - default: - return "" - } -} - -type AliyunAccess struct { - AccessKeyId string `json:"accessKeyId"` - AccessKeySecret string `json:"accessKeySecret"` -} - -type ByteplusAccess struct { - AccessKey string `json:"accessKey"` - SecretKey string `json:"secretKey"` -} - -type TencentAccess struct { - SecretId string `json:"secretId"` - SecretKey string `json:"secretKey"` -} - -type HuaweiCloudAccess struct { - AccessKeyId string `json:"accessKeyId"` - SecretAccessKey string `json:"secretAccessKey"` - Region string `json:"region"` -} - -type BaiduCloudAccess struct { - AccessKeyId string `json:"accessKeyId"` - SecretAccessKey string `json:"secretAccessKey"` -} - -type AwsAccess struct { - AccessKeyId string `json:"accessKeyId"` - SecretAccessKey string `json:"secretAccessKey"` - Region string `json:"region"` - HostedZoneId string `json:"hostedZoneId"` -} - -type CloudflareAccess struct { - DnsApiToken string `json:"dnsApiToken"` -} - -type QiniuAccess struct { - AccessKey string `json:"accessKey"` - SecretKey string `json:"secretKey"` -} - -type DogeCloudAccess struct { - AccessKey string `json:"accessKey"` - SecretKey string `json:"secretKey"` -} - -type NameSiloAccess struct { - ApiKey string `json:"apiKey"` -} - -type GodaddyAccess struct { - ApiKey string `json:"apiKey"` - ApiSecret string `json:"apiSecret"` -} - -type NameDotComAccess struct { - Username string `json:"username"` - ApiToken string `json:"apiToken"` -} - -type PdnsAccess struct { - ApiUrl string `json:"apiUrl"` - ApiKey string `json:"apiKey"` -} - -type VolcEngineAccess struct { - AccessKey string `json:"accessKey"` - SecretKey string `json:"secretKey"` - - // Deprecated: Use [AccessKey] and [SecretKey] instead in the future - AccessKeyId string `json:"accessKeyId"` - // Deprecated: Use [AccessKey] and [SecretKey] instead in the future - SecretAccessKey string `json:"secretAccessKey"` -} - -type HttpreqAccess struct { +type AccessConfigForACMEHttpReq struct { Endpoint string `json:"endpoint"` Mode string `json:"mode"` Username string `json:"username"` Password string `json:"password"` } -type LocalAccess struct{} +type AccessConfigForAliyun struct { + AccessKeyId string `json:"accessKeyId"` + AccessKeySecret string `json:"accessKeySecret"` +} -type SSHAccess struct { +type AccessConfigForAWS struct { + AccessKeyId string `json:"accessKeyId"` + SecretAccessKey string `json:"secretAccessKey"` + Region string `json:"region"` + HostedZoneId string `json:"hostedZoneId"` +} + +type AccessConfigForBaiduCloud struct { + AccessKeyId string `json:"accessKeyId"` + SecretAccessKey string `json:"secretAccessKey"` +} + +type AccessConfigForBytePlus struct { + AccessKey string `json:"accessKey"` + SecretKey string `json:"secretKey"` +} + +type AccessConfigForCloudflare struct { + DnsApiToken string `json:"dnsApiToken"` +} + +type AccessConfigForDogeCloud struct { + AccessKey string `json:"accessKey"` + SecretKey string `json:"secretKey"` +} + +type AccessConfigForGoDaddy struct { + ApiKey string `json:"apiKey"` + ApiSecret string `json:"apiSecret"` +} + +type AccessConfigForHuaweiCloud struct { + AccessKeyId string `json:"accessKeyId"` + SecretAccessKey string `json:"secretAccessKey"` + Region string `json:"region"` +} + +type AccessConfigForLocal struct{} + +type AccessConfigForKubernetes struct { + KubeConfig string `json:"kubeConfig"` +} + +type AccessConfigForNameDotCom struct { + Username string `json:"username"` + ApiToken string `json:"apiToken"` +} + +type AccessConfigForNameSilo struct { + ApiKey string `json:"apiKey"` +} + +type AccessConfigForPowerDNS struct { + ApiUrl string `json:"apiUrl"` + ApiKey string `json:"apiKey"` +} + +type AccessConfigForQiniu struct { + AccessKey string `json:"accessKey"` + SecretKey string `json:"secretKey"` +} + +type AccessConfigForSSH struct { Host string `json:"host"` Port string `json:"port"` Username string `json:"username"` @@ -115,10 +94,16 @@ type SSHAccess struct { KeyPassphrase string `json:"keyPassphrase"` } -type WebhookAccess struct { - Url string `json:"url"` +type AccessConfigForTencentCloud struct { + SecretId string `json:"secretId"` + SecretKey string `json:"secretKey"` } -type KubernetesAccess struct { - KubeConfig string `json:"kubeConfig"` +type AccessConfigForVolcEngine struct { + AccessKeyId string `json:"accessKeyId"` + SecretAccessKey string `json:"secretAccessKey"` +} + +type AccessConfigForWebhook struct { + Url string `json:"url"` } diff --git a/internal/domain/acme_accounts.go b/internal/domain/acme_accounts.go index 05e25e42..b4f88dc4 100644 --- a/internal/domain/acme_accounts.go +++ b/internal/domain/acme_accounts.go @@ -1,17 +1,13 @@ package domain import ( - "time" - "github.com/go-acme/lego/v4/registration" ) type AcmeAccount struct { - Id string - Ca string - Email string - Resource *registration.Resource - Key string - Created time.Time - Updated time.Time + Meta + CA string `json:"ca" db:"ca"` + Email string `json:"email" db:"email"` + Resource *registration.Resource `json:"resource" db:"resource"` + Key string `json:"key" db:"key"` } diff --git a/internal/domain/certificate.go b/internal/domain/certificate.go index b5ee0e0e..2fe0c131 100644 --- a/internal/domain/certificate.go +++ b/internal/domain/certificate.go @@ -2,42 +2,25 @@ package domain import "time" -var ValidityDuration = time.Hour * 24 * 10 +type CertificateSourceType string + +const ( + CertificateSourceTypeWorkflow = CertificateSourceType("workflow") + CertificateSourceTypeUpload = CertificateSourceType("upload") +) type Certificate struct { Meta - SAN string `json:"san" db:"san"` - Certificate string `json:"certificate" db:"certificate"` - PrivateKey string `json:"privateKey" db:"privateKey"` - IssuerCertificate string `json:"issuerCertificate" db:"issuerCertificate"` - CertUrl string `json:"certUrl" db:"certUrl"` - CertStableUrl string `json:"certStableUrl" db:"certStableUrl"` - Output string `json:"output" db:"output"` - Workflow string `json:"workflow" db:"workflow"` - ExpireAt time.Time `json:"ExpireAt" db:"expireAt"` - NodeId string `json:"nodeId" db:"nodeId"` -} - -type MetaData struct { - Version string `json:"version"` - SerialNumber string `json:"serialNumber"` - Validity CertificateValidity `json:"validity"` - SignatureAlgorithm string `json:"signatureAlgorithm"` - Issuer CertificateIssuer `json:"issuer"` - Subject CertificateSubject `json:"subject"` -} - -type CertificateIssuer struct { - Country string `json:"country"` - Organization string `json:"organization"` - CommonName string `json:"commonName"` -} - -type CertificateSubject struct { - CN string `json:"CN"` -} - -type CertificateValidity struct { - NotBefore string `json:"notBefore"` - NotAfter string `json:"notAfter"` + Source CertificateSourceType `json:"source" db:"source"` + SubjectAltNames string `json:"subjectAltNames" db:"subjectAltNames"` + Certificate string `json:"certificate" db:"certificate"` + PrivateKey string `json:"privateKey" db:"privateKey"` + IssuerCertificate string `json:"issuerCertificate" db:"issuerCertificate"` + EffectAt time.Time `json:"effectAt" db:"effectAt"` + ExpireAt time.Time `json:"expireAt" db:"expireAt"` + ACMECertUrl string `json:"acmeCertUrl" db:"acmeCertUrl"` + ACMECertStableUrl string `json:"acmeCertStableUrl" db:"acmeCertStableUrl"` + WorkflowId string `json:"workflowId" db:"workflowId"` + WorkflowNodeId string `json:"workflowNodeId" db:"workflowNodeId"` + WorkflowOutputId string `json:"workflowOutputId" db:"workflowOutputId"` } diff --git a/internal/domain/common.go b/internal/domain/common.go deleted file mode 100644 index 8ff8f221..00000000 --- a/internal/domain/common.go +++ /dev/null @@ -1,9 +0,0 @@ -package domain - -import "time" - -type Meta struct { - Id string `json:"id" db:"id"` - Created time.Time `json:"created" db:"created"` - Updated time.Time `json:"updated" db:"updated"` -} diff --git a/internal/domain/domains.go b/internal/domain/domains.go deleted file mode 100644 index f3d04a53..00000000 --- a/internal/domain/domains.go +++ /dev/null @@ -1,144 +0,0 @@ -package domain - -import ( - "encoding/json" - "strings" - - "github.com/usual2970/certimate/internal/pkg/utils/maps" -) - -type ApplyConfig struct { - Email string `json:"email"` - Access string `json:"access"` - KeyAlgorithm string `json:"keyAlgorithm"` - Nameservers string `json:"nameservers"` - Timeout int64 `json:"timeout"` - DisableFollowCNAME bool `json:"disableFollowCNAME"` -} - -type DeployConfig struct { - Id string `json:"id"` - Access string `json:"access"` - Type string `json:"type"` - Config map[string]any `json:"config"` -} - -// Deprecated: 以字符串形式获取配置项。 -// -// 入参: -// - key: 配置项的键。 -// -// 出参: -// - 配置项的值。如果配置项不存在或者类型不是字符串,则返回空字符串。 -func (dc *DeployConfig) GetConfigAsString(key string) string { - return maps.GetValueAsString(dc.Config, key) -} - -// Deprecated: 以字符串形式获取配置项。 -// -// 入参: -// - key: 配置项的键。 -// - defaultValue: 默认值。 -// -// 出参: -// - 配置项的值。如果配置项不存在、类型不是字符串或者值为零值,则返回默认值。 -func (dc *DeployConfig) GetConfigOrDefaultAsString(key string, defaultValue string) string { - return maps.GetValueOrDefaultAsString(dc.Config, key, defaultValue) -} - -// Deprecated: 以 32 位整数形式获取配置项。 -// -// 入参: -// - key: 配置项的键。 -// -// 出参: -// - 配置项的值。如果配置项不存在或者类型不是 32 位整数,则返回 0。 -func (dc *DeployConfig) GetConfigAsInt32(key string) int32 { - return maps.GetValueAsInt32(dc.Config, key) -} - -// Deprecated: 以 32 位整数形式获取配置项。 -// -// 入参: -// - key: 配置项的键。 -// - defaultValue: 默认值。 -// -// 出参: -// - 配置项的值。如果配置项不存在、类型不是 32 位整数或者值为零值,则返回默认值。 -func (dc *DeployConfig) GetConfigOrDefaultAsInt32(key string, defaultValue int32) int32 { - return maps.GetValueOrDefaultAsInt32(dc.Config, key, defaultValue) -} - -// Deprecated: 以布尔形式获取配置项。 -// -// 入参: -// - key: 配置项的键。 -// -// 出参: -// - 配置项的值。如果配置项不存在或者类型不是布尔,则返回 false。 -func (dc *DeployConfig) GetConfigAsBool(key string) bool { - return maps.GetValueAsBool(dc.Config, key) -} - -// Deprecated: 以布尔形式获取配置项。 -// -// 入参: -// - key: 配置项的键。 -// - defaultValue: 默认值。 -// -// 出参: -// - 配置项的值。如果配置项不存在或者类型不是布尔,则返回默认值。 -func (dc *DeployConfig) GetConfigOrDefaultAsBool(key string, defaultValue bool) bool { - return maps.GetValueOrDefaultAsBool(dc.Config, key, defaultValue) -} - -// Deprecated: 以变量字典形式获取配置项。 -// -// 出参: -// - 变量字典。 -func (dc *DeployConfig) GetConfigAsVariables() map[string]string { - rs := make(map[string]string) - - if dc.Config != nil { - value, ok := dc.Config["variables"] - if !ok { - return rs - } - - kvs := make([]KV, 0) - bts, _ := json.Marshal(value) - if err := json.Unmarshal(bts, &kvs); err != nil { - return rs - } - - for _, kv := range kvs { - rs[kv.Key] = kv.Value - } - } - - return rs -} - -// Deprecated: GetDomain returns the domain from the deploy config, -// if the domain is a wildcard domain, and wildcard is true, return the wildcard domain -func (dc *DeployConfig) GetDomain(wildcard ...bool) string { - val := dc.GetConfigAsString("domain") - if val == "" { - return "" - } - - if !strings.HasPrefix(val, "*") { - return val - } - - if len(wildcard) > 0 && wildcard[0] { - return val - } - - return strings.TrimPrefix(val, "*") -} - -type KV struct { - Key string `json:"key"` - Value string `json:"value"` -} diff --git a/internal/domain/meta.go b/internal/domain/meta.go new file mode 100644 index 00000000..bbafb542 --- /dev/null +++ b/internal/domain/meta.go @@ -0,0 +1,9 @@ +package domain + +import "time" + +type Meta struct { + Id string `json:"id" db:"id"` + CreatedAt time.Time `json:"created" db:"created"` + UpdatedAt time.Time `json:"updated" db:"updated"` +} diff --git a/internal/domain/notify.go b/internal/domain/notify.go index e307600c..7db79be6 100644 --- a/internal/domain/notify.go +++ b/internal/domain/notify.go @@ -1,5 +1,7 @@ package domain +type NotifyChannelType string + /* 消息通知渠道常量值。 @@ -7,14 +9,14 @@ package domain NOTICE: If you add new constant, please keep ASCII order. */ const ( - NotifyChannelBark = "bark" - NotifyChannelDingtalk = "dingtalk" - NotifyChannelEmail = "email" - NotifyChannelLark = "lark" - NotifyChannelServerChan = "serverchan" - NotifyChannelTelegram = "telegram" - NotifyChannelWebhook = "webhook" - NotifyChannelWeCom = "wecom" + NotifyChannelTypeBark = NotifyChannelType("bark") + NotifyChannelTypeDingTalk = NotifyChannelType("dingtalk") + NotifyChannelTypeEmail = NotifyChannelType("email") + NotifyChannelTypeLark = NotifyChannelType("lark") + NotifyChannelTypeServerChan = NotifyChannelType("serverchan") + NotifyChannelTypeTelegram = NotifyChannelType("telegram") + NotifyChannelTypeWebhook = NotifyChannelType("webhook") + NotifyChannelTypeWeCom = NotifyChannelType("wecom") ) type NotifyTestPushReq struct { diff --git a/internal/domain/provider.go b/internal/domain/provider.go new file mode 100644 index 00000000..a196d2c3 --- /dev/null +++ b/internal/domain/provider.go @@ -0,0 +1,66 @@ +package domain + +type AccessProviderType string + +/* +提供商类型常量值。 + + 注意:如果追加新的常量值,请保持以 ASCII 排序。 + NOTICE: If you add new constant, please keep ASCII order. +*/ +const ( + AccessProviderTypeACMEHttpReq = AccessProviderType("acmehttpreq") + AccessProviderTypeAliyun = AccessProviderType("aliyun") + AccessProviderTypeAWS = AccessProviderType("aws") + AccessProviderTypeBaiduCloud = AccessProviderType("baiducloud") + AccessProviderTypeBytePlus = AccessProviderType("byteplus") + AccessProviderTypeCloudflare = AccessProviderType("cloudflare") + AccessProviderTypeDogeCloud = AccessProviderType("dogecloud") + AccessProviderTypeGoDaddy = AccessProviderType("godaddy") + AccessProviderTypeHuaweiCloud = AccessProviderType("huaweicloud") + AccessProviderTypeKubernetes = AccessProviderType("k8s") + AccessProviderTypeLocal = AccessProviderType("local") + AccessProviderTypeNameDotCom = AccessProviderType("namedotcom") + AccessProviderTypeNameSilo = AccessProviderType("namesilo") + AccessProviderTypePowerDNS = AccessProviderType("powerdns") + AccessProviderTypeQiniu = AccessProviderType("qiniu") + AccessProviderTypeSSH = AccessProviderType("ssh") + AccessProviderTypeTencentCloud = AccessProviderType("tencentcloud") + AccessProviderTypeVolcEngine = AccessProviderType("volcengine") + AccessProviderTypeWebhook = AccessProviderType("webhook") +) + +type DeployProviderType string + +/* +提供商部署目标常量值。 +短横线前的部分始终等于提供商类型。 + + 注意:如果追加新的常量值,请保持以 ASCII 排序。 + NOTICE: If you add new constant, please keep ASCII order. +*/ +const ( + DeployProviderTypeAliyunALB = DeployProviderType("aliyun-alb") + DeployProviderTypeAliyunCDN = DeployProviderType("aliyun-cdn") + DeployProviderTypeAliyunCLB = DeployProviderType("aliyun-clb") + DeployProviderTypeAliyunDCDN = DeployProviderType("aliyun-dcdn") + DeployProviderTypeAliyunNLB = DeployProviderType("aliyun-nlb") + DeployProviderTypeAliyunOSS = DeployProviderType("aliyun-oss") + DeployProviderTypeBaiduCloudCDN = DeployProviderType("baiducloud-cdn") + DeployProviderTypeBytePlusCDN = DeployProviderType("byteplus-cdn") + DeployProviderTypeDogeCloudCDN = DeployProviderType("dogecloud-cdn") + DeployProviderTypeHuaweiCloudCDN = DeployProviderType("huaweicloud-cdn") + DeployProviderTypeHuaweiCloudELB = DeployProviderType("huaweicloud-elb") + DeployProviderTypeK8sSecret = DeployProviderType("k8s-secret") + DeployProviderTypeLocal = DeployProviderType("local") + DeployProviderTypeQiniuCDN = DeployProviderType("qiniu-cdn") + DeployProviderTypeSSH = DeployProviderType("ssh") + DeployProviderTypeTencentCloudCDN = DeployProviderType("tencentcloud-cdn") + DeployProviderTypeTencentCloudCLB = DeployProviderType("tencentcloud-clb") + DeployProviderTypeTencentCloudCOS = DeployProviderType("tencentcloud-cos") + DeployProviderTypeTencentCloudECDN = DeployProviderType("tencentcloud-ecdn") + DeployProviderTypeTencentCloudEO = DeployProviderType("tencentcloud-eo") + DeployProviderTypeVolcEngineCDN = DeployProviderType("volcengine-cdn") + DeployProviderTypeVolcEngineLive = DeployProviderType("volcengine-live") + DeployProviderTypeWebhook = DeployProviderType("webhook") +) diff --git a/internal/domain/setting.go b/internal/domain/setting.go deleted file mode 100644 index da368566..00000000 --- a/internal/domain/setting.go +++ /dev/null @@ -1,45 +0,0 @@ -package domain - -import ( - "encoding/json" - "fmt" - "time" -) - -type Setting struct { - ID string `json:"id"` - Name string `json:"name"` - Content string `json:"content"` - Created time.Time `json:"created"` - Updated time.Time `json:"updated"` -} - -type ChannelsConfig map[string]map[string]any - -func (s *Setting) GetChannelContent(channel string) (map[string]any, error) { - conf := &ChannelsConfig{} - if err := json.Unmarshal([]byte(s.Content), conf); err != nil { - return nil, err - } - - v, ok := (*conf)[channel] - if !ok { - return nil, fmt.Errorf("channel \"%s\" not found", channel) - } - - return v, nil -} - -type NotifyTemplates struct { - NotifyTemplates []NotifyTemplate `json:"notifyTemplates"` -} - -type NotifyTemplate struct { - Title string `json:"title"` - Content string `json:"content"` -} - -type NotifyMessage struct { - Subject string - Message string -} diff --git a/internal/domain/settings.go b/internal/domain/settings.go new file mode 100644 index 00000000..8d1d983f --- /dev/null +++ b/internal/domain/settings.go @@ -0,0 +1,37 @@ +package domain + +import ( + "encoding/json" + "fmt" +) + +type Settings struct { + Meta + Name string `json:"name" db:"name"` + Content string `json:"content" db:"content"` +} + +type NotifyTemplatesSettingsContent struct { + NotifyTemplates []NotifyTemplate `json:"notifyTemplates"` +} + +type NotifyTemplate struct { + Subject string `json:"subject"` + Message string `json:"message"` +} + +type NotifyChannelsSettingsContent map[string]map[string]any + +func (s *Settings) GetNotifyChannelConfig(channel string) (map[string]any, error) { + conf := &NotifyChannelsSettingsContent{} + if err := json.Unmarshal([]byte(s.Content), conf); err != nil { + return nil, err + } + + v, ok := (*conf)[channel] + if !ok { + return nil, fmt.Errorf("channel \"%s\" not found", channel) + } + + return v, nil +} diff --git a/internal/domain/workflow.go b/internal/domain/workflow.go index 2190ba6d..2657b8a6 100644 --- a/internal/domain/workflow.go +++ b/internal/domain/workflow.go @@ -1,95 +1,101 @@ package domain import ( - "fmt" - "strconv" + "time" + + "github.com/usual2970/certimate/internal/pkg/utils/maps" ) -const ( - WorkflowNodeTypeStart = "start" - WorkflowNodeTypeEnd = "end" - WorkflowNodeTypeApply = "apply" - WorkflowNodeTypeDeploy = "deploy" - WorkflowNodeTypeNotify = "notify" - WorkflowNodeTypeBranch = "branch" - WorkflowNodeTypeCondition = "condition" -) +type WorkflowNodeType string const ( - WorkflowTypeAuto = "auto" - WorkflowTypeManual = "manual" + WorkflowNodeTypeStart = WorkflowNodeType("start") + WorkflowNodeTypeEnd = WorkflowNodeType("end") + WorkflowNodeTypeApply = WorkflowNodeType("apply") + WorkflowNodeTypeDeploy = WorkflowNodeType("deploy") + WorkflowNodeTypeNotify = WorkflowNodeType("notify") + WorkflowNodeTypeBranch = WorkflowNodeType("branch") + WorkflowNodeTypeCondition = WorkflowNodeType("condition") +) + +type WorkflowTriggerType string + +const ( + WorkflowTriggerTypeAuto = WorkflowTriggerType("auto") + WorkflowTriggerTypeManual = WorkflowTriggerType("manual") ) type Workflow struct { Meta - Name string `json:"name"` - Description string `json:"description"` - Type string `json:"type"` - Crontab string `json:"crontab"` - Content *WorkflowNode `json:"content"` - Draft *WorkflowNode `json:"draft"` - Enabled bool `json:"enabled"` - HasDraft bool `json:"hasDraft"` + Name string `json:"name" db:"name"` + Description string `json:"description" db:"description"` + Trigger WorkflowTriggerType `json:"trigger" db:"trigger"` + TriggerCron string `json:"triggerCron" db:"triggerCron"` + Enabled bool `json:"enabled" db:"enabled"` + Content *WorkflowNode `json:"content" db:"content"` + Draft *WorkflowNode `json:"draft" db:"draft"` + HasDraft bool `json:"hasDraft" db:"hasDraft"` + LastRunId string `json:"lastRunId" db:"lastRunId"` + LastRunStatus WorkflowRunStatusType `json:"lastRunStatus" db:"lastRunStatus"` + LastRunTime time.Time `json:"lastRunTime" db:"lastRunTime"` } type WorkflowNode struct { - Id string `json:"id"` - Name string `json:"name"` - Next *WorkflowNode `json:"next"` - Config map[string]any `json:"config"` - Input []WorkflowNodeIo `json:"input"` - Output []WorkflowNodeIo `json:"output"` + Id string `json:"id"` + Type WorkflowNodeType `json:"type"` + Name string `json:"name"` - Validated bool `json:"validated"` - Type string `json:"type"` + Config map[string]any `json:"config"` + Inputs []WorkflowNodeIO `json:"inputs"` + Outputs []WorkflowNodeIO `json:"outputs"` + Next *WorkflowNode `json:"next"` Branches []WorkflowNode `json:"branches"` + + Validated bool `json:"validated"` } func (n *WorkflowNode) GetConfigString(key string) string { - if v, ok := n.Config[key]; ok { - if s, ok := v.(string); ok { - return s - } - } - return "" + return maps.GetValueAsString(n.Config, key) } func (n *WorkflowNode) GetConfigBool(key string) bool { - if v, ok := n.Config[key]; ok { - if b, ok := v.(bool); ok { - return b - } - } - return false + return maps.GetValueAsBool(n.Config, key) +} + +func (n *WorkflowNode) GetConfigInt32(key string) int32 { + return maps.GetValueAsInt32(n.Config, key) } func (n *WorkflowNode) GetConfigInt64(key string) int64 { - // 先转成字符串,再转成 int64 - if v, ok := n.Config[key]; ok { - temp := fmt.Sprintf("%v", v) - if i, err := strconv.ParseInt(temp, 10, 64); err == nil { - return i + return maps.GetValueAsInt64(n.Config, key) +} + +func (n *WorkflowNode) GetConfigMap(key string) map[string]any { + if val, ok := n.Config[key]; ok { + if result, ok := val.(map[string]any); ok { + return result } } - return 0 + return make(map[string]any) } -type WorkflowNodeIo struct { +type WorkflowNodeIO struct { Label string `json:"label"` Name string `json:"name"` Type string `json:"type"` Required bool `json:"required"` Value any `json:"value"` - ValueSelector WorkflowNodeIoValueSelector `json:"valueSelector"` + ValueSelector WorkflowNodeIOValueSelector `json:"valueSelector"` } -type WorkflowNodeIoValueSelector struct { +type WorkflowNodeIOValueSelector struct { Id string `json:"id"` Name string `json:"name"` } type WorkflowRunReq struct { - Id string `json:"id"` + WorkflowId string `json:"workflowId"` + Trigger WorkflowTriggerType `json:"trigger"` } diff --git a/internal/domain/workflow_output.go b/internal/domain/workflow_output.go index 5ae09205..abbddac1 100644 --- a/internal/domain/workflow_output.go +++ b/internal/domain/workflow_output.go @@ -1,12 +1,12 @@ package domain -const WorkflowOutputCertificate = "certificate" - type WorkflowOutput struct { Meta - Workflow string `json:"workflow"` - NodeId string `json:"nodeId"` - Node *WorkflowNode `json:"node"` - Output []WorkflowNodeIo `json:"output"` - Succeed bool `json:"succeed"` + WorkflowId string `json:"workflowId" db:"workflow"` + NodeId string `json:"nodeId" db:"nodeId"` + Node *WorkflowNode `json:"node" db:"node"` + Outputs []WorkflowNodeIO `json:"outputs" db:"outputs"` + Succeeded bool `json:"succeeded" db:"succeeded"` } + +const WORKFLOW_OUTPUT_CERTIFICATE = "certificate" diff --git a/internal/domain/workflow_run.go b/internal/domain/workflow_run.go new file mode 100644 index 00000000..ef4fb643 --- /dev/null +++ b/internal/domain/workflow_run.go @@ -0,0 +1,49 @@ +package domain + +import "time" + +type WorkflowRunStatusType string + +const ( + WorkflowRunStatusTypePending WorkflowRunStatusType = "pending" + WorkflowRunStatusTypeRunning WorkflowRunStatusType = "running" + WorkflowRunStatusTypeSucceeded WorkflowRunStatusType = "succeeded" + WorkflowRunStatusTypeFailed WorkflowRunStatusType = "failed" +) + +type WorkflowRun struct { + Meta + WorkflowId string `json:"workflowId" db:"workflowId"` + Status WorkflowRunStatusType `json:"status" db:"status"` + Trigger WorkflowTriggerType `json:"trigger" db:"trigger"` + StartedAt time.Time `json:"startedAt" db:"startedAt"` + EndedAt time.Time `json:"endedAt" db:"endedAt"` + Logs []WorkflowRunLog `json:"logs" db:"logs"` + Error string `json:"error" db:"error"` +} + +type WorkflowRunLog struct { + NodeId string `json:"nodeId"` + NodeName string `json:"nodeName"` + Error string `json:"error"` + Outputs []WorkflowRunLogOutput `json:"outputs"` +} + +type WorkflowRunLogOutput struct { + Time string `json:"time"` + Title string `json:"title"` + Content string `json:"content"` + Error string `json:"error"` +} + +type WorkflowRunLogs []WorkflowRunLog + +func (r WorkflowRunLogs) FirstError() string { + for _, log := range r { + if log.Error != "" { + return log.Error + } + } + + return "" +} diff --git a/internal/domain/workflow_run_log.go b/internal/domain/workflow_run_log.go deleted file mode 100644 index 91a40963..00000000 --- a/internal/domain/workflow_run_log.go +++ /dev/null @@ -1,33 +0,0 @@ -package domain - -type RunLogOutput struct { - Time string `json:"time"` - Title string `json:"title"` - Content string `json:"content"` - Error string `json:"error"` -} - -type RunLog struct { - NodeName string `json:"nodeName"` - Error string `json:"error"` - Outputs []RunLogOutput `json:"outputs"` -} - -type WorkflowRunLog struct { - Meta - Workflow string `json:"workflow"` - Log []RunLog `json:"log"` - Succeed bool `json:"succeed"` - Error string `json:"error"` -} - -type RunLogs []RunLog - -func (r RunLogs) Error() string { - for _, log := range r { - if log.Error != "" { - return log.Error - } - } - return "" -} diff --git a/internal/domains/deploy.go b/internal/domains/deploy.go deleted file mode 100644 index d664ecf3..00000000 --- a/internal/domains/deploy.go +++ /dev/null @@ -1,213 +0,0 @@ -package domains - -import ( - "context" - "crypto/ecdsa" - "crypto/rsa" - "fmt" - "strings" - "time" - - "github.com/pocketbase/pocketbase/models" - - "golang.org/x/exp/slices" - - "github.com/usual2970/certimate/internal/applicant" - "github.com/usual2970/certimate/internal/deployer" - "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/utils/app" - - "github.com/usual2970/certimate/internal/pkg/utils/x509" -) - -type Phase string - -const ( - checkPhase Phase = "check" - applyPhase Phase = "apply" - deployPhase Phase = "deploy" -) - -const validityDuration = time.Hour * 24 * 10 - -func deploy(ctx context.Context, record *models.Record) error { - defer func() { - if r := recover(); r != nil { - app.GetApp().Logger().Error("部署失败", "err", r) - } - }() - var certificate *applicant.Certificate - - history := NewHistory(record) - defer history.commit() - - // ############1.检查域名配置 - history.record(checkPhase, "开始检查", nil) - - currRecord, err := app.GetApp().Dao().FindRecordById("domains", record.Id) - if err != nil { - app.GetApp().Logger().Error("获取记录失败", "err", err) - history.record(checkPhase, "获取域名配置失败", &RecordInfo{Err: err}) - return err - } - history.record(checkPhase, "获取记录成功", nil) - - cert := currRecord.GetString("certificate") - expiredAt := currRecord.GetDateTime("expiredAt").Time() - - // 检查证书是否包含设置的所有域名 - changed := isCertChanged(cert, currRecord) - - if cert != "" && time.Until(expiredAt) > validityDuration && currRecord.GetBool("deployed") && !changed { - app.GetApp().Logger().Info("证书在有效期内") - history.record(checkPhase, "证书在有效期内且已部署,跳过", &RecordInfo{ - Info: []string{fmt.Sprintf("证书有效期至 %s", expiredAt.Format("2006-01-02"))}, - }, true) - - // 跳过的情况也算成功 - history.setWholeSuccess(true) - return nil - } - history.record(checkPhase, "检查通过", nil, true) - - // ############2.申请证书 - history.record(applyPhase, "开始申请", nil) - - if cert != "" && time.Until(expiredAt) > validityDuration && !changed { - history.record(applyPhase, "证书在有效期内,跳过", &RecordInfo{ - Info: []string{fmt.Sprintf("证书有效期至 %s", expiredAt.Format("2006-01-02"))}, - }) - } else { - applicant, err := applicant.Get(currRecord) - if err != nil { - history.record(applyPhase, "获取applicant失败", &RecordInfo{Err: err}) - app.GetApp().Logger().Error("获取applicant失败", "err", err) - return err - } - certificate, err = applicant.Apply() - if err != nil { - history.record(applyPhase, "申请证书失败", &RecordInfo{Err: err}) - app.GetApp().Logger().Error("申请证书失败", "err", err) - return err - } - history.record(applyPhase, "申请证书成功", &RecordInfo{ - Info: []string{fmt.Sprintf("证书地址: %s", certificate.CertUrl)}, - }) - history.setCert(certificate) - } - - history.record(applyPhase, "保存证书成功", nil, true) - - // ############3.部署证书 - history.record(deployPhase, "开始部署", nil, false) - deployers, err := deployer.Gets(currRecord, certificate) - if err != nil { - history.record(deployPhase, "获取deployer失败", &RecordInfo{Err: err}) - app.GetApp().Logger().Error("获取deployer失败", "err", err) - return err - } - - // 没有部署配置,也算成功 - if len(deployers) == 0 { - history.record(deployPhase, "没有部署配置", &RecordInfo{Info: []string{"没有部署配置"}}) - history.setWholeSuccess(true) - return nil - } - - for _, deployer := range deployers { - if err = deployer.Deploy(ctx); err != nil { - - app.GetApp().Logger().Error("部署失败", "err", err) - history.record(deployPhase, "部署失败", &RecordInfo{Err: err, Info: deployer.GetInfos()}) - return err - } - history.record(deployPhase, fmt.Sprintf("[%s]-部署成功", deployer.GetID()), &RecordInfo{ - Info: deployer.GetInfos(), - }, false) - - } - - app.GetApp().Logger().Info("部署成功") - history.record(deployPhase, "部署成功", nil, true) - - history.setWholeSuccess(true) - - return nil -} - -func isCertChanged(certificate string, record *models.Record) bool { - // 如果证书为空,直接返回true - if certificate == "" { - return true - } - - // 解析证书 - cert, err := x509.ParseCertificateFromPEM(certificate) - if err != nil { - app.GetApp().Logger().Error("解析证书失败", "err", err) - return true - } - - // 遍历域名列表,检查是否都在证书中,找到第一个不存在证书中域名时提前返回true - for _, domain := range strings.Split(record.GetString("domain"), ";") { - if !slices.Contains(cert.DNSNames, domain) && !slices.Contains(cert.DNSNames, "*."+removeLastSubdomain(domain)) { - return true - } - } - - // 解析applyConfig - applyConfig := &domain.ApplyConfig{} - record.UnmarshalJSONField("applyConfig", applyConfig) - - // 检查证书加密算法是否变更 - switch pubkey := cert.PublicKey.(type) { - case *rsa.PublicKey: - bitSize := pubkey.N.BitLen() - switch bitSize { - case 2048: - // RSA2048 - if applyConfig.KeyAlgorithm != "" && applyConfig.KeyAlgorithm != "RSA2048" { - return true - } - case 3072: - // RSA3072 - if applyConfig.KeyAlgorithm != "RSA3072" { - return true - } - case 4096: - // RSA4096 - if applyConfig.KeyAlgorithm != "RSA4096" { - return true - } - case 8192: - // RSA8192 - if applyConfig.KeyAlgorithm != "RSA8192" { - return true - } - } - case *ecdsa.PublicKey: - bitSize := pubkey.Curve.Params().BitSize - switch bitSize { - case 256: - // EC256 - if applyConfig.KeyAlgorithm != "EC256" { - return true - } - case 384: - // EC384 - if applyConfig.KeyAlgorithm != "EC384" { - return true - } - } - } - - return false -} - -func removeLastSubdomain(domain string) string { - parts := strings.Split(domain, ".") - if len(parts) > 1 { - return strings.Join(parts[1:], ".") - } - return domain -} diff --git a/internal/domains/domains.go b/internal/domains/domains.go deleted file mode 100644 index dd65dff8..00000000 --- a/internal/domains/domains.go +++ /dev/null @@ -1,79 +0,0 @@ -package domains - -import ( - "context" - "fmt" - - "github.com/pocketbase/pocketbase/models" - - "github.com/usual2970/certimate/internal/utils/app" -) - -func create(ctx context.Context, record *models.Record) error { - if !record.GetBool("enabled") { - return nil - } - - if record.GetBool("rightnow") { - go func() { - if err := deploy(ctx, record); err != nil { - app.GetApp().Logger().Error("deploy failed", "err", err) - } - }() - } - - scheduler := app.GetScheduler() - - err := scheduler.Add(record.Id, record.GetString("crontab"), func() { - deploy(ctx, record) - }) - if err != nil { - app.GetApp().Logger().Error("add cron job failed", "err", err) - return fmt.Errorf("add cron job failed: %w", err) - } - app.GetApp().Logger().Error("add cron job failed", "domain", record.GetString("domain")) - - scheduler.Start() - return nil -} - -func update(ctx context.Context, record *models.Record) error { - scheduler := app.GetScheduler() - scheduler.Remove(record.Id) - if !record.GetBool("enabled") { - return nil - } - - if record.GetBool("rightnow") { - go func() { - if err := deploy(ctx, record); err != nil { - app.GetApp().Logger().Error("deploy failed", "err", err) - } - }() - } - - err := scheduler.Add(record.Id, record.GetString("crontab"), func() { - deploy(ctx, record) - }) - if err != nil { - app.GetApp().Logger().Error("update cron job failed", "err", err) - return fmt.Errorf("update cron job failed: %w", err) - } - app.GetApp().Logger().Info("update cron job success", "domain", record.GetString("domain")) - - scheduler.Start() - return nil -} - -func delete(_ context.Context, record *models.Record) error { - scheduler := app.GetScheduler() - - scheduler.Remove(record.Id) - scheduler.Start() - return nil -} - -func setRightnow(ctx context.Context, record *models.Record, ok bool) error { - record.Set("rightnow", ok) - return app.GetApp().Dao().SaveRecord(record) -} diff --git a/internal/domains/event.go b/internal/domains/event.go deleted file mode 100644 index 7acb31e9..00000000 --- a/internal/domains/event.go +++ /dev/null @@ -1,27 +0,0 @@ -package domains - -import ( - "github.com/pocketbase/pocketbase/core" - - "github.com/usual2970/certimate/internal/utils/app" -) - -const tableName = "domains" - -func AddEvent() error { - app := app.GetApp() - - app.OnRecordAfterCreateRequest(tableName).Add(func(e *core.RecordCreateEvent) error { - return create(e.HttpContext.Request().Context(), e.Record) - }) - - app.OnRecordAfterUpdateRequest(tableName).Add(func(e *core.RecordUpdateEvent) error { - return update(e.HttpContext.Request().Context(), e.Record) - }) - - app.OnRecordAfterDeleteRequest(tableName).Add(func(e *core.RecordDeleteEvent) error { - return delete(e.HttpContext.Request().Context(), e.Record) - }) - - return nil -} diff --git a/internal/domains/history.go b/internal/domains/history.go deleted file mode 100644 index 47ed5afa..00000000 --- a/internal/domains/history.go +++ /dev/null @@ -1,122 +0,0 @@ -package domains - -import ( - "time" - - "github.com/pocketbase/pocketbase/models" - - "github.com/usual2970/certimate/internal/applicant" - "github.com/usual2970/certimate/internal/utils/app" - "github.com/usual2970/certimate/internal/utils/xtime" -) - -type historyItem struct { - Time string `json:"time"` - Message string `json:"message"` - Error string `json:"error"` - Info []string `json:"info"` -} - -type RecordInfo struct { - Err error `json:"err"` - Info []string `json:"info"` -} - -type history struct { - Domain string `json:"domain"` - Log map[Phase][]historyItem `json:"log"` - Phase Phase `json:"phase"` - PhaseSuccess bool `json:"phaseSuccess"` - DeployedAt string `json:"deployedAt"` - Cert *applicant.Certificate `json:"cert"` - WholeSuccess bool `json:"wholeSuccess"` -} - -func NewHistory(record *models.Record) *history { - return &history{ - Domain: record.Id, - DeployedAt: time.Now().UTC().Format("2006-01-02T15:04:05Z"), - Log: make(map[Phase][]historyItem), - Phase: checkPhase, - PhaseSuccess: false, - } -} - -func (a *history) record(phase Phase, msg string, info *RecordInfo, pass ...bool) { - if info == nil { - info = &RecordInfo{} - } - a.Phase = phase - if len(pass) > 0 { - a.PhaseSuccess = pass[0] - } - - errMsg := "" - if info.Err != nil { - errMsg = info.Err.Error() - a.PhaseSuccess = false - } - - a.Log[phase] = append(a.Log[phase], historyItem{ - Message: msg, - Error: errMsg, - Info: info.Info, - Time: xtime.BeijingTimeStr(), - }) -} - -func (a *history) setCert(cert *applicant.Certificate) { - a.Cert = cert -} - -func (a *history) setWholeSuccess(success bool) { - a.WholeSuccess = success -} - -func (a *history) commit() error { - collection, err := app.GetApp().Dao().FindCollectionByNameOrId("deployments") - if err != nil { - return err - } - - record := models.NewRecord(collection) - - record.Set("domain", a.Domain) - record.Set("deployedAt", a.DeployedAt) - record.Set("log", a.Log) - record.Set("phase", string(a.Phase)) - record.Set("phaseSuccess", a.PhaseSuccess) - record.Set("wholeSuccess", a.WholeSuccess) - - if err := app.GetApp().Dao().SaveRecord(record); err != nil { - return err - } - - domainRecord, err := app.GetApp().Dao().FindRecordById("domains", a.Domain) - if err != nil { - return err - } - - domainRecord.Set("lastDeployedAt", a.DeployedAt) - domainRecord.Set("lastDeployment", record.Id) - domainRecord.Set("rightnow", false) - if a.Phase == deployPhase && a.PhaseSuccess { - domainRecord.Set("deployed", true) - } - cert := a.Cert - if cert != nil { - domainRecord.Set("certUrl", cert.CertUrl) - domainRecord.Set("certStableUrl", cert.CertStableUrl) - domainRecord.Set("privateKey", cert.PrivateKey) - domainRecord.Set("certificate", cert.Certificate) - domainRecord.Set("issuerCertificate", cert.IssuerCertificate) - domainRecord.Set("csr", cert.Csr) - domainRecord.Set("expiredAt", time.Now().Add(time.Hour*24*90)) - } - - if err := app.GetApp().Dao().SaveRecord(domainRecord); err != nil { - return err - } - - return nil -} diff --git a/internal/notify/notify.go b/internal/notify/notify.go index 6b218a18..f509630c 100644 --- a/internal/notify/notify.go +++ b/internal/notify/notify.go @@ -2,13 +2,15 @@ package notify import ( "context" + "encoding/json" "fmt" "golang.org/x/sync/errgroup" + "github.com/usual2970/certimate/internal/domain" "github.com/usual2970/certimate/internal/pkg/core/notifier" "github.com/usual2970/certimate/internal/pkg/utils/maps" - "github.com/usual2970/certimate/internal/utils/app" + "github.com/usual2970/certimate/internal/repository" ) func SendToAllChannels(subject, message string) error { @@ -37,7 +39,7 @@ func SendToAllChannels(subject, message string) error { } func SendToChannel(subject, message string, channel string, channelConfig map[string]any) error { - notifier, err := createNotifier(channel, channelConfig) + notifier, err := createNotifier(domain.NotifyChannelType(channel), channelConfig) if err != nil { return err } @@ -47,13 +49,14 @@ func SendToChannel(subject, message string, channel string, channelConfig map[st } func getEnabledNotifiers() ([]notifier.Notifier, error) { - settings, err := app.GetApp().Dao().FindFirstRecordByFilter("settings", "name='notifyChannels'") + settingsRepo := repository.NewSettingsRepository() + settings, err := settingsRepo.GetByName(context.Background(), "notifyChannels") if err != nil { return nil, fmt.Errorf("find notifyChannels error: %w", err) } rs := make(map[string]map[string]any) - if err := settings.UnmarshalJSONField("content", &rs); err != nil { + if err := json.Unmarshal([]byte(settings.Content), &rs); err != nil { return nil, fmt.Errorf("unmarshal notifyChannels error: %w", err) } @@ -63,7 +66,7 @@ func getEnabledNotifiers() ([]notifier.Notifier, error) { continue } - notifier, err := createNotifier(k, v) + notifier, err := createNotifier(domain.NotifyChannelType(k), v) if err != nil { continue } diff --git a/internal/notify/factory.go b/internal/notify/providers.go similarity index 87% rename from internal/notify/factory.go rename to internal/notify/providers.go index b77c7c91..6483a7a0 100644 --- a/internal/notify/factory.go +++ b/internal/notify/providers.go @@ -16,25 +16,25 @@ import ( "github.com/usual2970/certimate/internal/pkg/utils/maps" ) -func createNotifier(channel string, channelConfig map[string]any) (notifier.Notifier, error) { +func createNotifier(channel domain.NotifyChannelType, channelConfig map[string]any) (notifier.Notifier, error) { /* 注意:如果追加新的常量值,请保持以 ASCII 排序。 NOTICE: If you add new constant, please keep ASCII order. */ switch channel { - case domain.NotifyChannelBark: + case domain.NotifyChannelTypeBark: return providerBark.New(&providerBark.BarkNotifierConfig{ DeviceKey: maps.GetValueAsString(channelConfig, "deviceKey"), ServerUrl: maps.GetValueAsString(channelConfig, "serverUrl"), }) - case domain.NotifyChannelDingtalk: + case domain.NotifyChannelTypeDingTalk: return providerDingTalk.New(&providerDingTalk.DingTalkNotifierConfig{ AccessToken: maps.GetValueAsString(channelConfig, "accessToken"), Secret: maps.GetValueAsString(channelConfig, "secret"), }) - case domain.NotifyChannelEmail: + case domain.NotifyChannelTypeEmail: return providerEmail.New(&providerEmail.EmailNotifierConfig{ SmtpHost: maps.GetValueAsString(channelConfig, "smtpHost"), SmtpPort: maps.GetValueAsInt32(channelConfig, "smtpPort"), @@ -45,28 +45,28 @@ func createNotifier(channel string, channelConfig map[string]any) (notifier.Noti ReceiverAddress: maps.GetValueAsString(channelConfig, "receiverAddress"), }) - case domain.NotifyChannelLark: + case domain.NotifyChannelTypeLark: return providerLark.New(&providerLark.LarkNotifierConfig{ WebhookUrl: maps.GetValueAsString(channelConfig, "webhookUrl"), }) - case domain.NotifyChannelServerChan: + case domain.NotifyChannelTypeServerChan: return providerServerChan.New(&providerServerChan.ServerChanNotifierConfig{ Url: maps.GetValueAsString(channelConfig, "url"), }) - case domain.NotifyChannelTelegram: + case domain.NotifyChannelTypeTelegram: return providerTelegram.New(&providerTelegram.TelegramNotifierConfig{ ApiToken: maps.GetValueAsString(channelConfig, "apiToken"), ChatId: maps.GetValueAsInt64(channelConfig, "chatId"), }) - case domain.NotifyChannelWebhook: + case domain.NotifyChannelTypeWebhook: return providerWebhook.New(&providerWebhook.WebhookNotifierConfig{ Url: maps.GetValueAsString(channelConfig, "url"), }) - case domain.NotifyChannelWeCom: + case domain.NotifyChannelTypeWeCom: return providerWeCom.New(&providerWeCom.WeComNotifierConfig{ WebhookUrl: maps.GetValueAsString(channelConfig, "webhookUrl"), }) diff --git a/internal/notify/service.go b/internal/notify/service.go index 76162ff1..8c99d824 100644 --- a/internal/notify/service.go +++ b/internal/notify/service.go @@ -12,15 +12,15 @@ const ( notifyTestBody = "欢迎使用 Certimate ,这是一条测试通知。" ) -type SettingRepository interface { - GetByName(ctx context.Context, name string) (*domain.Setting, error) +type SettingsRepository interface { + GetByName(ctx context.Context, name string) (*domain.Settings, error) } type NotifyService struct { - settingRepo SettingRepository + settingRepo SettingsRepository } -func NewNotifyService(settingRepo SettingRepository) *NotifyService { +func NewNotifyService(settingRepo SettingsRepository) *NotifyService { return &NotifyService{ settingRepo: settingRepo, } @@ -32,7 +32,7 @@ func (n *NotifyService) Test(ctx context.Context, req *domain.NotifyTestPushReq) return fmt.Errorf("failed to get notify channels settings: %w", err) } - channelConfig, err := setting.GetChannelContent(req.Channel) + channelConfig, err := setting.GetNotifyChannelConfig(req.Channel) if err != nil { return fmt.Errorf("failed to get notify channel \"%s\" config: %w", req.Channel, err) } diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/acmehttpreq/acmehttpreq.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/acmehttpreq/acmehttpreq.go new file mode 100644 index 00000000..4242809f --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/acmehttpreq/acmehttpreq.go @@ -0,0 +1,41 @@ +package acmehttpreq + +import ( + "errors" + "net/url" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/httpreq" +) + +type ACMEHttpReqApplicantConfig struct { + Endpoint string `json:"endpoint"` + Mode string `json:"mode"` + Username string `json:"username"` + Password string `json:"password"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *ACMEHttpReqApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + endpoint, _ := url.Parse(config.Endpoint) + providerConfig := httpreq.NewDefaultConfig() + providerConfig.Endpoint = endpoint + providerConfig.Mode = config.Mode + providerConfig.Username = config.Username + providerConfig.Password = config.Password + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := httpreq.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/aliyun/aliyun.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/aliyun/aliyun.go new file mode 100644 index 00000000..687cc0ff --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/aliyun/aliyun.go @@ -0,0 +1,35 @@ +package aliyun + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/alidns" +) + +type AliyunApplicantConfig struct { + AccessKeyId string `json:"accessKeyId"` + AccessKeySecret string `json:"accessKeySecret"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *AliyunApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := alidns.NewDefaultConfig() + providerConfig.APIKey = config.AccessKeyId + providerConfig.SecretKey = config.AccessKeySecret + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := alidns.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/aws/aws.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/aws/aws.go new file mode 100644 index 00000000..1a207eee --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/aws/aws.go @@ -0,0 +1,39 @@ +package aws + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/route53" +) + +type AWSApplicantConfig struct { + AccessKeyId string `json:"accessKeyId"` + SecretAccessKey string `json:"secretAccessKey"` + Region string `json:"region"` + HostedZoneId string `json:"hostedZoneId"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *AWSApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := route53.NewDefaultConfig() + providerConfig.AccessKeyID = config.AccessKeyId + providerConfig.SecretAccessKey = config.SecretAccessKey + providerConfig.Region = config.Region + providerConfig.HostedZoneID = config.HostedZoneId + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := route53.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare/cloudflare.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare/cloudflare.go new file mode 100644 index 00000000..0f1abc40 --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare/cloudflare.go @@ -0,0 +1,33 @@ +package cloudflare + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/cloudflare" +) + +type CloudflareApplicantConfig struct { + DnsApiToken string `json:"dnsApiToken"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *CloudflareApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := cloudflare.NewDefaultConfig() + providerConfig.AuthToken = config.DnsApiToken + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := cloudflare.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy/godaddy.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy/godaddy.go new file mode 100644 index 00000000..1a85a28d --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy/godaddy.go @@ -0,0 +1,35 @@ +package godaddy + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/godaddy" +) + +type GoDaddyApplicantConfig struct { + ApiKey string `json:"apiKey"` + ApiSecret string `json:"apiSecret"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *GoDaddyApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := godaddy.NewDefaultConfig() + providerConfig.APIKey = config.ApiKey + providerConfig.APISecret = config.ApiSecret + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := godaddy.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud/huaweicloud.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud/huaweicloud.go new file mode 100644 index 00000000..a271f99c --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud/huaweicloud.go @@ -0,0 +1,43 @@ +package huaweicloud + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + hwc "github.com/go-acme/lego/v4/providers/dns/huaweicloud" +) + +type HuaweiCloudApplicantConfig struct { + AccessKeyId string `json:"accessKeyId"` + SecretAccessKey string `json:"secretAccessKey"` + Region string `json:"region"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *HuaweiCloudApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + region := config.Region + if region == "" { + // 华为云的 SDK 要求必须传一个区域,实际上 DNS-01 流程里用不到,但不传会报错 + region = "cn-north-1" + } + + providerConfig := hwc.NewDefaultConfig() + providerConfig.AccessKeyID = config.AccessKeyId + providerConfig.SecretAccessKey = config.SecretAccessKey + providerConfig.Region = region + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := hwc.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom/namedotcom.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom/namedotcom.go new file mode 100644 index 00000000..b5c8d3cb --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom/namedotcom.go @@ -0,0 +1,35 @@ +package namedotcom + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/namedotcom" +) + +type NameDotComApplicantConfig struct { + Username string `json:"username"` + ApiToken string `json:"apiToken"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *NameDotComApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := namedotcom.NewDefaultConfig() + providerConfig.Username = config.Username + providerConfig.APIToken = config.ApiToken + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := namedotcom.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo/namesilo.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo/namesilo.go new file mode 100644 index 00000000..f62201d6 --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo/namesilo.go @@ -0,0 +1,33 @@ +package namesilo + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/namesilo" +) + +type NameSiloApplicantConfig struct { + ApiKey string `json:"apiKey"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *NameSiloApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := namesilo.NewDefaultConfig() + providerConfig.APIKey = config.ApiKey + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := namesilo.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns/powerdns.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns/powerdns.go new file mode 100644 index 00000000..b6512389 --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns/powerdns.go @@ -0,0 +1,37 @@ +package namesilo + +import ( + "errors" + "net/url" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/pdns" +) + +type PowerDNSApplicantConfig struct { + ApiUrl string `json:"apiUrl"` + ApiKey string `json:"apiKey"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *PowerDNSApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + host, _ := url.Parse(config.ApiUrl) + providerConfig := pdns.NewDefaultConfig() + providerConfig.Host = host + providerConfig.APIKey = config.ApiKey + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := pdns.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud/tencentcloud.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud/tencentcloud.go new file mode 100644 index 00000000..bd335fc4 --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud/tencentcloud.go @@ -0,0 +1,35 @@ +package tencentcloud + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/tencentcloud" +) + +type TencentCloudApplicantConfig struct { + SecretId string `json:"secretId"` + SecretKey string `json:"secretKey"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *TencentCloudApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := tencentcloud.NewDefaultConfig() + providerConfig.SecretID = config.SecretId + providerConfig.SecretKey = config.SecretKey + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := tencentcloud.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine/volcengine.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine/volcengine.go new file mode 100644 index 00000000..0c9ad3c5 --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine/volcengine.go @@ -0,0 +1,35 @@ +package volcengine + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/volcengine" +) + +type VolcEngineApplicantConfig struct { + AccessKeyId string `json:"accessKeyId"` + SecretAccessKey string `json:"secretAccessKey"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *VolcEngineApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := volcengine.NewDefaultConfig() + providerConfig.AccessKey = config.AccessKeyId + providerConfig.SecretKey = config.SecretAccessKey + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := volcengine.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/deployer/deployer.go b/internal/pkg/core/deployer/deployer.go index b7b839fe..78d7c7de 100644 --- a/internal/pkg/core/deployer/deployer.go +++ b/internal/pkg/core/deployer/deployer.go @@ -20,5 +20,5 @@ type Deployer interface { // 表示证书部署结果的数据结构。 type DeployResult struct { - DeploymentData map[string]any `json:"deploymentData,omitempty"` + ExtendedData map[string]any `json:"extendedData,omitempty"` } diff --git a/internal/pkg/core/deployer/providers/aliyun-alb/aliyun_alb.go b/internal/pkg/core/deployer/providers/aliyun-alb/aliyun_alb.go index cdef4ee8..a92b4d33 100644 --- a/internal/pkg/core/deployer/providers/aliyun-alb/aliyun_alb.go +++ b/internal/pkg/core/deployer/providers/aliyun-alb/aliyun_alb.go @@ -12,6 +12,7 @@ import ( xerrors "github.com/pkg/errors" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/uploader" providerCas "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas" ) @@ -35,7 +36,7 @@ type AliyunALBDeployerConfig struct { type AliyunALBDeployer struct { config *AliyunALBDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClient *aliyunAlb.Client sslUploader uploader.Uploader } @@ -43,10 +44,10 @@ type AliyunALBDeployer struct { var _ deployer.Deployer = (*AliyunALBDeployer)(nil) func New(config *AliyunALBDeployerConfig) (*AliyunALBDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *AliyunALBDeployerConfig, logger deployer.Logger) (*AliyunALBDeployer, error) { +func NewWithLogger(config *AliyunALBDeployerConfig, logger logger.Logger) (*AliyunALBDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/aliyun-cdn/aliyun_cdn.go b/internal/pkg/core/deployer/providers/aliyun-cdn/aliyun_cdn.go index 85005e8c..d2de5684 100644 --- a/internal/pkg/core/deployer/providers/aliyun-cdn/aliyun_cdn.go +++ b/internal/pkg/core/deployer/providers/aliyun-cdn/aliyun_cdn.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "strings" "time" aliyunCdn "github.com/alibabacloud-go/cdn-20180510/v5/client" @@ -12,6 +13,7 @@ import ( xerrors "github.com/pkg/errors" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" ) type AliyunCDNDeployerConfig struct { @@ -19,23 +21,23 @@ type AliyunCDNDeployerConfig struct { AccessKeyId string `json:"accessKeyId"` // 阿里云 AccessKeySecret。 AccessKeySecret string `json:"accessKeySecret"` - // 加速域名(不支持泛域名)。 + // 加速域名(支持泛域名)。 Domain string `json:"domain"` } type AliyunCDNDeployer struct { config *AliyunCDNDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClient *aliyunCdn.Client } var _ deployer.Deployer = (*AliyunCDNDeployer)(nil) func New(config *AliyunCDNDeployerConfig) (*AliyunCDNDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *AliyunCDNDeployerConfig, logger deployer.Logger) (*AliyunCDNDeployer, error) { +func NewWithLogger(config *AliyunCDNDeployerConfig, logger logger.Logger) (*AliyunCDNDeployer, error) { if config == nil { return nil, errors.New("config is nil") } @@ -57,10 +59,13 @@ func NewWithLogger(config *AliyunCDNDeployerConfig, logger deployer.Logger) (*Al } func (d *AliyunCDNDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { + // "*.example.com" → ".example.com",适配阿里云 CDN 要求的泛域名格式 + domain := strings.TrimPrefix(d.config.Domain, "*") + // 设置 CDN 域名域名证书 // REF: https://help.aliyun.com/zh/cdn/developer-reference/api-cdn-2018-05-10-setcdndomainsslcertificate setCdnDomainSSLCertificateReq := &aliyunCdn.SetCdnDomainSSLCertificateRequest{ - DomainName: tea.String(d.config.Domain), + DomainName: tea.String(domain), CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())), CertType: tea.String("upload"), SSLProtocol: tea.String("on"), diff --git a/internal/pkg/core/deployer/providers/aliyun-clb/aliyun_clb.go b/internal/pkg/core/deployer/providers/aliyun-clb/aliyun_clb.go index 380c8581..86f6dfd9 100644 --- a/internal/pkg/core/deployer/providers/aliyun-clb/aliyun_clb.go +++ b/internal/pkg/core/deployer/providers/aliyun-clb/aliyun_clb.go @@ -11,6 +11,7 @@ import ( xerrors "github.com/pkg/errors" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/uploader" providerSlb "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-slb" ) @@ -34,7 +35,7 @@ type AliyunCLBDeployerConfig struct { type AliyunCLBDeployer struct { config *AliyunCLBDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClient *aliyunSlb.Client sslUploader uploader.Uploader } @@ -42,10 +43,10 @@ type AliyunCLBDeployer struct { var _ deployer.Deployer = (*AliyunCLBDeployer)(nil) func New(config *AliyunCLBDeployerConfig) (*AliyunCLBDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *AliyunCLBDeployerConfig, logger deployer.Logger) (*AliyunCLBDeployer, error) { +func NewWithLogger(config *AliyunCLBDeployerConfig, logger logger.Logger) (*AliyunCLBDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/aliyun-dcdn/aliyun_dcdn.go b/internal/pkg/core/deployer/providers/aliyun-dcdn/aliyun_dcdn.go index 41f21362..65c9a375 100644 --- a/internal/pkg/core/deployer/providers/aliyun-dcdn/aliyun_dcdn.go +++ b/internal/pkg/core/deployer/providers/aliyun-dcdn/aliyun_dcdn.go @@ -13,6 +13,7 @@ import ( xerrors "github.com/pkg/errors" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" ) type AliyunDCDNDeployerConfig struct { @@ -26,17 +27,17 @@ type AliyunDCDNDeployerConfig struct { type AliyunDCDNDeployer struct { config *AliyunDCDNDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClient *aliyunDcdn.Client } var _ deployer.Deployer = (*AliyunDCDNDeployer)(nil) func New(config *AliyunDCDNDeployerConfig) (*AliyunDCDNDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *AliyunDCDNDeployerConfig, logger deployer.Logger) (*AliyunDCDNDeployer, error) { +func NewWithLogger(config *AliyunDCDNDeployerConfig, logger logger.Logger) (*AliyunDCDNDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/aliyun-nlb/aliyun_nlb.go b/internal/pkg/core/deployer/providers/aliyun-nlb/aliyun_nlb.go index 93ef6bf1..c5558b2c 100644 --- a/internal/pkg/core/deployer/providers/aliyun-nlb/aliyun_nlb.go +++ b/internal/pkg/core/deployer/providers/aliyun-nlb/aliyun_nlb.go @@ -12,6 +12,7 @@ import ( xerrors "github.com/pkg/errors" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/uploader" providerCas "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas" ) @@ -35,7 +36,7 @@ type AliyunNLBDeployerConfig struct { type AliyunNLBDeployer struct { config *AliyunNLBDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClient *aliyunNlb.Client sslUploader uploader.Uploader } @@ -43,10 +44,10 @@ type AliyunNLBDeployer struct { var _ deployer.Deployer = (*AliyunNLBDeployer)(nil) func New(config *AliyunNLBDeployerConfig) (*AliyunNLBDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *AliyunNLBDeployerConfig, logger deployer.Logger) (*AliyunNLBDeployer, error) { +func NewWithLogger(config *AliyunNLBDeployerConfig, logger logger.Logger) (*AliyunNLBDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/aliyun-oss/aliyun_oss.go b/internal/pkg/core/deployer/providers/aliyun-oss/aliyun_oss.go index 656c9e10..9caf0a3b 100644 --- a/internal/pkg/core/deployer/providers/aliyun-oss/aliyun_oss.go +++ b/internal/pkg/core/deployer/providers/aliyun-oss/aliyun_oss.go @@ -9,6 +9,7 @@ import ( xerrors "github.com/pkg/errors" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" ) type AliyunOSSDeployerConfig struct { @@ -26,17 +27,17 @@ type AliyunOSSDeployerConfig struct { type AliyunOSSDeployer struct { config *AliyunOSSDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClient *oss.Client } var _ deployer.Deployer = (*AliyunOSSDeployer)(nil) func New(config *AliyunOSSDeployerConfig) (*AliyunOSSDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *AliyunOSSDeployerConfig, logger deployer.Logger) (*AliyunOSSDeployer, error) { +func NewWithLogger(config *AliyunOSSDeployerConfig, logger logger.Logger) (*AliyunOSSDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/baiducloud-cdn/baiducloud_cdn.go b/internal/pkg/core/deployer/providers/baiducloud-cdn/baiducloud_cdn.go index 28d6bed5..ab932b42 100644 --- a/internal/pkg/core/deployer/providers/baiducloud-cdn/baiducloud_cdn.go +++ b/internal/pkg/core/deployer/providers/baiducloud-cdn/baiducloud_cdn.go @@ -11,6 +11,7 @@ import ( xerrors "github.com/pkg/errors" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" ) type BaiduCloudCDNDeployerConfig struct { @@ -18,23 +19,23 @@ type BaiduCloudCDNDeployerConfig struct { AccessKeyId string `json:"accessKeyId"` // 百度智能云 SecretAccessKey。 SecretAccessKey string `json:"secretAccessKey"` - // 加速域名(不支持泛域名)。 + // 加速域名(支持泛域名)。 Domain string `json:"domain"` } type BaiduCloudCDNDeployer struct { config *BaiduCloudCDNDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClient *bceCdn.Client } var _ deployer.Deployer = (*BaiduCloudCDNDeployer)(nil) func New(config *BaiduCloudCDNDeployerConfig) (*BaiduCloudCDNDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *BaiduCloudCDNDeployerConfig, logger deployer.Logger) (*BaiduCloudCDNDeployer, error) { +func NewWithLogger(config *BaiduCloudCDNDeployerConfig, logger logger.Logger) (*BaiduCloudCDNDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/byteplus-cdn/byteplus_cdn.go b/internal/pkg/core/deployer/providers/byteplus-cdn/byteplus_cdn.go index 27650e05..9497bb6a 100644 --- a/internal/pkg/core/deployer/providers/byteplus-cdn/byteplus_cdn.go +++ b/internal/pkg/core/deployer/providers/byteplus-cdn/byteplus_cdn.go @@ -10,6 +10,7 @@ import ( xerrors "github.com/pkg/errors" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/uploader" providerCdn "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/byteplus-cdn" ) @@ -25,7 +26,7 @@ type BytePlusCDNDeployerConfig struct { type BytePlusCDNDeployer struct { config *BytePlusCDNDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClient *bpCdn.CDN sslUploader uploader.Uploader } @@ -33,10 +34,10 @@ type BytePlusCDNDeployer struct { var _ deployer.Deployer = (*BytePlusCDNDeployer)(nil) func New(config *BytePlusCDNDeployerConfig) (*BytePlusCDNDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *BytePlusCDNDeployerConfig, logger deployer.Logger) (*BytePlusCDNDeployer, error) { +func NewWithLogger(config *BytePlusCDNDeployerConfig, logger logger.Logger) (*BytePlusCDNDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/dogecloud-cdn/dogecloud_cdn.go b/internal/pkg/core/deployer/providers/dogecloud-cdn/dogecloud_cdn.go index 20ef5904..4d9f4ac4 100644 --- a/internal/pkg/core/deployer/providers/dogecloud-cdn/dogecloud_cdn.go +++ b/internal/pkg/core/deployer/providers/dogecloud-cdn/dogecloud_cdn.go @@ -8,6 +8,7 @@ import ( xerrors "github.com/pkg/errors" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/uploader" providerDoge "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/dogecloud" dogesdk "github.com/usual2970/certimate/internal/pkg/vendors/dogecloud-sdk" @@ -24,7 +25,7 @@ type DogeCloudCDNDeployerConfig struct { type DogeCloudCDNDeployer struct { config *DogeCloudCDNDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClient *dogesdk.Client sslUploader uploader.Uploader } @@ -32,10 +33,10 @@ type DogeCloudCDNDeployer struct { var _ deployer.Deployer = (*DogeCloudCDNDeployer)(nil) func New(config *DogeCloudCDNDeployerConfig) (*DogeCloudCDNDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *DogeCloudCDNDeployerConfig, logger deployer.Logger) (*DogeCloudCDNDeployer, error) { +func NewWithLogger(config *DogeCloudCDNDeployerConfig, logger logger.Logger) (*DogeCloudCDNDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/huaweicloud-cdn/huaweicloud_cdn.go b/internal/pkg/core/deployer/providers/huaweicloud-cdn/huaweicloud_cdn.go index b305156b..1dba8085 100644 --- a/internal/pkg/core/deployer/providers/huaweicloud-cdn/huaweicloud_cdn.go +++ b/internal/pkg/core/deployer/providers/huaweicloud-cdn/huaweicloud_cdn.go @@ -11,6 +11,7 @@ import ( xerrors "github.com/pkg/errors" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/uploader" providerScm "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/huaweicloud-scm" "github.com/usual2970/certimate/internal/pkg/utils/cast" @@ -30,7 +31,7 @@ type HuaweiCloudCDNDeployerConfig struct { type HuaweiCloudCDNDeployer struct { config *HuaweiCloudCDNDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClient *huaweicloudsdk.Client sslUploader uploader.Uploader } @@ -38,10 +39,10 @@ type HuaweiCloudCDNDeployer struct { var _ deployer.Deployer = (*HuaweiCloudCDNDeployer)(nil) func New(config *HuaweiCloudCDNDeployerConfig) (*HuaweiCloudCDNDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *HuaweiCloudCDNDeployerConfig, logger deployer.Logger) (*HuaweiCloudCDNDeployer, error) { +func NewWithLogger(config *HuaweiCloudCDNDeployerConfig, logger logger.Logger) (*HuaweiCloudCDNDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/huaweicloud-elb/huaweicloud_elb.go b/internal/pkg/core/deployer/providers/huaweicloud-elb/huaweicloud_elb.go index d3c142f0..010bdd2b 100644 --- a/internal/pkg/core/deployer/providers/huaweicloud-elb/huaweicloud_elb.go +++ b/internal/pkg/core/deployer/providers/huaweicloud-elb/huaweicloud_elb.go @@ -17,6 +17,7 @@ import ( "golang.org/x/exp/slices" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/uploader" providerElb "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/huaweicloud-elb" "github.com/usual2970/certimate/internal/pkg/utils/cast" @@ -44,7 +45,7 @@ type HuaweiCloudELBDeployerConfig struct { type HuaweiCloudELBDeployer struct { config *HuaweiCloudELBDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClient *hcElb.ElbClient sslUploader uploader.Uploader } @@ -52,10 +53,10 @@ type HuaweiCloudELBDeployer struct { var _ deployer.Deployer = (*HuaweiCloudELBDeployer)(nil) func New(config *HuaweiCloudELBDeployerConfig) (*HuaweiCloudELBDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *HuaweiCloudELBDeployerConfig, logger deployer.Logger) (*HuaweiCloudELBDeployer, error) { +func NewWithLogger(config *HuaweiCloudELBDeployerConfig, logger logger.Logger) (*HuaweiCloudELBDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/k8s-secret/k8s_secret.go b/internal/pkg/core/deployer/providers/k8s-secret/k8s_secret.go index f14fe1f6..f09e8331 100644 --- a/internal/pkg/core/deployer/providers/k8s-secret/k8s_secret.go +++ b/internal/pkg/core/deployer/providers/k8s-secret/k8s_secret.go @@ -13,34 +13,37 @@ import ( "k8s.io/client-go/tools/clientcmd" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/utils/x509" ) type K8sSecretDeployerConfig struct { // kubeconfig 文件内容。 KubeConfig string `json:"kubeConfig,omitempty"` - // K8s 命名空间。 + // Kubernetes 命名空间。 Namespace string `json:"namespace,omitempty"` - // K8s Secret 名称。 + // Kubernetes Secret 名称。 SecretName string `json:"secretName"` - // K8s Secret 中用于存放证书的 Key。 + // Kubernetes Secret 类型。 + SecretType string `json:"secretType"` + // Kubernetes Secret 中用于存放证书的 Key。 SecretDataKeyForCrt string `json:"secretDataKeyForCrt,omitempty"` - // K8s Secret 中用于存放私钥的 Key。 + // Kubernetes Secret 中用于存放私钥的 Key。 SecretDataKeyForKey string `json:"secretDataKeyForKey,omitempty"` } type K8sSecretDeployer struct { config *K8sSecretDeployerConfig - logger deployer.Logger + logger logger.Logger } var _ deployer.Deployer = (*K8sSecretDeployer)(nil) func New(config *K8sSecretDeployerConfig) (*K8sSecretDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *K8sSecretDeployerConfig, logger deployer.Logger) (*K8sSecretDeployer, error) { +func NewWithLogger(config *K8sSecretDeployerConfig, logger logger.Logger) (*K8sSecretDeployer, error) { if config == nil { return nil, errors.New("config is nil") } @@ -101,7 +104,7 @@ func (d *K8sSecretDeployer) Deploy(ctx context.Context, certPem string, privkeyP Name: d.config.SecretName, Annotations: secretAnnotations, }, - Type: k8sCore.SecretType("kubernetes.io/tls"), + Type: k8sCore.SecretType(d.config.SecretType), } secretPayload.Data = make(map[string][]byte) secretPayload.Data[d.config.SecretDataKeyForCrt] = []byte(certPem) @@ -117,7 +120,7 @@ func (d *K8sSecretDeployer) Deploy(ctx context.Context, certPem string, privkeyP } // 更新 Secret 实例 - secretPayload.Type = k8sCore.SecretType("kubernetes.io/tls") + secretPayload.Type = k8sCore.SecretType(d.config.SecretType) if secretPayload.ObjectMeta.Annotations == nil { secretPayload.ObjectMeta.Annotations = secretAnnotations } else { diff --git a/internal/pkg/core/deployer/providers/local/local.go b/internal/pkg/core/deployer/providers/local/local.go index d4eb7a66..344936d9 100644 --- a/internal/pkg/core/deployer/providers/local/local.go +++ b/internal/pkg/core/deployer/providers/local/local.go @@ -11,6 +11,7 @@ import ( xerrors "github.com/pkg/errors" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/utils/fs" "github.com/usual2970/certimate/internal/pkg/utils/x509" ) @@ -45,16 +46,16 @@ type LocalDeployerConfig struct { type LocalDeployer struct { config *LocalDeployerConfig - logger deployer.Logger + logger logger.Logger } var _ deployer.Deployer = (*LocalDeployer)(nil) func New(config *LocalDeployerConfig) (*LocalDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *LocalDeployerConfig, logger deployer.Logger) (*LocalDeployer, error) { +func NewWithLogger(config *LocalDeployerConfig, logger logger.Logger) (*LocalDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/qiniu-cdn/qiniu_cdn.go b/internal/pkg/core/deployer/providers/qiniu-cdn/qiniu_cdn.go index 7871bf17..03ae1762 100644 --- a/internal/pkg/core/deployer/providers/qiniu-cdn/qiniu_cdn.go +++ b/internal/pkg/core/deployer/providers/qiniu-cdn/qiniu_cdn.go @@ -9,6 +9,7 @@ import ( "github.com/qiniu/go-sdk/v7/auth" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/uploader" providerQiniu "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/qiniu-sslcert" qiniusdk "github.com/usual2970/certimate/internal/pkg/vendors/qiniu-sdk" @@ -25,7 +26,7 @@ type QiniuCDNDeployerConfig struct { type QiniuCDNDeployer struct { config *QiniuCDNDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClient *qiniusdk.Client sslUploader uploader.Uploader } @@ -33,10 +34,10 @@ type QiniuCDNDeployer struct { var _ deployer.Deployer = (*QiniuCDNDeployer)(nil) func New(config *QiniuCDNDeployerConfig) (*QiniuCDNDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *QiniuCDNDeployerConfig, logger deployer.Logger) (*QiniuCDNDeployer, error) { +func NewWithLogger(config *QiniuCDNDeployerConfig, logger logger.Logger) (*QiniuCDNDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/ssh/ssh.go b/internal/pkg/core/deployer/providers/ssh/ssh.go index 27e3fc1a..6d86434c 100644 --- a/internal/pkg/core/deployer/providers/ssh/ssh.go +++ b/internal/pkg/core/deployer/providers/ssh/ssh.go @@ -13,6 +13,7 @@ import ( "golang.org/x/crypto/ssh" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/utils/x509" ) @@ -57,16 +58,16 @@ type SshDeployerConfig struct { type SshDeployer struct { config *SshDeployerConfig - logger deployer.Logger + logger logger.Logger } var _ deployer.Deployer = (*SshDeployer)(nil) func New(config *SshDeployerConfig) (*SshDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *SshDeployerConfig, logger deployer.Logger) (*SshDeployer, error) { +func NewWithLogger(config *SshDeployerConfig, logger logger.Logger) (*SshDeployer, error) { if config == nil { return nil, errors.New("config is nil") } @@ -208,8 +209,8 @@ func execSshCommand(sshCli *ssh.Client, command string) (string, string, error) if err != nil { return "", "", err } - defer session.Close() + var stdoutBuf bytes.Buffer session.Stdout = &stdoutBuf var stderrBuf bytes.Buffer diff --git a/internal/pkg/core/deployer/providers/ssh/ssh_test.go b/internal/pkg/core/deployer/providers/ssh/ssh_test.go index f1c25e63..0dd58358 100644 --- a/internal/pkg/core/deployer/providers/ssh/ssh_test.go +++ b/internal/pkg/core/deployer/providers/ssh/ssh_test.go @@ -74,7 +74,6 @@ func TestDeploy(t *testing.T) { }) if err != nil { t.Errorf("err: %+v", err) - panic(err) } fInputCertData, _ := os.ReadFile(fInputCertPath) @@ -82,7 +81,6 @@ func TestDeploy(t *testing.T) { res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData)) if err != nil { t.Errorf("err: %+v", err) - panic(err) } t.Logf("ok: %v", res) diff --git a/internal/pkg/core/deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go b/internal/pkg/core/deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go index 68475257..fac9dbae 100644 --- a/internal/pkg/core/deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go +++ b/internal/pkg/core/deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go @@ -13,6 +13,7 @@ import ( "golang.org/x/exp/slices" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/uploader" providerSsl "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/tencentcloud-ssl" ) @@ -28,7 +29,7 @@ type TencentCloudCDNDeployerConfig struct { type TencentCloudCDNDeployer struct { config *TencentCloudCDNDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClients *tencentCloudCDNDeployerSdkClients sslUploader uploader.Uploader } @@ -41,10 +42,10 @@ type tencentCloudCDNDeployerSdkClients struct { } func New(config *TencentCloudCDNDeployerConfig) (*TencentCloudCDNDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *TencentCloudCDNDeployerConfig, logger deployer.Logger) (*TencentCloudCDNDeployer, error) { +func NewWithLogger(config *TencentCloudCDNDeployerConfig, logger logger.Logger) (*TencentCloudCDNDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/tencentcloud-clb/tencentcloud_clb.go b/internal/pkg/core/deployer/providers/tencentcloud-clb/tencentcloud_clb.go index 990e266d..ed00e1c9 100644 --- a/internal/pkg/core/deployer/providers/tencentcloud-clb/tencentcloud_clb.go +++ b/internal/pkg/core/deployer/providers/tencentcloud-clb/tencentcloud_clb.go @@ -12,6 +12,7 @@ import ( tcSsl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/uploader" providerSsl "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/tencentcloud-ssl" ) @@ -38,7 +39,7 @@ type TencentCloudCLBDeployerConfig struct { type TencentCloudCLBDeployer struct { config *TencentCloudCLBDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClients *wSdkClients sslUploader uploader.Uploader } @@ -51,10 +52,10 @@ type wSdkClients struct { } func New(config *TencentCloudCLBDeployerConfig) (*TencentCloudCLBDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *TencentCloudCLBDeployerConfig, logger deployer.Logger) (*TencentCloudCLBDeployer, error) { +func NewWithLogger(config *TencentCloudCLBDeployerConfig, logger logger.Logger) (*TencentCloudCLBDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/tencentcloud-cos/tencentcloud_cos.go b/internal/pkg/core/deployer/providers/tencentcloud-cos/tencentcloud_cos.go index 88f2ad60..23c2d11a 100644 --- a/internal/pkg/core/deployer/providers/tencentcloud-cos/tencentcloud_cos.go +++ b/internal/pkg/core/deployer/providers/tencentcloud-cos/tencentcloud_cos.go @@ -11,6 +11,7 @@ import ( tcSsl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/uploader" providerSsl "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/tencentcloud-ssl" ) @@ -30,7 +31,7 @@ type TencentCloudCOSDeployerConfig struct { type TencentCloudCOSDeployer struct { config *TencentCloudCOSDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClient *tcSsl.Client sslUploader uploader.Uploader } @@ -38,10 +39,10 @@ type TencentCloudCOSDeployer struct { var _ deployer.Deployer = (*TencentCloudCOSDeployer)(nil) func New(config *TencentCloudCOSDeployerConfig) (*TencentCloudCOSDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *TencentCloudCOSDeployerConfig, logger deployer.Logger) (*TencentCloudCOSDeployer, error) { +func NewWithLogger(config *TencentCloudCOSDeployerConfig, logger logger.Logger) (*TencentCloudCOSDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go b/internal/pkg/core/deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go index b5be93ba..e8cbdbb3 100644 --- a/internal/pkg/core/deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go +++ b/internal/pkg/core/deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go @@ -12,6 +12,7 @@ import ( tcSsl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/uploader" providerSsl "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/tencentcloud-ssl" ) @@ -27,7 +28,7 @@ type TencentCloudECDNDeployerConfig struct { type TencentCloudECDNDeployer struct { config *TencentCloudECDNDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClients *wSdkClients sslUploader uploader.Uploader } @@ -40,10 +41,10 @@ type wSdkClients struct { } func New(config *TencentCloudECDNDeployerConfig) (*TencentCloudECDNDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *TencentCloudECDNDeployerConfig, logger deployer.Logger) (*TencentCloudECDNDeployer, error) { +func NewWithLogger(config *TencentCloudECDNDeployerConfig, logger logger.Logger) (*TencentCloudECDNDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/tencentcloud-eo/tencentcloud_eo.go b/internal/pkg/core/deployer/providers/tencentcloud-eo/tencentcloud_eo.go index a1de42fa..fb45ea9e 100644 --- a/internal/pkg/core/deployer/providers/tencentcloud-eo/tencentcloud_eo.go +++ b/internal/pkg/core/deployer/providers/tencentcloud-eo/tencentcloud_eo.go @@ -11,6 +11,7 @@ import ( tcTeo "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo/v20220901" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/uploader" providerSsl "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/tencentcloud-ssl" ) @@ -28,7 +29,7 @@ type TencentCloudEODeployerConfig struct { type TencentCloudEODeployer struct { config *TencentCloudEODeployerConfig - logger deployer.Logger + logger logger.Logger sdkClients *wSdkClients sslUploader uploader.Uploader } @@ -41,10 +42,10 @@ type wSdkClients struct { } func New(config *TencentCloudEODeployerConfig) (*TencentCloudEODeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *TencentCloudEODeployerConfig, logger deployer.Logger) (*TencentCloudEODeployer, error) { +func NewWithLogger(config *TencentCloudEODeployerConfig, logger logger.Logger) (*TencentCloudEODeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/volcengine-cdn/volcengine_cdn.go b/internal/pkg/core/deployer/providers/volcengine-cdn/volcengine_cdn.go index 11906474..903ad1ea 100644 --- a/internal/pkg/core/deployer/providers/volcengine-cdn/volcengine_cdn.go +++ b/internal/pkg/core/deployer/providers/volcengine-cdn/volcengine_cdn.go @@ -10,6 +10,7 @@ import ( veCdn "github.com/volcengine/volc-sdk-golang/service/cdn" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/uploader" providerCdn "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/volcengine-cdn" ) @@ -25,7 +26,7 @@ type VolcEngineCDNDeployerConfig struct { type VolcEngineCDNDeployer struct { config *VolcEngineCDNDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClient *veCdn.CDN sslUploader uploader.Uploader } @@ -33,10 +34,10 @@ type VolcEngineCDNDeployer struct { var _ deployer.Deployer = (*VolcEngineCDNDeployer)(nil) func New(config *VolcEngineCDNDeployerConfig) (*VolcEngineCDNDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *VolcEngineCDNDeployerConfig, logger deployer.Logger) (*VolcEngineCDNDeployer, error) { +func NewWithLogger(config *VolcEngineCDNDeployerConfig, logger logger.Logger) (*VolcEngineCDNDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/volcengine-live/volcengine_live.go b/internal/pkg/core/deployer/providers/volcengine-live/volcengine_live.go index f492cf89..aba43a82 100644 --- a/internal/pkg/core/deployer/providers/volcengine-live/volcengine_live.go +++ b/internal/pkg/core/deployer/providers/volcengine-live/volcengine_live.go @@ -10,6 +10,7 @@ import ( veLive "github.com/volcengine/volc-sdk-golang/service/live/v20230101" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/uploader" providerLive "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/volcengine-live" "github.com/usual2970/certimate/internal/pkg/utils/cast" @@ -26,7 +27,7 @@ type VolcEngineLiveDeployerConfig struct { type VolcEngineLiveDeployer struct { config *VolcEngineLiveDeployerConfig - logger deployer.Logger + logger logger.Logger sdkClient *veLive.Live sslUploader uploader.Uploader } @@ -34,10 +35,10 @@ type VolcEngineLiveDeployer struct { var _ deployer.Deployer = (*VolcEngineLiveDeployer)(nil) func New(config *VolcEngineLiveDeployerConfig) (*VolcEngineLiveDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *VolcEngineLiveDeployerConfig, logger deployer.Logger) (*VolcEngineLiveDeployer, error) { +func NewWithLogger(config *VolcEngineLiveDeployerConfig, logger logger.Logger) (*VolcEngineLiveDeployer, error) { if config == nil { return nil, errors.New("config is nil") } diff --git a/internal/pkg/core/deployer/providers/webhook/webhook.go b/internal/pkg/core/deployer/providers/webhook/webhook.go index 76fcaaf8..d81da684 100644 --- a/internal/pkg/core/deployer/providers/webhook/webhook.go +++ b/internal/pkg/core/deployer/providers/webhook/webhook.go @@ -5,35 +5,38 @@ import ( "context" "encoding/json" "errors" - "net/http" + "io" "strings" + "time" + "github.com/gojek/heimdall/v7/httpclient" xerrors "github.com/pkg/errors" "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/utils/x509" - xhttp "github.com/usual2970/certimate/internal/utils/http" ) type WebhookDeployerConfig struct { // Webhook URL。 - Url string `json:"url"` - // Webhook 变量字典。 - Variables map[string]string `json:"variables,omitempty"` + WebhookUrl string `json:"webhookUrl"` + // Webhook 回调数据(JSON 格式)。 + WebhookData string `json:"webhookData,omitempty"` } type WebhookDeployer struct { - config *WebhookDeployerConfig - logger deployer.Logger + config *WebhookDeployerConfig + logger logger.Logger + httpClient *httpclient.Client } var _ deployer.Deployer = (*WebhookDeployer)(nil) func New(config *WebhookDeployerConfig) (*WebhookDeployer, error) { - return NewWithLogger(config, deployer.NewNilLogger()) + return NewWithLogger(config, logger.NewNilLogger()) } -func NewWithLogger(config *WebhookDeployerConfig, logger deployer.Logger) (*WebhookDeployer, error) { +func NewWithLogger(config *WebhookDeployerConfig, logger logger.Logger) (*WebhookDeployer, error) { if config == nil { return nil, errors.New("config is nil") } @@ -42,17 +45,13 @@ func NewWithLogger(config *WebhookDeployerConfig, logger deployer.Logger) (*Webh return nil, errors.New("logger is nil") } - return &WebhookDeployer{ - config: config, - logger: logger, - }, nil -} + client := httpclient.NewClient(httpclient.WithHTTPTimeout(30 * time.Second)) -type webhookData struct { - SubjectAltNames string `json:"subjectAltNames"` - Certificate string `json:"certificate"` - PrivateKey string `json:"privateKey"` - Variables map[string]string `json:"variables"` + return &WebhookDeployer{ + config: config, + logger: logger, + httpClient: client, + }, nil } func (d *WebhookDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { @@ -61,25 +60,51 @@ func (d *WebhookDeployer) Deploy(ctx context.Context, certPem string, privkeyPem return nil, xerrors.Wrap(err, "failed to parse x509") } - data := &webhookData{ - SubjectAltNames: strings.Join(certX509.DNSNames, ","), - Certificate: certPem, - PrivateKey: privkeyPem, - Variables: d.config.Variables, + var webhookData interface{} + err = json.Unmarshal([]byte(d.config.WebhookData), &webhookData) + if err != nil { + return nil, xerrors.Wrap(err, "failed to unmarshall webhook data") } - body, _ := json.Marshal(data) - resp, err := xhttp.Req(d.config.Url, http.MethodPost, bytes.NewReader(body), map[string]string{ - "Content-Type": "application/json", - }) + + replaceJsonValueRecursively(webhookData, "${DOMAIN}", certX509.Subject.CommonName) + replaceJsonValueRecursively(webhookData, "${DOMAINS}", strings.Join(certX509.DNSNames, ";")) + replaceJsonValueRecursively(webhookData, "${SUBJECT_ALT_NAMES}", strings.Join(certX509.DNSNames, ";")) + replaceJsonValueRecursively(webhookData, "${CERTIFICATE}", certPem) + replaceJsonValueRecursively(webhookData, "${PRIVATE_KEY}", privkeyPem) + + reqBody, _ := json.Marshal(&webhookData) + resp, err := d.httpClient.Post(d.config.WebhookUrl, bytes.NewReader(reqBody), map[string][]string{"Content-Type": {"application/json"}}) if err != nil { return nil, xerrors.Wrap(err, "failed to send webhook request") } + defer resp.Body.Close() - d.logger.Logt("Webhook Response", string(resp)) + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, xerrors.Wrap(err, "failed to read response body") + } + + d.logger.Logt("Webhook Response", string(respBody)) return &deployer.DeployResult{ - DeploymentData: map[string]any{ - "responseText": string(resp), + ExtendedData: map[string]any{ + "responseText": string(respBody), }, }, nil } + +func replaceJsonValueRecursively(data interface{}, oldStr, newStr string) interface{} { + switch v := data.(type) { + case map[string]interface{}: + for k, val := range v { + v[k] = replaceJsonValueRecursively(val, oldStr, newStr) + } + case []interface{}: + for i, val := range v { + v[i] = replaceJsonValueRecursively(val, oldStr, newStr) + } + case string: + return strings.ReplaceAll(v, oldStr, newStr) + } + return data +} diff --git a/internal/pkg/core/deployer/providers/webhook/webhook_test.go b/internal/pkg/core/deployer/providers/webhook/webhook_test.go index a3b36dda..ddb719c4 100644 --- a/internal/pkg/core/deployer/providers/webhook/webhook_test.go +++ b/internal/pkg/core/deployer/providers/webhook/webhook_test.go @@ -14,7 +14,8 @@ import ( var ( fInputCertPath string fInputKeyPath string - fUrl string + fWebhookUrl string + fWebhookData string ) func init() { @@ -22,7 +23,8 @@ func init() { flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "") flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "") - flag.StringVar(&fUrl, argsPrefix+"URL", "", "") + flag.StringVar(&fWebhookUrl, argsPrefix+"URL", "", "") + flag.StringVar(&fWebhookData, argsPrefix+"DATA", "", "") } /* @@ -31,7 +33,8 @@ Shell command to run this test: go test -v webhook_test.go -args \ --CERTIMATE_DEPLOYER_WEBHOOK_INPUTCERTPATH="/path/to/your-input-cert.pem" \ --CERTIMATE_DEPLOYER_WEBHOOK_INPUTKEYPATH="/path/to/your-input-key.pem" \ - --CERTIMATE_DEPLOYER_WEBHOOK_URL="https://example.com/your-webhook-url" + --CERTIMATE_DEPLOYER_WEBHOOK_URL="https://example.com/your-webhook-url" \ + --CERTIMATE_DEPLOYER_WEBHOOK_DATA="{\"certificate\":\"${Certificate}\",\"privateKey\":\"${PrivateKey}\"}" */ func TestDeploy(t *testing.T) { flag.Parse() @@ -41,11 +44,13 @@ func TestDeploy(t *testing.T) { "args:", fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath), fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath), - fmt.Sprintf("URL: %v", fUrl), + fmt.Sprintf("WEBHOOKURL: %v", fWebhookUrl), + fmt.Sprintf("WEBHOOKDATA: %v", fWebhookData), }, "\n")) deployer, err := provider.New(&provider.WebhookDeployerConfig{ - Url: fUrl, + WebhookUrl: fWebhookUrl, + WebhookData: fWebhookData, }) if err != nil { t.Errorf("err: %+v", err) diff --git a/internal/pkg/core/deployer/logger.go b/internal/pkg/core/logger/builtin.go similarity index 74% rename from internal/pkg/core/deployer/logger.go rename to internal/pkg/core/logger/builtin.go index 8a8b2f32..d3209d70 100644 --- a/internal/pkg/core/deployer/logger.go +++ b/internal/pkg/core/logger/builtin.go @@ -1,4 +1,4 @@ -package deployer +package logger import ( "encoding/json" @@ -7,31 +7,6 @@ import ( "strings" ) -// 表示定义证书部署器的日志记录器的抽象类型接口。 -type Logger interface { - // 追加一条日志记录。 - // 该方法会将 `data` 以 JSON 序列化后拼接到 `tag` 结尾。 - // - // 入参: - // - tag:标签。 - // - data:数据。 - Logt(tag string, data ...any) - - // 追加一条日志记录。 - // 该方法会将 `args` 以 `format` 格式化。 - // - // 入参: - // - format:格式化字符串。 - // - args:格式化参数。 - Logf(format string, args ...any) - - // 获取所有日志记录。 - GetRecords() []string - - // 清空所有日志记录。 - FlushRecords() -} - // 表示默认的日志记录器类型。 type DefaultLogger struct { records []string diff --git a/internal/pkg/core/logger/logger.go b/internal/pkg/core/logger/logger.go new file mode 100644 index 00000000..cc6284cd --- /dev/null +++ b/internal/pkg/core/logger/logger.go @@ -0,0 +1,27 @@ +package logger + +// 表示定义日志记录器的抽象类型接口。 +type Logger interface { + // 追加一条日志记录。 + // 该方法会将 `data` 以 JSON 序列化后拼接到 `tag` 结尾。 + // + // 入参: + // - tag:标签。 + // - data:数据。 + Logt(tag string, data ...any) + + // 追加一条日志记录。 + // 该方法会将 `args` 以 `format` 格式化。 + // + // 入参: + // - format:格式化字符串。 + // - args:格式化参数。 + Logf(format string, args ...any) + + // 获取所有日志记录。 + // TODO: 记录时间 + GetRecords() []string + + // 清空所有日志记录。 + FlushRecords() +} diff --git a/internal/pkg/core/deployer/logger_test.go b/internal/pkg/core/logger/logger_test.go similarity index 89% rename from internal/pkg/core/deployer/logger_test.go rename to internal/pkg/core/logger/logger_test.go index 35021a99..29308a83 100644 --- a/internal/pkg/core/deployer/logger_test.go +++ b/internal/pkg/core/logger/logger_test.go @@ -1,9 +1,9 @@ -package deployer_test +package logger_test import ( "testing" - "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" ) /* @@ -13,7 +13,7 @@ Shell command to run this test: */ func TestLogger(t *testing.T) { t.Run("Logger_Appendt", func(t *testing.T) { - logger := deployer.NewDefaultLogger() + logger := logger.NewDefaultLogger() logger.Logt("test") logger.Logt("test_nil", nil) @@ -34,7 +34,7 @@ func TestLogger(t *testing.T) { }) t.Run("Logger_Appendf", func(t *testing.T) { - logger := deployer.NewDefaultLogger() + logger := logger.NewDefaultLogger() logger.Logf("test") logger.Logf("test_nil: %v", nil) diff --git a/internal/pkg/core/notifier/notifier.go b/internal/pkg/core/notifier/notifier.go index d8819395..22fc8574 100644 --- a/internal/pkg/core/notifier/notifier.go +++ b/internal/pkg/core/notifier/notifier.go @@ -19,5 +19,5 @@ type Notifier interface { // 表示通知发送结果的数据结构。 type NotifyResult struct { - NotificationData map[string]any `json:"notificationData,omitempty"` + ExtendedData map[string]any `json:"extendedData,omitempty"` } diff --git a/internal/pkg/core/uploader/uploader.go b/internal/pkg/core/uploader/uploader.go index 1fc34d82..76748a99 100644 --- a/internal/pkg/core/uploader/uploader.go +++ b/internal/pkg/core/uploader/uploader.go @@ -21,7 +21,7 @@ type Uploader interface { // 表示证书上传结果的数据结构,包含上传后的证书 ID、名称和其他数据。 type UploadResult struct { - CertId string `json:"certId"` - CertName string `json:"certName"` - CertData map[string]any `json:"certData,omitempty"` + CertId string `json:"certId"` + CertName string `json:"certName"` + ExtendedData map[string]any `json:"extendedData,omitempty"` } diff --git a/internal/pkg/utils/maps/maps.go b/internal/pkg/utils/maps/maps.go index 0c80e3a3..a7c11592 100644 --- a/internal/pkg/utils/maps/maps.go +++ b/internal/pkg/utils/maps/maps.go @@ -118,6 +118,12 @@ func GetValueOrDefaultAsInt64(dict map[string]any, key string, defaultValue int6 } } + if result, ok := value.(int32); ok { + if result != 0 { + return int64(result) + } + } + // 兼容字符串类型的值 if str, ok := value.(string); ok { if result, err := strconv.ParseInt(str, 10, 64); err == nil { diff --git a/internal/repository/access.go b/internal/repository/access.go index d9cdfbef..9646dcc9 100644 --- a/internal/repository/access.go +++ b/internal/repository/access.go @@ -5,8 +5,8 @@ import ( "database/sql" "errors" + "github.com/usual2970/certimate/internal/app" "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/utils/app" ) type AccessRepository struct{} @@ -24,16 +24,16 @@ func (a *AccessRepository) GetById(ctx context.Context, id string) (*domain.Acce return nil, err } - rs := &domain.Access{ + access := &domain.Access{ Meta: domain.Meta{ - Id: record.GetId(), - Created: record.GetTime("created"), - Updated: record.GetTime("updated"), + Id: record.GetId(), + CreatedAt: record.GetCreated().Time(), + UpdatedAt: record.GetUpdated().Time(), }, - Name: record.GetString("name"), - Config: record.GetString("config"), - ConfigType: record.GetString("configType"), - Usage: record.GetString("usage"), + Name: record.GetString("name"), + Provider: record.GetString("provider"), + Config: record.GetString("config"), + Usage: record.GetString("usage"), } - return rs, nil + return access, nil } diff --git a/internal/repository/acme_account.go b/internal/repository/acme_account.go index 9f7e6d21..3289ced4 100644 --- a/internal/repository/acme_account.go +++ b/internal/repository/acme_account.go @@ -6,9 +6,10 @@ import ( "github.com/go-acme/lego/v4/registration" "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase/models" - "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/utils/app" "golang.org/x/sync/singleflight" + + "github.com/usual2970/certimate/internal/app" + "github.com/usual2970/certimate/internal/domain" ) type AcmeAccountRepository struct{} @@ -46,13 +47,15 @@ func (r *AcmeAccountRepository) GetByCAAndEmail(ca, email string) (*domain.AcmeA } return &domain.AcmeAccount{ - Id: record.GetString("id"), - Ca: record.GetString("ca"), + Meta: domain.Meta{ + Id: record.GetId(), + CreatedAt: record.GetCreated().Time(), + UpdatedAt: record.GetUpdated().Time(), + }, + CA: record.GetString("ca"), Email: record.GetString("email"), Key: record.GetString("key"), Resource: resource, - Created: record.GetTime("created"), - Updated: record.GetTime("updated"), }, nil } diff --git a/internal/repository/certificate.go b/internal/repository/certificate.go index bff25a12..9bce7a9e 100644 --- a/internal/repository/certificate.go +++ b/internal/repository/certificate.go @@ -3,8 +3,8 @@ package repository import ( "context" + "github.com/usual2970/certimate/internal/app" "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/utils/app" ) type CertificateRepository struct{} @@ -13,12 +13,14 @@ func NewCertificateRepository() *CertificateRepository { return &CertificateRepository{} } -func (c *CertificateRepository) GetExpireSoon(ctx context.Context) ([]domain.Certificate, error) { - rs := []domain.Certificate{} - if err := app.GetApp().Dao().DB(). - NewQuery("select * from certificate where expireAt > datetime('now') and expireAt < datetime('now', '+20 days')"). - All(&rs); err != nil { +func (c *CertificateRepository) ListExpireSoon(ctx context.Context) ([]domain.Certificate, error) { + certificates := []domain.Certificate{} + err := app.GetApp().Dao().DB(). + NewQuery("SELECT * FROM certificate WHERE expireAt > DATETIME('now') AND expireAt < DATETIME('now', '+20 days')"). + All(&certificates) + if err != nil { return nil, err } - return rs, nil + + return certificates, nil } diff --git a/internal/repository/setting.go b/internal/repository/setting.go deleted file mode 100644 index c173151f..00000000 --- a/internal/repository/setting.go +++ /dev/null @@ -1,31 +0,0 @@ -package repository - -import ( - "context" - - "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/utils/app" -) - -type SettingRepository struct{} - -func NewSettingRepository() *SettingRepository { - return &SettingRepository{} -} - -func (s *SettingRepository) GetByName(ctx context.Context, name string) (*domain.Setting, error) { - resp, err := app.GetApp().Dao().FindFirstRecordByFilter("settings", "name='"+name+"'") - if err != nil { - return nil, err - } - - rs := &domain.Setting{ - ID: resp.GetString("id"), - Name: resp.GetString("name"), - Content: resp.GetString("content"), - Created: resp.GetTime("created"), - Updated: resp.GetTime("updated"), - } - - return rs, nil -} diff --git a/internal/repository/settings.go b/internal/repository/settings.go new file mode 100644 index 00000000..bd13cc2e --- /dev/null +++ b/internal/repository/settings.go @@ -0,0 +1,33 @@ +package repository + +import ( + "context" + + "github.com/pocketbase/dbx" + "github.com/usual2970/certimate/internal/app" + "github.com/usual2970/certimate/internal/domain" +) + +type SettingsRepository struct{} + +func NewSettingsRepository() *SettingsRepository { + return &SettingsRepository{} +} + +func (s *SettingsRepository) GetByName(ctx context.Context, name string) (*domain.Settings, error) { + record, err := app.GetApp().Dao().FindFirstRecordByFilter("settings", "name={:name}", dbx.Params{"name": name}) + if err != nil { + return nil, err + } + + settings := &domain.Settings{ + Meta: domain.Meta{ + Id: record.GetId(), + CreatedAt: record.GetCreated().Time(), + UpdatedAt: record.GetUpdated().Time(), + }, + Name: record.GetString("name"), + Content: record.GetString("content"), + } + return settings, nil +} diff --git a/internal/repository/statistics.go b/internal/repository/statistics.go index 92627b36..6cd19009 100644 --- a/internal/repository/statistics.go +++ b/internal/repository/statistics.go @@ -3,8 +3,8 @@ package repository import ( "context" + "github.com/usual2970/certimate/internal/app" "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/utils/app" ) type StatisticsRepository struct{} @@ -13,47 +13,54 @@ func NewStatisticsRepository() *StatisticsRepository { return &StatisticsRepository{} } -type totalResp struct { - Total int `json:"total" db:"total"` -} - func (r *StatisticsRepository) Get(ctx context.Context) (*domain.Statistics, error) { rs := &domain.Statistics{} + // 所有证书 - certTotal := totalResp{} - if err := app.GetApp().Dao().DB().NewQuery("select count(*) as total from certificate").One(&certTotal); err != nil { + certTotal := struct { + Total int `db:"total"` + }{} + if err := app.GetApp().Dao().DB().NewQuery("SELECT COUNT(*) AS total FROM certificate").One(&certTotal); err != nil { return nil, err } rs.CertificateTotal = certTotal.Total // 即将过期证书 - certExpireSoonTotal := totalResp{} + certExpireSoonTotal := struct { + Total int `db:"total"` + }{} if err := app.GetApp().Dao().DB(). - NewQuery("select count(*) as total from certificate where expireAt > datetime('now') and expireAt < datetime('now', '+20 days')"). + NewQuery("SELECT COUNT(*) AS total FROM certificate WHERE expireAt > DATETIME('now') and expireAt < DATETIME('now', '+20 days')"). One(&certExpireSoonTotal); err != nil { return nil, err } rs.CertificateExpireSoon = certExpireSoonTotal.Total // 已过期证书 - certExpiredTotal := totalResp{} + certExpiredTotal := struct { + Total int `db:"total"` + }{} if err := app.GetApp().Dao().DB(). - NewQuery("select count(*) as total from certificate where expireAt < datetime('now')"). + NewQuery("SELECT COUNT(*) AS total FROM certificate WHERE expireAt < DATETIME('now')"). One(&certExpiredTotal); err != nil { return nil, err } rs.CertificateExpired = certExpiredTotal.Total // 所有工作流 - workflowTotal := totalResp{} - if err := app.GetApp().Dao().DB().NewQuery("select count(*) as total from workflow").One(&workflowTotal); err != nil { + workflowTotal := struct { + Total int `db:"total"` + }{} + if err := app.GetApp().Dao().DB().NewQuery("SELECT COUNT(*) AS total FROM workflow").One(&workflowTotal); err != nil { return nil, err } rs.WorkflowTotal = workflowTotal.Total // 已启用工作流 - workflowEnabledTotal := totalResp{} - if err := app.GetApp().Dao().DB().NewQuery("select count(*) as total from workflow where enabled is TRUE").One(&workflowEnabledTotal); err != nil { + workflowEnabledTotal := struct { + Total int `db:"total"` + }{} + if err := app.GetApp().Dao().DB().NewQuery("SELECT COUNT(*) AS total FROM workflow WHERE enabled IS TRUE").One(&workflowEnabledTotal); err != nil { return nil, err } rs.WorkflowEnabled = workflowEnabledTotal.Total diff --git a/internal/repository/workflow.go b/internal/repository/workflow.go index 5ab3f9f4..7c0fc46e 100644 --- a/internal/repository/workflow.go +++ b/internal/repository/workflow.go @@ -6,9 +6,10 @@ import ( "errors" "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" "github.com/pocketbase/pocketbase/models" + "github.com/usual2970/certimate/internal/app" "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/utils/app" ) type WorkflowRepository struct{} @@ -20,12 +21,13 @@ func NewWorkflowRepository() *WorkflowRepository { func (w *WorkflowRepository) ListEnabledAuto(ctx context.Context) ([]domain.Workflow, error) { records, err := app.GetApp().Dao().FindRecordsByFilter( "workflow", - "enabled={:enabled} && type={:type}", - "-created", 1000, 0, dbx.Params{"enabled": true, "type": domain.WorkflowTypeAuto}, + "enabled={:enabled} && trigger={:trigger}", + "-created", 1000, 0, dbx.Params{"enabled": true, "trigger": domain.WorkflowTriggerTypeAuto}, ) if err != nil { return nil, err } + rs := make([]domain.Workflow, 0) for _, record := range records { workflow, err := record2Workflow(record) @@ -34,25 +36,53 @@ func (w *WorkflowRepository) ListEnabledAuto(ctx context.Context) ([]domain.Work } rs = append(rs, *workflow) } + return rs, nil } -func (w *WorkflowRepository) SaveRunLog(ctx context.Context, log *domain.WorkflowRunLog) error { - collection, err := app.GetApp().Dao().FindCollectionByNameOrId("workflow_run_log") +func (w *WorkflowRepository) SaveRun(ctx context.Context, run *domain.WorkflowRun) error { + collection, err := app.GetApp().Dao().FindCollectionByNameOrId("workflow_run") if err != nil { return err } - record := models.NewRecord(collection) - record.Set("workflow", log.Workflow) - record.Set("log", log.Log) - record.Set("succeed", log.Succeed) - record.Set("error", log.Error) + err = app.GetApp().Dao().RunInTransaction(func(txDao *daos.Dao) error { + record := models.NewRecord(collection) + record.Set("workflowId", run.WorkflowId) + record.Set("trigger", string(run.Trigger)) + record.Set("status", string(run.Status)) + record.Set("startedAt", run.StartedAt) + record.Set("endedAt", run.EndedAt) + record.Set("logs", run.Logs) + record.Set("error", run.Error) + err = txDao.SaveRecord(record) + if err != nil { + return err + } - return app.GetApp().Dao().SaveRecord(record) + _, err = txDao.DB().Update( + "workflow", + dbx.Params{ + "lastRunId": record.GetId(), + "lastRunStatus": record.GetString("status"), + "lastRunTime": record.GetString("startedAt"), + }, + dbx.NewExp("id={:id}", dbx.Params{"id": run.WorkflowId}), + ).Execute() + if err != nil { + return err + } + + return nil + }) + if err != nil { + return err + } + + return nil } -func (w *WorkflowRepository) Get(ctx context.Context, id string) (*domain.Workflow, error) { +func (w *WorkflowRepository) GetById(ctx context.Context, id string) (*domain.Workflow, error) { record, err := app.GetApp().Dao().FindRecordById("workflow", id) if err != nil { if errors.Is(err, sql.ErrNoRows) { @@ -77,20 +107,21 @@ func record2Workflow(record *models.Record) (*domain.Workflow, error) { workflow := &domain.Workflow{ Meta: domain.Meta{ - Id: record.GetId(), - Created: record.GetTime("created"), - Updated: record.GetTime("updated"), + Id: record.GetId(), + CreatedAt: record.GetCreated().Time(), + UpdatedAt: record.GetUpdated().Time(), }, - Name: record.GetString("name"), - Description: record.GetString("description"), - Type: record.GetString("type"), - Crontab: record.GetString("crontab"), - Enabled: record.GetBool("enabled"), - HasDraft: record.GetBool("hasDraft"), - - Content: content, - Draft: draft, + Name: record.GetString("name"), + Description: record.GetString("description"), + Trigger: domain.WorkflowTriggerType(record.GetString("trigger")), + TriggerCron: record.GetString("triggerCron"), + Enabled: record.GetBool("enabled"), + Content: content, + Draft: draft, + HasDraft: record.GetBool("hasDraft"), + LastRunId: record.GetString("lastRunId"), + LastRunStatus: domain.WorkflowRunStatusType(record.GetString("lastRunStatus")), + LastRunTime: record.GetDateTime("lastRunTime").Time(), } - return workflow, nil } diff --git a/internal/repository/workflow_output.go b/internal/repository/workflow_output.go index cd9e0d47..074dd85d 100644 --- a/internal/repository/workflow_output.go +++ b/internal/repository/workflow_output.go @@ -7,8 +7,8 @@ import ( "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase/models" + "github.com/usual2970/certimate/internal/app" "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/utils/app" ) type WorkflowOutputRepository struct{} @@ -17,7 +17,7 @@ func NewWorkflowOutputRepository() *WorkflowOutputRepository { return &WorkflowOutputRepository{} } -func (w *WorkflowOutputRepository) Get(ctx context.Context, nodeId string) (*domain.WorkflowOutput, error) { +func (w *WorkflowOutputRepository) GetByNodeId(ctx context.Context, nodeId string) (*domain.WorkflowOutput, error) { records, err := app.GetApp().Dao().FindRecordsByFilter("workflow_output", "nodeId={:nodeId}", "-created", 1, 0, dbx.Params{"nodeId": nodeId}) if err != nil { if errors.Is(err, sql.ErrNoRows) { @@ -35,29 +35,29 @@ func (w *WorkflowOutputRepository) Get(ctx context.Context, nodeId string) (*dom return nil, errors.New("failed to unmarshal node") } - output := make([]domain.WorkflowNodeIo, 0) - if err := record.UnmarshalJSONField("output", &output); err != nil { + outputs := make([]domain.WorkflowNodeIO, 0) + if err := record.UnmarshalJSONField("outputs", &outputs); err != nil { return nil, errors.New("failed to unmarshal output") } rs := &domain.WorkflowOutput{ Meta: domain.Meta{ - Id: record.GetId(), - Created: record.GetCreated().Time(), - Updated: record.GetUpdated().Time(), + Id: record.GetId(), + CreatedAt: record.GetCreated().Time(), + UpdatedAt: record.GetUpdated().Time(), }, - Workflow: record.GetString("workflow"), - NodeId: record.GetString("nodeId"), - Node: node, - Output: output, - Succeed: record.GetBool("succeed"), + WorkflowId: record.GetString("workflowId"), + NodeId: record.GetString("nodeId"), + Node: node, + Outputs: outputs, + Succeeded: record.GetBool("succeeded"), } return rs, nil } -func (w *WorkflowOutputRepository) GetCertificate(ctx context.Context, nodeId string) (*domain.Certificate, error) { - records, err := app.GetApp().Dao().FindRecordsByFilter("certificate", "nodeId={:nodeId}", "-created", 1, 0, dbx.Params{"nodeId": nodeId}) +func (w *WorkflowOutputRepository) GetCertificateByNodeId(ctx context.Context, nodeId string) (*domain.Certificate, error) { + records, err := app.GetApp().Dao().FindRecordsByFilter("certificate", "workflowNodeId={:workflowNodeId}", "-created", 1, 0, dbx.Params{"workflowNodeId": nodeId}) if err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, domain.ErrRecordNotFound @@ -72,20 +72,22 @@ func (w *WorkflowOutputRepository) GetCertificate(ctx context.Context, nodeId st rs := &domain.Certificate{ Meta: domain.Meta{ - Id: record.GetId(), - Created: record.GetDateTime("created").Time(), - Updated: record.GetDateTime("updated").Time(), + Id: record.GetId(), + CreatedAt: record.GetCreated().Time(), + UpdatedAt: record.GetUpdated().Time(), }, + Source: domain.CertificateSourceType(record.GetString("source")), + SubjectAltNames: record.GetString("subjectAltNames"), Certificate: record.GetString("certificate"), PrivateKey: record.GetString("privateKey"), IssuerCertificate: record.GetString("issuerCertificate"), - SAN: record.GetString("san"), - Output: record.GetString("output"), + EffectAt: record.GetDateTime("effectAt").Time(), ExpireAt: record.GetDateTime("expireAt").Time(), - CertUrl: record.GetString("certUrl"), - CertStableUrl: record.GetString("certStableUrl"), - Workflow: record.GetString("workflow"), - NodeId: record.GetString("nodeId"), + ACMECertUrl: record.GetString("acmeCertUrl"), + ACMECertStableUrl: record.GetString("acmeCertStableUrl"), + WorkflowId: record.GetString("workflowId"), + WorkflowNodeId: record.GetString("workflowNodeId"), + WorkflowOutputId: record.GetString("workflowOutputId"), } return rs, nil } @@ -107,11 +109,11 @@ func (w *WorkflowOutputRepository) Save(ctx context.Context, output *domain.Work return err } } - record.Set("workflow", output.Workflow) + record.Set("workflowId", output.WorkflowId) record.Set("nodeId", output.NodeId) record.Set("node", output.Node) - record.Set("output", output.Output) - record.Set("succeed", output.Succeed) + record.Set("outputs", output.Outputs) + record.Set("succeeded", output.Succeeded) if err := app.GetApp().Dao().SaveRecord(record); err != nil { return err @@ -128,30 +130,32 @@ func (w *WorkflowOutputRepository) Save(ctx context.Context, output *domain.Work } certRecord := models.NewRecord(certCollection) + certRecord.Set("source", string(certificate.Source)) + certRecord.Set("subjectAltNames", certificate.SubjectAltNames) certRecord.Set("certificate", certificate.Certificate) certRecord.Set("privateKey", certificate.PrivateKey) certRecord.Set("issuerCertificate", certificate.IssuerCertificate) - certRecord.Set("san", certificate.SAN) - certRecord.Set("output", certificate.Output) + certRecord.Set("effectAt", certificate.EffectAt) certRecord.Set("expireAt", certificate.ExpireAt) - certRecord.Set("certUrl", certificate.CertUrl) - certRecord.Set("certStableUrl", certificate.CertStableUrl) - certRecord.Set("workflow", certificate.Workflow) - certRecord.Set("nodeId", certificate.NodeId) + certRecord.Set("acmeCertUrl", certificate.ACMECertUrl) + certRecord.Set("acmeCertStableUrl", certificate.ACMECertStableUrl) + certRecord.Set("workflowId", certificate.WorkflowId) + certRecord.Set("workflowNodeId", certificate.WorkflowNodeId) + certRecord.Set("workflowOutputId", certificate.WorkflowOutputId) if err := app.GetApp().Dao().SaveRecord(certRecord); err != nil { return err } // 更新 certificate - for i, item := range output.Output { - if item.Name == "certificate" { - output.Output[i].Value = certRecord.GetId() + for i, item := range output.Outputs { + if item.Name == domain.WORKFLOW_OUTPUT_CERTIFICATE { + output.Outputs[i].Value = certRecord.GetId() break } } - record.Set("output", output.Output) + record.Set("outputs", output.Outputs) if err := app.GetApp().Dao().SaveRecord(record); err != nil { return err diff --git a/internal/rest/notify.go b/internal/rest/notify.go index 463bc81d..a9d00420 100644 --- a/internal/rest/notify.go +++ b/internal/rest/notify.go @@ -4,7 +4,7 @@ import ( "context" "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/utils/resp" + "github.com/usual2970/certimate/internal/rest/resp" "github.com/labstack/echo/v5" ) diff --git a/internal/utils/resp/resp.go b/internal/rest/resp/resp.go similarity index 100% rename from internal/utils/resp/resp.go rename to internal/rest/resp/resp.go index b4d8240f..d1aa078a 100644 --- a/internal/utils/resp/resp.go +++ b/internal/rest/resp/resp.go @@ -3,9 +3,9 @@ package resp import ( "net/http" - "github.com/usual2970/certimate/internal/domain" - "github.com/labstack/echo/v5" + + "github.com/usual2970/certimate/internal/domain" ) type Response struct { diff --git a/internal/rest/statistics.go b/internal/rest/statistics.go index a26f1d36..b539f6b4 100644 --- a/internal/rest/statistics.go +++ b/internal/rest/statistics.go @@ -5,7 +5,7 @@ import ( "github.com/labstack/echo/v5" "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/utils/resp" + "github.com/usual2970/certimate/internal/rest/resp" ) type StatisticsService interface { diff --git a/internal/rest/workflow.go b/internal/rest/workflow.go index 8d6270ec..0ccab150 100644 --- a/internal/rest/workflow.go +++ b/internal/rest/workflow.go @@ -5,7 +5,7 @@ import ( "github.com/labstack/echo/v5" "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/utils/resp" + "github.com/usual2970/certimate/internal/rest/resp" ) type WorkflowService interface { diff --git a/internal/routes/routes.go b/internal/routes/routes.go index 4e0e51b7..058f1815 100644 --- a/internal/routes/routes.go +++ b/internal/routes/routes.go @@ -14,7 +14,7 @@ import ( func Register(e *echo.Echo) { group := e.Group("/api", apis.RequireAdminAuth()) - notifyRepo := repository.NewSettingRepository() + notifyRepo := repository.NewSettingsRepository() notifySvc := notify.NewNotifyService(notifyRepo) workflowRepo := repository.NewWorkflowRepository() diff --git a/internal/utils/http/http.go b/internal/utils/http/http.go deleted file mode 100644 index 6269ea98..00000000 --- a/internal/utils/http/http.go +++ /dev/null @@ -1,71 +0,0 @@ -package http - -import ( - "fmt" - "io" - "net/http" - "time" - - "github.com/gojek/heimdall/v7/httpclient" -) - -type Options struct { - Timeout time.Duration -} - -type Option func(o *Options) - -func WithTimeout(timeout time.Duration) Option { - return func(o *Options) { - o.Timeout = timeout - } -} - -func Req(url string, method string, body io.Reader, head map[string]string, opts ...Option) ([]byte, error) { - reader, err := Req2GetReader(url, method, body, head, opts...) - if err != nil { - return nil, err - } - defer reader.Close() - - return io.ReadAll(reader) -} - -func Req2GetReader(url string, method string, body io.Reader, head map[string]string, opts ...Option) (io.ReadCloser, error) { - req := BuildReq(url, method, body, head) - - return ToRequest(req, opts...) -} - -func BuildReq(url string, method string, body io.Reader, head map[string]string) *http.Request { - // Create an http.Request instance - req, _ := http.NewRequest(method, url, body) - for k, v := range head { - req.Header.Set(k, v) - } - - return req -} - -func ToRequest(req *http.Request, opts ...Option) (io.ReadCloser, error) { - options := &Options{ - Timeout: 30000 * time.Millisecond, - } - - for _, opt := range opts { - opt(options) - } - - client := httpclient.NewClient(httpclient.WithHTTPTimeout(options.Timeout)) - // Call the `Do` method, which has a similar interface to the `http.Do` method - res, err := client.Do(req) - if err != nil { - return nil, err - } - - if res.StatusCode != http.StatusOK { - return nil, fmt.Errorf("status code is not 200: %d", res.StatusCode) - } - - return res.Body, nil -} diff --git a/internal/utils/variables/variables.go b/internal/utils/variables/variables.go deleted file mode 100644 index 74a7b22d..00000000 --- a/internal/utils/variables/variables.go +++ /dev/null @@ -1,29 +0,0 @@ -package variables - -import "strings" - -// Parse2Map 将变量赋值字符串解析为map -func Parse2Map(str string) map[string]string { - m := make(map[string]string) - - lines := strings.Split(str, ";") - - for _, line := range lines { - - line = strings.TrimSpace(line) - - if line == "" { - continue - } - - kv := strings.Split(line, "=") - - if len(kv) != 2 { - continue - } - - m[kv[0]] = kv[1] - } - - return m -} diff --git a/internal/utils/variables/variables_test.go b/internal/utils/variables/variables_test.go deleted file mode 100644 index c1c2764e..00000000 --- a/internal/utils/variables/variables_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package variables - -import ( - "reflect" - "testing" -) - -func TestParse2Map(t *testing.T) { - type args struct { - str string - } - tests := []struct { - name string - args args - want map[string]string - }{ - { - name: "test1", - args: args{ - str: "a=1;b=2;c=3", - }, - want: map[string]string{ - "a": "1", - "b": "2", - "c": "3", - }, - }, - { - name: "test2", - args: args{ - str: `a=1; - b=2; - c=`, - }, - want: map[string]string{ - "a": "1", - "b": "2", - "c": "", - }, - }, - { - name: "test3", - args: args{ - str: "1", - }, - want: map[string]string{}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := Parse2Map(tt.args.str); !reflect.DeepEqual(got, tt.want) { - t.Errorf("Parse2Map() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/internal/utils/xtime/time.go b/internal/utils/xtime/time.go deleted file mode 100644 index 149321dc..00000000 --- a/internal/utils/xtime/time.go +++ /dev/null @@ -1,15 +0,0 @@ -package xtime - -import ( - "time" -) - -func BeijingTimeStr() string { - location, _ := time.LoadLocation("Asia/Shanghai") - - // 获取当前时间 - now := time.Now().In(location) - - // 格式化为字符串 - return now.Format("2006-01-02 15:04:05") -} diff --git a/internal/workflow/event.go b/internal/workflow/event.go index 04b53521..2f209baa 100644 --- a/internal/workflow/event.go +++ b/internal/workflow/event.go @@ -7,14 +7,14 @@ import ( "github.com/pocketbase/pocketbase/core" "github.com/pocketbase/pocketbase/models" + "github.com/usual2970/certimate/internal/app" "github.com/usual2970/certimate/internal/domain" "github.com/usual2970/certimate/internal/repository" - "github.com/usual2970/certimate/internal/utils/app" ) const tableName = "workflow" -func AddEvent() error { +func RegisterEvents() error { app := app.GetApp() app.OnRecordAfterCreateRequest(tableName).Add(func(e *core.RecordCreateEvent) error { @@ -32,40 +32,45 @@ func AddEvent() error { return nil } -func delete(_ context.Context, record *models.Record) error { - id := record.Id - scheduler := app.GetScheduler() - scheduler.Remove(id) - scheduler.Start() - return nil -} - func update(ctx context.Context, record *models.Record) error { - // 是不是自动 - // 是不是 enabled - - id := record.Id - enabled := record.GetBool("enabled") - executeMethod := record.GetString("type") - scheduler := app.GetScheduler() - if !enabled || executeMethod == domain.WorkflowTypeManual { - scheduler.Remove(id) + + // 向数据库插入/更新时,同时更新定时任务 + workflowId := record.GetId() + enabled := record.GetBool("enabled") + trigger := record.GetString("trigger") + + // 如果是手动触发或未启用,移除定时任务 + if !enabled || trigger == string(domain.WorkflowTriggerTypeManual) { + scheduler.Remove(fmt.Sprintf("workflow#%s", workflowId)) scheduler.Start() return nil } - err := scheduler.Add(id, record.GetString("crontab"), func() { + // 反之,重新添加定时任务 + err := scheduler.Add(fmt.Sprintf("workflow#%s", workflowId), record.GetString("triggerCron"), func() { NewWorkflowService(repository.NewWorkflowRepository()).Run(ctx, &domain.WorkflowRunReq{ - Id: id, + WorkflowId: workflowId, + Trigger: domain.WorkflowTriggerTypeAuto, }) }) if err != nil { - app.GetApp().Logger().Error("add cron job failed", "err", err) + app.GetLogger().Error("add cron job failed", "err", err) return fmt.Errorf("add cron job failed: %w", err) } - app.GetApp().Logger().Error("add cron job failed", "san", record.GetString("san")) scheduler.Start() + + return nil +} + +func delete(_ context.Context, record *models.Record) error { + scheduler := app.GetScheduler() + + // 从数据库删除时,同时移除定时任务 + workflowId := record.GetId() + scheduler.Remove(fmt.Sprintf("workflow#%s", workflowId)) + scheduler.Start() + return nil } diff --git a/internal/workflow/node-processor/apply_node.go b/internal/workflow/node-processor/apply_node.go index 44257d4c..d214ca63 100644 --- a/internal/workflow/node-processor/apply_node.go +++ b/internal/workflow/node-processor/apply_node.go @@ -17,6 +17,8 @@ type applyNode struct { *Logger } +var validityDuration = time.Hour * 24 * 10 + func NewApplyNode(node *domain.WorkflowNode) *applyNode { return &applyNode{ node: node, @@ -27,10 +29,10 @@ func NewApplyNode(node *domain.WorkflowNode) *applyNode { type WorkflowOutputRepository interface { // 查询节点输出 - Get(ctx context.Context, nodeId string) (*domain.WorkflowOutput, error) + GetByNodeId(ctx context.Context, nodeId string) (*domain.WorkflowOutput, error) // 查询申请节点的证书 - GetCertificate(ctx context.Context, nodeId string) (*domain.Certificate, error) + GetCertificateByNodeId(ctx context.Context, nodeId string) (*domain.Certificate, error) // 保存节点输出 Save(ctx context.Context, output *domain.WorkflowOutput, certificate *domain.Certificate, cb func(id string) error) error @@ -39,35 +41,33 @@ type WorkflowOutputRepository interface { // 申请节点根据申请类型执行不同的操作 func (a *applyNode) Run(ctx context.Context) error { a.AddOutput(ctx, a.node.Name, "开始执行") - // 查询是否申请过,已申请过则直接返回(先保持和 v0.2 一致) - output, err := a.outputRepo.Get(ctx, a.node.Id) + // 查询是否申请过,已申请过则直接返回 + // TODO: 先保持和 v0.2 一致,后续增加是否强制申请的参数 + output, err := a.outputRepo.GetByNodeId(ctx, a.node.Id) if err != nil && !domain.IsRecordNotFound(err) { a.AddOutput(ctx, a.node.Name, "查询申请记录失败", err.Error()) return err } - if output != nil && output.Succeed { - cert, err := a.outputRepo.GetCertificate(ctx, a.node.Id) - if err != nil { - a.AddOutput(ctx, a.node.Name, "获取证书失败", err.Error()) - return err - } - - if time.Until(cert.ExpireAt) > domain.ValidityDuration { - a.AddOutput(ctx, a.node.Name, "已申请过证书,且证书在有效期内") - return nil + if output != nil && output.Succeeded { + lastCertificate, _ := a.outputRepo.GetCertificateByNodeId(ctx, a.node.Id) + if lastCertificate != nil { + if time.Until(lastCertificate.ExpireAt) > validityDuration { + a.AddOutput(ctx, a.node.Name, "已申请过证书,且证书在有效期内") + return nil + } } } // 获取Applicant - apply, err := applicant.GetWithApplyNode(a.node) + applicant, err := applicant.NewWithApplyNode(a.node) if err != nil { a.AddOutput(ctx, a.node.Name, "获取申请对象失败", err.Error()) return err } // 申请 - certificate, err := apply.Apply() + applyResult, err := applicant.Apply() if err != nil { a.AddOutput(ctx, a.node.Name, "申请失败", err.Error()) return err @@ -81,35 +81,37 @@ func (a *applyNode) Run(ctx context.Context) error { outputId = output.Id } output = &domain.WorkflowOutput{ - Workflow: GetWorkflowId(ctx), - NodeId: a.node.Id, - Node: a.node, - Succeed: true, - Output: a.node.Output, - Meta: domain.Meta{Id: outputId}, + Meta: domain.Meta{Id: outputId}, + WorkflowId: GetWorkflowId(ctx), + NodeId: a.node.Id, + Node: a.node, + Succeeded: true, + Outputs: a.node.Outputs, } - cert, err := x509.ParseCertificateFromPEM(certificate.Certificate) + certX509, err := x509.ParseCertificateFromPEM(applyResult.Certificate) if err != nil { a.AddOutput(ctx, a.node.Name, "解析证书失败", err.Error()) return err } - certificateRecord := &domain.Certificate{ - SAN: strings.Join(cert.DNSNames, ";"), - Certificate: certificate.Certificate, - PrivateKey: certificate.PrivateKey, - IssuerCertificate: certificate.IssuerCertificate, - CertUrl: certificate.CertUrl, - CertStableUrl: certificate.CertStableUrl, - ExpireAt: cert.NotAfter, - Workflow: GetWorkflowId(ctx), - NodeId: a.node.Id, + certificate := &domain.Certificate{ + Source: domain.CertificateSourceTypeWorkflow, + SubjectAltNames: strings.Join(certX509.DNSNames, ";"), + Certificate: applyResult.Certificate, + PrivateKey: applyResult.PrivateKey, + IssuerCertificate: applyResult.IssuerCertificate, + ACMECertUrl: applyResult.ACMECertUrl, + ACMECertStableUrl: applyResult.ACMECertStableUrl, + EffectAt: certX509.NotBefore, + ExpireAt: certX509.NotAfter, + WorkflowId: GetWorkflowId(ctx), + WorkflowNodeId: a.node.Id, } - if err := a.outputRepo.Save(ctx, output, certificateRecord, func(id string) error { - if certificateRecord != nil { - certificateRecord.Output = id + if err := a.outputRepo.Save(ctx, output, certificate, func(id string) error { + if certificate != nil { + certificate.WorkflowOutputId = id } return nil diff --git a/internal/workflow/node-processor/deploy_node.go b/internal/workflow/node-processor/deploy_node.go index 46c7df9f..1623e84c 100644 --- a/internal/workflow/node-processor/deploy_node.go +++ b/internal/workflow/node-processor/deploy_node.go @@ -5,7 +5,6 @@ import ( "fmt" "strings" - "github.com/usual2970/certimate/internal/applicant" "github.com/usual2970/certimate/internal/deployer" "github.com/usual2970/certimate/internal/domain" "github.com/usual2970/certimate/internal/repository" @@ -28,7 +27,7 @@ func NewDeployNode(node *domain.WorkflowNode) *deployNode { func (d *deployNode) Run(ctx context.Context) error { d.AddOutput(ctx, d.node.Name, "开始执行") // 检查是否部署过(部署过则直接返回,和 v0.2 暂时保持一致) - output, err := d.outputRepo.Get(ctx, d.node.Id) + output, err := d.outputRepo.GetByNodeId(ctx, d.node.Id) if err != nil && !domain.IsRecordNotFound(err) { d.AddOutput(ctx, d.node.Name, "查询部署记录失败", err.Error()) return err @@ -43,7 +42,7 @@ func (d *deployNode) Run(ctx context.Context) error { return fmt.Errorf("证书来源配置错误: %s", certSource) } - cert, err := d.outputRepo.GetCertificate(ctx, certSourceSlice[0]) + cert, err := d.outputRepo.GetCertificateByNodeId(ctx, certSourceSlice[0]) if err != nil { d.AddOutput(ctx, d.node.Name, "获取证书失败", err.Error()) return err @@ -53,38 +52,15 @@ func (d *deployNode) Run(ctx context.Context) error { // 部署过但是证书更新了,重新部署 // 部署过且证书未更新,直接返回 - if d.deployed(output) && cert.Created.Before(output.Updated) { + if d.deployed(output) && cert.CreatedAt.Before(output.UpdatedAt) { d.AddOutput(ctx, d.node.Name, "已部署过且证书未更新") return nil } - accessRepo := repository.NewAccessRepository() - access, err := accessRepo.GetById(context.Background(), d.node.GetConfigString("access")) - if err != nil { - d.AddOutput(ctx, d.node.Name, "获取授权配置失败", err.Error()) - return err - } - option := &deployer.DeployerOption{ - DomainId: d.node.Id, - Domain: cert.SAN, - Access: access.Config, - AccessRecord: access, - Certificate: applicant.Certificate{ - CertUrl: cert.CertUrl, - CertStableUrl: cert.CertStableUrl, - PrivateKey: cert.PrivateKey, - Certificate: cert.Certificate, - IssuerCertificate: cert.IssuerCertificate, - }, - DeployConfig: domain.DeployConfig{ - Id: d.node.Id, - Access: access.Id, - Type: d.node.GetConfigString("providerType"), - Config: d.node.Config, - }, - } - - deploy, err := deployer.GetWithTypeAndOption(d.node.GetConfigString("providerType"), option) + deploy, err := deployer.NewWithDeployNode(d.node, struct { + Certificate string + PrivateKey string + }{Certificate: cert.Certificate, PrivateKey: cert.PrivateKey}) if err != nil { d.AddOutput(ctx, d.node.Name, "获取部署对象失败", err.Error()) return err @@ -104,11 +80,11 @@ func (d *deployNode) Run(ctx context.Context) error { outputId = output.Id } output = &domain.WorkflowOutput{ - Workflow: GetWorkflowId(ctx), - NodeId: d.node.Id, - Node: d.node, - Succeed: true, - Meta: domain.Meta{Id: outputId}, + Meta: domain.Meta{Id: outputId}, + WorkflowId: GetWorkflowId(ctx), + NodeId: d.node.Id, + Node: d.node, + Succeeded: true, } if err := d.outputRepo.Save(ctx, output, nil, nil); err != nil { @@ -122,5 +98,5 @@ func (d *deployNode) Run(ctx context.Context) error { } func (d *deployNode) deployed(output *domain.WorkflowOutput) bool { - return output != nil && output.Succeed + return output != nil && output.Succeeded } diff --git a/internal/workflow/node-processor/notify_node.go b/internal/workflow/node-processor/notify_node.go index 7fd92ec0..42d071b0 100644 --- a/internal/workflow/node-processor/notify_node.go +++ b/internal/workflow/node-processor/notify_node.go @@ -9,7 +9,7 @@ import ( ) type SettingRepository interface { - GetByName(ctx context.Context, name string) (*domain.Setting, error) + GetByName(ctx context.Context, name string) (*domain.Settings, error) } type notifyNode struct { node *domain.WorkflowNode @@ -21,7 +21,7 @@ func NewNotifyNode(node *domain.WorkflowNode) *notifyNode { return ¬ifyNode{ node: node, Logger: NewLogger(node), - settingRepo: repository.NewSettingRepository(), + settingRepo: repository.NewSettingsRepository(), } } @@ -35,14 +35,14 @@ func (n *notifyNode) Run(ctx context.Context) error { return err } - channelConfig, err := setting.GetChannelContent(n.node.GetConfigString("channel")) + channelConfig, err := setting.GetNotifyChannelConfig(n.node.GetConfigString("channel")) if err != nil { n.AddOutput(ctx, n.node.Name, "获取通知渠道配置失败", err.Error()) return err } - if err := notify.SendToChannel(n.node.GetConfigString("title"), - n.node.GetConfigString("content"), + if err := notify.SendToChannel(n.node.GetConfigString("subject"), + n.node.GetConfigString("message"), n.node.GetConfigString("channel"), channelConfig, ); err != nil { diff --git a/internal/workflow/node-processor/processor.go b/internal/workflow/node-processor/processor.go index e3a62297..fca0ee0a 100644 --- a/internal/workflow/node-processor/processor.go +++ b/internal/workflow/node-processor/processor.go @@ -3,37 +3,38 @@ package nodeprocessor import ( "context" "errors" + "time" "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/utils/xtime" ) type NodeProcessor interface { Run(ctx context.Context) error - Log(ctx context.Context) *domain.RunLog + Log(ctx context.Context) *domain.WorkflowRunLog AddOutput(ctx context.Context, title, content string, err ...string) } type Logger struct { - log *domain.RunLog + log *domain.WorkflowRunLog } func NewLogger(node *domain.WorkflowNode) *Logger { return &Logger{ - log: &domain.RunLog{ + log: &domain.WorkflowRunLog{ + NodeId: node.Id, NodeName: node.Name, - Outputs: make([]domain.RunLogOutput, 0), + Outputs: make([]domain.WorkflowRunLogOutput, 0), }, } } -func (l *Logger) Log(ctx context.Context) *domain.RunLog { +func (l *Logger) Log(ctx context.Context) *domain.WorkflowRunLog { return l.log } func (l *Logger) AddOutput(ctx context.Context, title, content string, err ...string) { - output := domain.RunLogOutput{ - Time: xtime.BeijingTimeStr(), + output := domain.WorkflowRunLogOutput{ + Time: time.Now().UTC().Format(time.RFC3339), Title: title, Content: content, } diff --git a/internal/workflow/node-processor/workflow_processor.go b/internal/workflow/node-processor/workflow_processor.go index 4602254f..20a53315 100644 --- a/internal/workflow/node-processor/workflow_processor.go +++ b/internal/workflow/node-processor/workflow_processor.go @@ -8,17 +8,17 @@ import ( type workflowProcessor struct { workflow *domain.Workflow - logs []domain.RunLog + logs []domain.WorkflowRunLog } func NewWorkflowProcessor(workflow *domain.Workflow) *workflowProcessor { return &workflowProcessor{ workflow: workflow, - logs: make([]domain.RunLog, 0), + logs: make([]domain.WorkflowRunLog, 0), } } -func (w *workflowProcessor) Log(ctx context.Context) []domain.RunLog { +func (w *workflowProcessor) Log(ctx context.Context) []domain.WorkflowRunLog { return w.logs } diff --git a/internal/workflow/service.go b/internal/workflow/service.go index 20510443..03bb8c80 100644 --- a/internal/workflow/service.go +++ b/internal/workflow/service.go @@ -3,15 +3,16 @@ package workflow import ( "context" "fmt" + "time" + "github.com/usual2970/certimate/internal/app" "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/utils/app" nodeprocessor "github.com/usual2970/certimate/internal/workflow/node-processor" ) type WorkflowRepository interface { - Get(ctx context.Context, id string) (*domain.Workflow, error) - SaveRunLog(ctx context.Context, log *domain.WorkflowRunLog) error + GetById(ctx context.Context, id string) (*domain.Workflow, error) + SaveRun(ctx context.Context, run *domain.WorkflowRun) error ListEnabledAuto(ctx context.Context) ([]domain.Workflow, error) } @@ -26,76 +27,74 @@ func NewWorkflowService(repo WorkflowRepository) *WorkflowService { } func (s *WorkflowService) InitSchedule(ctx context.Context) error { - // 查询所有的 enabled auto workflow workflows, err := s.repo.ListEnabledAuto(ctx) if err != nil { return err } + scheduler := app.GetScheduler() for _, workflow := range workflows { - err := scheduler.Add(workflow.Id, workflow.Crontab, func() { + err := scheduler.Add(fmt.Sprintf("workflow#%s", workflow.Id), workflow.TriggerCron, func() { s.Run(ctx, &domain.WorkflowRunReq{ - Id: workflow.Id, + WorkflowId: workflow.Id, + Trigger: domain.WorkflowTriggerTypeAuto, }) }) if err != nil { - app.GetApp().Logger().Error("failed to add schedule", "err", err) + app.GetLogger().Error("failed to add schedule", "err", err) return err } } scheduler.Start() - app.GetApp().Logger().Info("workflow schedule started") + + app.GetLogger().Info("workflow schedule started") + return nil } -func (s *WorkflowService) Run(ctx context.Context, req *domain.WorkflowRunReq) error { +func (s *WorkflowService) Run(ctx context.Context, options *domain.WorkflowRunReq) error { // 查询 - if req.Id == "" { - return domain.ErrInvalidParams - } - - workflow, err := s.repo.Get(ctx, req.Id) + workflow, err := s.repo.GetById(ctx, options.WorkflowId) if err != nil { - app.GetApp().Logger().Error("failed to get workflow", "id", req.Id, "err", err) + app.GetLogger().Error("failed to get workflow", "id", options.WorkflowId, "err", err) return err } // 执行 - if !workflow.Enabled { - app.GetApp().Logger().Error("workflow is disabled", "id", req.Id) - return fmt.Errorf("workflow is disabled") + run := &domain.WorkflowRun{ + WorkflowId: workflow.Id, + Status: domain.WorkflowRunStatusTypeRunning, + Trigger: options.Trigger, + StartedAt: time.Now(), + EndedAt: time.Now(), } - processor := nodeprocessor.NewWorkflowProcessor(workflow) if err := processor.Run(ctx); err != nil { - log := &domain.WorkflowRunLog{ - Workflow: workflow.Id, - Log: processor.Log(ctx), - Succeed: false, - Error: err.Error(), - } - if err := s.repo.SaveRunLog(ctx, log); err != nil { - app.GetApp().Logger().Error("failed to save run log", "err", err) + run.Status = domain.WorkflowRunStatusTypeFailed + run.EndedAt = time.Now() + run.Logs = processor.Log(ctx) + run.Error = err.Error() + + if err := s.repo.SaveRun(ctx, run); err != nil { + app.GetLogger().Error("failed to save workflow run", "err", err) } + return fmt.Errorf("failed to run workflow: %w", err) } - // 保存执行日志 + // 保存日志 logs := processor.Log(ctx) - runLogs := domain.RunLogs(logs) - runErr := runLogs.Error() - succeed := true - if runErr != "" { - succeed = false + runStatus := domain.WorkflowRunStatusTypeSucceeded + runError := domain.WorkflowRunLogs(logs).FirstError() + if runError != "" { + runStatus = domain.WorkflowRunStatusTypeFailed } - log := &domain.WorkflowRunLog{ - Workflow: workflow.Id, - Log: processor.Log(ctx), - Error: runErr, - Succeed: succeed, - } - if err := s.repo.SaveRunLog(ctx, log); err != nil { - app.GetApp().Logger().Error("failed to save run log", "err", err) + run.Status = runStatus + run.EndedAt = time.Now() + run.Logs = processor.Log(ctx) + run.Error = runError + if err := s.repo.SaveRun(ctx, run); err != nil { + app.GetLogger().Error("failed to save workflow run", "err", err) return err } diff --git a/main.go b/main.go index 7aa35221..b7885e39 100644 --- a/main.go +++ b/main.go @@ -6,20 +6,20 @@ import ( "os" "strings" + _ "time/tzdata" + "github.com/labstack/echo/v5" "github.com/labstack/echo/v5/middleware" "github.com/pocketbase/pocketbase/core" "github.com/pocketbase/pocketbase/plugins/migratecmd" - _ "github.com/usual2970/certimate/migrations" - + "github.com/usual2970/certimate/internal/app" "github.com/usual2970/certimate/internal/routes" "github.com/usual2970/certimate/internal/scheduler" - "github.com/usual2970/certimate/internal/utils/app" "github.com/usual2970/certimate/internal/workflow" "github.com/usual2970/certimate/ui" - _ "time/tzdata" + _ "github.com/usual2970/certimate/migrations" ) func main() { @@ -39,7 +39,7 @@ func main() { Automigrate: isGoRun, }) - workflow.AddEvent() + workflow.RegisterEvents() app.OnBeforeServe().Add(func(e *core.ServeEvent) error { routes.Register(e.Router) diff --git a/migrations/1734868882_updated_access.go b/migrations/1734868882_updated_access.go new file mode 100644 index 00000000..75dedc10 --- /dev/null +++ b/migrations/1734868882_updated_access.go @@ -0,0 +1,57 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models/schema" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("4yzbv8urny5ja1e") + if err != nil { + return err + } + + // remove + collection.Schema.RemoveField("c8egzzwj") + + return dao.SaveCollection(collection) + }, func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("4yzbv8urny5ja1e") + if err != nil { + return err + } + + // add + del_group := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "c8egzzwj", + "name": "group", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "teolp9pl72dxlxq", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }`), del_group); err != nil { + return err + } + collection.Schema.AddField(del_group) + + return dao.SaveCollection(collection) + }) +} diff --git a/migrations/1734869127_updated_domains.go b/migrations/1734869127_updated_domains.go new file mode 100644 index 00000000..f9575fa0 --- /dev/null +++ b/migrations/1734869127_updated_domains.go @@ -0,0 +1,57 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models/schema" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("z3p974ainxjqlvs") + if err != nil { + return err + } + + // remove + collection.Schema.RemoveField("1bspzuku") + + return dao.SaveCollection(collection) + }, func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("z3p974ainxjqlvs") + if err != nil { + return err + } + + // add + del_group := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "1bspzuku", + "name": "group", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "teolp9pl72dxlxq", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }`), del_group); err != nil { + return err + } + collection.Schema.AddField(del_group) + + return dao.SaveCollection(collection) + }) +} diff --git a/migrations/1734869146_updated_deployments.go b/migrations/1734869146_updated_deployments.go new file mode 100644 index 00000000..a1b31228 --- /dev/null +++ b/migrations/1734869146_updated_deployments.go @@ -0,0 +1,57 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models/schema" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("0a1o4e6sstp694f") + if err != nil { + return err + } + + // remove + collection.Schema.RemoveField("farvlzk7") + + return dao.SaveCollection(collection) + }, func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("0a1o4e6sstp694f") + if err != nil { + return err + } + + // add + del_domain := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "farvlzk7", + "name": "domain", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "z3p974ainxjqlvs", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }`), del_domain); err != nil { + return err + } + collection.Schema.AddField(del_domain) + + return dao.SaveCollection(collection) + }) +} diff --git a/migrations/1734869175_updated_domains.go b/migrations/1734869175_updated_domains.go new file mode 100644 index 00000000..1c89f58a --- /dev/null +++ b/migrations/1734869175_updated_domains.go @@ -0,0 +1,57 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models/schema" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("z3p974ainxjqlvs") + if err != nil { + return err + } + + // remove + collection.Schema.RemoveField("ghtlkn5j") + + return dao.SaveCollection(collection) + }, func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("z3p974ainxjqlvs") + if err != nil { + return err + } + + // add + del_lastDeployment := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "ghtlkn5j", + "name": "lastDeployment", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "0a1o4e6sstp694f", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }`), del_lastDeployment); err != nil { + return err + } + collection.Schema.AddField(del_lastDeployment) + + return dao.SaveCollection(collection) + }) +} diff --git a/migrations/1734869180_deleted_domains.go b/migrations/1734869180_deleted_domains.go new file mode 100644 index 00000000..af224651 --- /dev/null +++ b/migrations/1734869180_deleted_domains.go @@ -0,0 +1,337 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("z3p974ainxjqlvs") + if err != nil { + return err + } + + return dao.DeleteCollection(collection) + }, func(db dbx.Builder) error { + jsonData := `{ + "id": "z3p974ainxjqlvs", + "created": "2024-07-29 10:02:48.334Z", + "updated": "2024-12-22 12:06:15.156Z", + "name": "domains", + "type": "base", + "system": false, + "schema": [ + { + "system": false, + "id": "iuaerpl2", + "name": "domain", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }, + { + "system": false, + "id": "ukkhuw85", + "name": "email", + "type": "email", + "required": false, + "presentable": false, + "unique": false, + "options": { + "exceptDomains": null, + "onlyDomains": null + } + }, + { + "system": false, + "id": "v98eebqq", + "name": "crontab", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }, + { + "system": false, + "id": "alc8e9ow", + "name": "access", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "4yzbv8urny5ja1e", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }, + { + "system": false, + "id": "topsc9bj", + "name": "certUrl", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }, + { + "system": false, + "id": "vixgq072", + "name": "certStableUrl", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }, + { + "system": false, + "id": "g3a3sza5", + "name": "privateKey", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }, + { + "system": false, + "id": "gr6iouny", + "name": "certificate", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }, + { + "system": false, + "id": "tk6vnrmn", + "name": "issuerCertificate", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }, + { + "system": false, + "id": "sjo6ibse", + "name": "csr", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }, + { + "system": false, + "id": "x03n1bkj", + "name": "expiredAt", + "type": "date", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": "", + "max": "" + } + }, + { + "system": false, + "id": "srybpixz", + "name": "targetType", + "type": "select", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSelect": 1, + "values": [ + "aliyun-oss", + "aliyun-cdn", + "aliyun-dcdn", + "ssh", + "webhook", + "tencent-cdn", + "qiniu-cdn", + "local" + ] + } + }, + { + "system": false, + "id": "xy7yk0mb", + "name": "targetAccess", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "4yzbv8urny5ja1e", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }, + { + "system": false, + "id": "6jqeyggw", + "name": "enabled", + "type": "bool", + "required": false, + "presentable": false, + "unique": false, + "options": {} + }, + { + "system": false, + "id": "hdsjcchf", + "name": "deployed", + "type": "bool", + "required": false, + "presentable": false, + "unique": false, + "options": {} + }, + { + "system": false, + "id": "aiya3rev", + "name": "rightnow", + "type": "bool", + "required": false, + "presentable": false, + "unique": false, + "options": {} + }, + { + "system": false, + "id": "ixznmhzc", + "name": "lastDeployedAt", + "type": "date", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": "", + "max": "" + } + }, + { + "system": false, + "id": "zfnyj9he", + "name": "variables", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }, + { + "system": false, + "id": "g65gfh7a", + "name": "nameservers", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }, + { + "system": false, + "id": "wwrzc3jo", + "name": "applyConfig", + "type": "json", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSize": 2000000 + } + }, + { + "system": false, + "id": "474iwy8r", + "name": "deployConfig", + "type": "json", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSize": 2000000 + } + } + ], + "indexes": [ + "CREATE UNIQUE INDEX ` + "`" + `idx_4ABO6EQ` + "`" + ` ON ` + "`" + `domains` + "`" + ` (` + "`" + `domain` + "`" + `)" + ], + "listRule": null, + "viewRule": null, + "createRule": null, + "updateRule": null, + "deleteRule": null, + "options": {} + }` + + collection := &models.Collection{} + if err := json.Unmarshal([]byte(jsonData), &collection); err != nil { + return err + } + + return daos.New(db).SaveCollection(collection) + }) +} diff --git a/migrations/1734869185_deleted_deployments.go b/migrations/1734869185_deleted_deployments.go new file mode 100644 index 00000000..5b7ab42a --- /dev/null +++ b/migrations/1734869185_deleted_deployments.go @@ -0,0 +1,110 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("0a1o4e6sstp694f") + if err != nil { + return err + } + + return dao.DeleteCollection(collection) + }, func(db dbx.Builder) error { + jsonData := `{ + "id": "0a1o4e6sstp694f", + "created": "2024-07-30 06:30:27.801Z", + "updated": "2024-12-22 12:05:46.060Z", + "name": "deployments", + "type": "base", + "system": false, + "schema": [ + { + "system": false, + "id": "jx5f69i3", + "name": "log", + "type": "json", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSize": 2000000 + } + }, + { + "system": false, + "id": "qbxdtg9q", + "name": "phase", + "type": "select", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSelect": 1, + "values": [ + "check", + "apply", + "deploy" + ] + } + }, + { + "system": false, + "id": "rglrp1hz", + "name": "phaseSuccess", + "type": "bool", + "required": false, + "presentable": false, + "unique": false, + "options": {} + }, + { + "system": false, + "id": "lt1g1blu", + "name": "deployedAt", + "type": "date", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": "", + "max": "" + } + }, + { + "system": false, + "id": "wledpzgb", + "name": "wholeSuccess", + "type": "bool", + "required": false, + "presentable": false, + "unique": false, + "options": {} + } + ], + "indexes": [], + "listRule": null, + "viewRule": null, + "createRule": null, + "updateRule": null, + "deleteRule": null, + "options": {} + }` + + collection := &models.Collection{} + if err := json.Unmarshal([]byte(jsonData), &collection); err != nil { + return err + } + + return daos.New(db).SaveCollection(collection) + }) +} diff --git a/migrations/1734869190_deleted_access_groups.go b/migrations/1734869190_deleted_access_groups.go new file mode 100644 index 00000000..6e423d88 --- /dev/null +++ b/migrations/1734869190_deleted_access_groups.go @@ -0,0 +1,80 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("teolp9pl72dxlxq") + if err != nil { + return err + } + + return dao.DeleteCollection(collection) + }, func(db dbx.Builder) error { + jsonData := `{ + "id": "teolp9pl72dxlxq", + "created": "2024-09-13 12:51:05.611Z", + "updated": "2024-11-25 07:41:10.235Z", + "name": "access_groups", + "type": "base", + "system": false, + "schema": [ + { + "system": false, + "id": "7sajiv6i", + "name": "name", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }, + { + "system": false, + "id": "xp8admif", + "name": "access", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "4yzbv8urny5ja1e", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": null, + "displayFields": null + } + } + ], + "indexes": [ + "CREATE UNIQUE INDEX ` + "`" + `idx_RgRXp0R` + "`" + ` ON ` + "`" + `access_groups` + "`" + ` (` + "`" + `name` + "`" + `)" + ], + "listRule": null, + "viewRule": null, + "createRule": null, + "updateRule": null, + "deleteRule": null, + "options": {} + }` + + collection := &models.Collection{} + if err := json.Unmarshal([]byte(jsonData), &collection); err != nil { + return err + } + + return daos.New(db).SaveCollection(collection) + }) +} diff --git a/migrations/1735151867_updated_access.go b/migrations/1735151867_updated_access.go new file mode 100644 index 00000000..4dfdef1a --- /dev/null +++ b/migrations/1735151867_updated_access.go @@ -0,0 +1,110 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models/schema" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("4yzbv8urny5ja1e") + if err != nil { + return err + } + + // update + edit_configType := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "hwy7m03o", + "name": "configType", + "type": "select", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSelect": 1, + "values": [ + "acmehttpreq", + "aliyun", + "aws", + "baiducloud", + "byteplus", + "cloudflare", + "dogecloud", + "godaddy", + "huaweicloud", + "k8s", + "local", + "namedotcom", + "namesilo", + "powerdns", + "qiniu", + "ssh", + "tencentcloud", + "volcengine", + "webhook" + ] + } + }`), edit_configType); err != nil { + return err + } + collection.Schema.AddField(edit_configType) + + return dao.SaveCollection(collection) + }, func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("4yzbv8urny5ja1e") + if err != nil { + return err + } + + // update + edit_configType := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "hwy7m03o", + "name": "configType", + "type": "select", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSelect": 1, + "values": [ + "aliyun", + "tencent", + "huaweicloud", + "qiniu", + "aws", + "cloudflare", + "namesilo", + "godaddy", + "pdns", + "httpreq", + "local", + "ssh", + "webhook", + "k8s", + "baiducloud", + "dogecloud", + "volcengine", + "byteplus", + "namedotcom" + ] + } + }`), edit_configType); err != nil { + return err + } + collection.Schema.AddField(edit_configType) + + return dao.SaveCollection(collection) + }) +} diff --git a/migrations/1735913237_updated_access.go b/migrations/1735913237_updated_access.go new file mode 100644 index 00000000..047028cb --- /dev/null +++ b/migrations/1735913237_updated_access.go @@ -0,0 +1,110 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models/schema" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("4yzbv8urny5ja1e") + if err != nil { + return err + } + + // update + edit_provider := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "hwy7m03o", + "name": "provider", + "type": "select", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSelect": 1, + "values": [ + "acmehttpreq", + "aliyun", + "aws", + "baiducloud", + "byteplus", + "cloudflare", + "dogecloud", + "godaddy", + "huaweicloud", + "k8s", + "local", + "namedotcom", + "namesilo", + "powerdns", + "qiniu", + "ssh", + "tencentcloud", + "volcengine", + "webhook" + ] + } + }`), edit_provider); err != nil { + return err + } + collection.Schema.AddField(edit_provider) + + return dao.SaveCollection(collection) + }, func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("4yzbv8urny5ja1e") + if err != nil { + return err + } + + // update + edit_provider := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "hwy7m03o", + "name": "configType", + "type": "select", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSelect": 1, + "values": [ + "acmehttpreq", + "aliyun", + "aws", + "baiducloud", + "byteplus", + "cloudflare", + "dogecloud", + "godaddy", + "huaweicloud", + "k8s", + "local", + "namedotcom", + "namesilo", + "powerdns", + "qiniu", + "ssh", + "tencentcloud", + "volcengine", + "webhook" + ] + } + }`), edit_provider); err != nil { + return err + } + collection.Schema.AddField(edit_provider) + + return dao.SaveCollection(collection) + }) +} diff --git a/migrations/1735966817_updated_workflow.go b/migrations/1735966817_updated_workflow.go new file mode 100644 index 00000000..6d714a0b --- /dev/null +++ b/migrations/1735966817_updated_workflow.go @@ -0,0 +1,116 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models/schema" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("tovyif5ax6j62ur") + if err != nil { + return err + } + + // update + edit_trigger := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "vqoajwjq", + "name": "trigger", + "type": "select", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSelect": 1, + "values": [ + "auto", + "manual" + ] + } + }`), edit_trigger); err != nil { + return err + } + collection.Schema.AddField(edit_trigger) + + // update + edit_triggerCron := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "8ho247wh", + "name": "triggerCron", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }`), edit_triggerCron); err != nil { + return err + } + collection.Schema.AddField(edit_triggerCron) + + return dao.SaveCollection(collection) + }, func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("tovyif5ax6j62ur") + if err != nil { + return err + } + + // update + edit_trigger := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "vqoajwjq", + "name": "type", + "type": "select", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSelect": 1, + "values": [ + "auto", + "manual" + ] + } + }`), edit_trigger); err != nil { + return err + } + collection.Schema.AddField(edit_trigger) + + // update + edit_triggerCron := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "8ho247wh", + "name": "crontab", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }`), edit_triggerCron); err != nil { + return err + } + collection.Schema.AddField(edit_triggerCron) + + return dao.SaveCollection(collection) + }) +} diff --git a/migrations/1735976342_updated_certificate.go b/migrations/1735976342_updated_certificate.go new file mode 100644 index 00000000..2537f86c --- /dev/null +++ b/migrations/1735976342_updated_certificate.go @@ -0,0 +1,298 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models/schema" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("4szxr9x43tpj6np") + if err != nil { + return err + } + + // add + new_effectAt := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "v40aqzpd", + "name": "effectAt", + "type": "date", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": "", + "max": "" + } + }`), new_effectAt); err != nil { + return err + } + collection.Schema.AddField(new_effectAt) + + // update + edit_subjectAltNames := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "fugxf58p", + "name": "subjectAltNames", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }`), edit_subjectAltNames); err != nil { + return err + } + collection.Schema.AddField(edit_subjectAltNames) + + // update + edit_acmeCertUrl := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "ayyjy5ve", + "name": "acmeCertUrl", + "type": "url", + "required": false, + "presentable": false, + "unique": false, + "options": { + "exceptDomains": null, + "onlyDomains": null + } + }`), edit_acmeCertUrl); err != nil { + return err + } + collection.Schema.AddField(edit_acmeCertUrl) + + // update + edit_acmeCertStableUrl := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "3x5heo8e", + "name": "acmeCertStableUrl", + "type": "url", + "required": false, + "presentable": false, + "unique": false, + "options": { + "exceptDomains": null, + "onlyDomains": null + } + }`), edit_acmeCertStableUrl); err != nil { + return err + } + collection.Schema.AddField(edit_acmeCertStableUrl) + + // update + edit_workflowId := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "uvqfamb1", + "name": "workflowId", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "tovyif5ax6j62ur", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }`), edit_workflowId); err != nil { + return err + } + collection.Schema.AddField(edit_workflowId) + + // update + edit_workflowNodeId := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "uqldzldw", + "name": "workflowNodeId", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }`), edit_workflowNodeId); err != nil { + return err + } + collection.Schema.AddField(edit_workflowNodeId) + + // update + edit_workflowOutputId := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "2ohlr0yd", + "name": "workflowOutputId", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "bqnxb95f2cooowp", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }`), edit_workflowOutputId); err != nil { + return err + } + collection.Schema.AddField(edit_workflowOutputId) + + return dao.SaveCollection(collection) + }, func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("4szxr9x43tpj6np") + if err != nil { + return err + } + + // remove + collection.Schema.RemoveField("v40aqzpd") + + // update + edit_subjectAltNames := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "fugxf58p", + "name": "san", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }`), edit_subjectAltNames); err != nil { + return err + } + collection.Schema.AddField(edit_subjectAltNames) + + // update + edit_acmeCertUrl := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "ayyjy5ve", + "name": "certUrl", + "type": "url", + "required": false, + "presentable": false, + "unique": false, + "options": { + "exceptDomains": null, + "onlyDomains": null + } + }`), edit_acmeCertUrl); err != nil { + return err + } + collection.Schema.AddField(edit_acmeCertUrl) + + // update + edit_acmeCertStableUrl := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "3x5heo8e", + "name": "certStableUrl", + "type": "url", + "required": false, + "presentable": false, + "unique": false, + "options": { + "exceptDomains": null, + "onlyDomains": null + } + }`), edit_acmeCertStableUrl); err != nil { + return err + } + collection.Schema.AddField(edit_acmeCertStableUrl) + + // update + edit_workflowId := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "uvqfamb1", + "name": "workflow", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "tovyif5ax6j62ur", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }`), edit_workflowId); err != nil { + return err + } + collection.Schema.AddField(edit_workflowId) + + // update + edit_workflowNodeId := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "uqldzldw", + "name": "nodeId", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }`), edit_workflowNodeId); err != nil { + return err + } + collection.Schema.AddField(edit_workflowNodeId) + + // update + edit_workflowOutputId := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "2ohlr0yd", + "name": "output", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "bqnxb95f2cooowp", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }`), edit_workflowOutputId); err != nil { + return err + } + collection.Schema.AddField(edit_workflowOutputId) + + return dao.SaveCollection(collection) + }) +} diff --git a/migrations/1735977005_updated_workflow_output.go b/migrations/1735977005_updated_workflow_output.go new file mode 100644 index 00000000..26795e2e --- /dev/null +++ b/migrations/1735977005_updated_workflow_output.go @@ -0,0 +1,144 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models/schema" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("bqnxb95f2cooowp") + if err != nil { + return err + } + + // update + edit_workflowId := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "jka88auc", + "name": "workflowId", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "tovyif5ax6j62ur", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }`), edit_workflowId); err != nil { + return err + } + collection.Schema.AddField(edit_workflowId) + + // update + edit_outputs := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "he4cceqb", + "name": "outputs", + "type": "json", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSize": 2000000 + } + }`), edit_outputs); err != nil { + return err + } + collection.Schema.AddField(edit_outputs) + + // update + edit_succeeded := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "2yfxbxuf", + "name": "succeeded", + "type": "bool", + "required": false, + "presentable": false, + "unique": false, + "options": {} + }`), edit_succeeded); err != nil { + return err + } + collection.Schema.AddField(edit_succeeded) + + return dao.SaveCollection(collection) + }, func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("bqnxb95f2cooowp") + if err != nil { + return err + } + + // update + edit_workflowId := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "jka88auc", + "name": "workflow", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "tovyif5ax6j62ur", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }`), edit_workflowId); err != nil { + return err + } + collection.Schema.AddField(edit_workflowId) + + // update + edit_outputs := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "he4cceqb", + "name": "output", + "type": "json", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSize": 2000000 + } + }`), edit_outputs); err != nil { + return err + } + collection.Schema.AddField(edit_outputs) + + // update + edit_succeeded := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "2yfxbxuf", + "name": "succeed", + "type": "bool", + "required": false, + "presentable": false, + "unique": false, + "options": {} + }`), edit_succeeded); err != nil { + return err + } + collection.Schema.AddField(edit_succeeded) + + return dao.SaveCollection(collection) + }) +} diff --git a/migrations/1735977021_updated_workflow_run_log.go b/migrations/1735977021_updated_workflow_run_log.go new file mode 100644 index 00000000..1cafab81 --- /dev/null +++ b/migrations/1735977021_updated_workflow_run_log.go @@ -0,0 +1,144 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models/schema" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("qjp8lygssgwyqyz") + if err != nil { + return err + } + + // update + edit_workflowId := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "m8xfsyyy", + "name": "workflowId", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "tovyif5ax6j62ur", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }`), edit_workflowId); err != nil { + return err + } + collection.Schema.AddField(edit_workflowId) + + // update + edit_logs := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "2m9byaa9", + "name": "logs", + "type": "json", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSize": 2000000 + } + }`), edit_logs); err != nil { + return err + } + collection.Schema.AddField(edit_logs) + + // update + edit_succeeded := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "cht6kqw9", + "name": "succeeded", + "type": "bool", + "required": false, + "presentable": false, + "unique": false, + "options": {} + }`), edit_succeeded); err != nil { + return err + } + collection.Schema.AddField(edit_succeeded) + + return dao.SaveCollection(collection) + }, func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("qjp8lygssgwyqyz") + if err != nil { + return err + } + + // update + edit_workflowId := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "m8xfsyyy", + "name": "workflow", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "tovyif5ax6j62ur", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }`), edit_workflowId); err != nil { + return err + } + collection.Schema.AddField(edit_workflowId) + + // update + edit_logs := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "2m9byaa9", + "name": "log", + "type": "json", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSize": 2000000 + } + }`), edit_logs); err != nil { + return err + } + collection.Schema.AddField(edit_logs) + + // update + edit_succeeded := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "cht6kqw9", + "name": "succeed", + "type": "bool", + "required": false, + "presentable": false, + "unique": false, + "options": {} + }`), edit_succeeded); err != nil { + return err + } + collection.Schema.AddField(edit_succeeded) + + return dao.SaveCollection(collection) + }) +} diff --git a/migrations/1735977530_updated_certificate.go b/migrations/1735977530_updated_certificate.go new file mode 100644 index 00000000..8812c593 --- /dev/null +++ b/migrations/1735977530_updated_certificate.go @@ -0,0 +1,57 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models/schema" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("4szxr9x43tpj6np") + if err != nil { + return err + } + + // add + new_source := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "by9hetqi", + "name": "source", + "type": "select", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSelect": 1, + "values": [ + "workflow", + "upload" + ] + } + }`), new_source); err != nil { + return err + } + collection.Schema.AddField(new_source) + + return dao.SaveCollection(collection) + }, func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("4szxr9x43tpj6np") + if err != nil { + return err + } + + // remove + collection.Schema.RemoveField("by9hetqi") + + return dao.SaveCollection(collection) + }) +} diff --git a/migrations/1735980691_updated_workflow_run_log.go b/migrations/1735980691_updated_workflow_run_log.go new file mode 100644 index 00000000..03117dc8 --- /dev/null +++ b/migrations/1735980691_updated_workflow_run_log.go @@ -0,0 +1,105 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models/schema" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("qjp8lygssgwyqyz") + if err != nil { + return err + } + + collection.Name = "workflow_run" + + // add + new_trigger := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "jlroa3fk", + "name": "trigger", + "type": "select", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSelect": 1, + "values": [ + "auto", + "manual" + ] + } + }`), new_trigger); err != nil { + return err + } + collection.Schema.AddField(new_trigger) + + // add + new_startedAt := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "k9xvtf89", + "name": "startedAt", + "type": "date", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": "", + "max": "" + } + }`), new_startedAt); err != nil { + return err + } + collection.Schema.AddField(new_startedAt) + + // add + new_endedAt := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "3ikum7mk", + "name": "endedAt", + "type": "date", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": "", + "max": "" + } + }`), new_endedAt); err != nil { + return err + } + collection.Schema.AddField(new_endedAt) + + return dao.SaveCollection(collection) + }, func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("qjp8lygssgwyqyz") + if err != nil { + return err + } + + collection.Name = "workflow_run_log" + + // remove + collection.Schema.RemoveField("jlroa3fk") + + // remove + collection.Schema.RemoveField("k9xvtf89") + + // remove + collection.Schema.RemoveField("3ikum7mk") + + return dao.SaveCollection(collection) + }) +} diff --git a/migrations/1735981441_updated_workflow.go b/migrations/1735981441_updated_workflow.go new file mode 100644 index 00000000..051945f2 --- /dev/null +++ b/migrations/1735981441_updated_workflow.go @@ -0,0 +1,106 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models/schema" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("tovyif5ax6j62ur") + if err != nil { + return err + } + + // add + new_lastRunId := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "a23wkj9x", + "name": "lastRunId", + "type": "relation", + "required": false, + "presentable": false, + "unique": false, + "options": { + "collectionId": "qjp8lygssgwyqyz", + "cascadeDelete": false, + "minSelect": null, + "maxSelect": 1, + "displayFields": null + } + }`), new_lastRunId); err != nil { + return err + } + collection.Schema.AddField(new_lastRunId) + + // add + new_lastRunStatus := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "zivdxh23", + "name": "lastRunStatus", + "type": "select", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSelect": 1, + "values": [ + "pending", + "running", + "succeeded", + "failed" + ] + } + }`), new_lastRunStatus); err != nil { + return err + } + collection.Schema.AddField(new_lastRunStatus) + + // add + new_lastRunTime := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "u9bosu36", + "name": "lastRunTime", + "type": "date", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": "", + "max": "" + } + }`), new_lastRunTime); err != nil { + return err + } + collection.Schema.AddField(new_lastRunTime) + + return dao.SaveCollection(collection) + }, func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("tovyif5ax6j62ur") + if err != nil { + return err + } + + // remove + collection.Schema.RemoveField("a23wkj9x") + + // remove + collection.Schema.RemoveField("zivdxh23") + + // remove + collection.Schema.RemoveField("u9bosu36") + + return dao.SaveCollection(collection) + }) +} diff --git a/migrations/1735981515_updated_workflow_run.go b/migrations/1735981515_updated_workflow_run.go new file mode 100644 index 00000000..c649cd04 --- /dev/null +++ b/migrations/1735981515_updated_workflow_run.go @@ -0,0 +1,78 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models/schema" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("qjp8lygssgwyqyz") + if err != nil { + return err + } + + // remove + collection.Schema.RemoveField("cht6kqw9") + + // add + new_status := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "qldmh0tw", + "name": "status", + "type": "select", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSelect": 1, + "values": [ + "pending", + "running", + "succeeded", + "failed" + ] + } + }`), new_status); err != nil { + return err + } + collection.Schema.AddField(new_status) + + return dao.SaveCollection(collection) + }, func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("qjp8lygssgwyqyz") + if err != nil { + return err + } + + // add + del_succeeded := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "cht6kqw9", + "name": "succeeded", + "type": "bool", + "required": false, + "presentable": false, + "unique": false, + "options": {} + }`), del_succeeded); err != nil { + return err + } + collection.Schema.AddField(del_succeeded) + + // remove + collection.Schema.RemoveField("qldmh0tw") + + return dao.SaveCollection(collection) + }) +} diff --git a/ui/.eslintrc.cjs b/ui/.eslintrc.cjs index a2faf5ac..6bd9b5fd 100644 --- a/ui/.eslintrc.cjs +++ b/ui/.eslintrc.cjs @@ -8,11 +8,26 @@ module.exports = { node: true, es2020: true, }, - extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended", "plugin:react-hooks/recommended"], + extends: [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:import/recommended", + "plugin:import/typescript", + "plugin:prettier/recommended", + "plugin:react-hooks/recommended", + "plugin:tailwindcss/recommended", + ], ignorePatterns: ["dist", ".eslintrc.cjs"], parser: "@typescript-eslint/parser", plugins: ["react-refresh"], rules: { + "@typescript-eslint/consistent-type-imports": "error", + "@typescript-eslint/no-empty-object-type": [ + "error", + { + allowInterfaces: "with-single-extends", + }, + ], "@typescript-eslint/no-explicit-any": [ "warn", { @@ -28,11 +43,69 @@ module.exports = { varsIgnorePattern: "^_", }, ], + "import/no-named-as-default-member": "off", + "import/no-unresolved": "off", + "import/order": [ + "error", + { + groups: ["builtin", "external", "internal", ["parent", "sibling"], "index"], + pathGroups: [ + { + pattern: "react*", + group: "external", + position: "before", + }, + { + pattern: "react/**", + group: "external", + position: "before", + }, + { + pattern: "react-*", + group: "external", + position: "before", + }, + { + pattern: "react-*/**", + group: "external", + position: "before", + }, + { + pattern: "~/**", + group: "external", + position: "after", + }, + { + pattern: "@/**", + group: "internal", + position: "before", + }, + ], + pathGroupsExcludedImportTypes: ["builtin"], + alphabetize: { + order: "asc", + }, + }, + ], "react-refresh/only-export-components": [ "warn", { allowConstantExport: true, }, ], + "sort-imports": [ + "error", + { + ignoreDeclarationSort: true, + }, + ], + "tailwindcss/no-custom-classname": "off", + }, + settings: { + "import/resolver": { + node: { + extensions: [".js", ".jsx", ".ts", ".tsx"], + }, + }, }, }; diff --git a/ui/dist/.gitkeep b/ui/dist/.gitkeep deleted file mode 100644 index 5f282702..00000000 --- a/ui/dist/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ui/index.html b/ui/index.html index 4a71aab8..fe1c7f6b 100644 --- a/ui/index.html +++ b/ui/index.html @@ -6,7 +6,7 @@ Certimate - Your Trusted SSL Automation Partner - +
diff --git a/ui/package-lock.json b/ui/package-lock.json index e286c84d..57e6696d 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -8,68 +8,61 @@ "name": "ui", "version": "0.0.0", "dependencies": { + "@ant-design/icons": "^5.5.2", "@ant-design/pro-components": "^2.8.2", - "@hookform/resolvers": "^3.9.0", - "@radix-ui/react-dialog": "^1.1.2", - "@radix-ui/react-dropdown-menu": "^2.1.1", - "@radix-ui/react-label": "^2.1.0", - "@radix-ui/react-scroll-area": "^1.1.0", - "@radix-ui/react-select": "^2.1.1", - "@radix-ui/react-slot": "^1.1.0", - "@tanstack/react-table": "^8.20.5", "ahooks": "^3.8.4", - "antd": "^5.22.2", + "antd": "^5.22.7", "antd-zod": "^6.0.0", - "class-variance-authority": "^0.7.0", - "clsx": "^2.1.1", "cron-parser": "^4.9.0", - "i18next": "^23.15.1", - "i18next-browser-languagedetector": "^8.0.0", - "i18next-http-backend": "^2.6.1", + "i18next": "^24.2.0", + "i18next-browser-languagedetector": "^8.0.2", "immer": "^10.1.1", "jszip": "^3.10.1", - "lucide-react": "^0.417.0", - "nanoid": "^5.0.7", - "pocketbase": "^0.21.4", + "lucide-react": "^0.469.0", + "nanoid": "^5.0.9", + "pocketbase": "^0.21.5", + "radash": "^12.1.0", "react": "^18.3.1", "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.3.1", - "react-hook-form": "^7.52.1", - "react-i18next": "^15.0.2", - "react-router-dom": "^6.25.1", - "tailwind-merge": "^2.4.0", - "tailwindcss-animate": "^1.0.7", - "zod": "^3.23.8", - "zustand": "^5.0.1" + "react-i18next": "^15.4.0", + "react-router-dom": "^7.1.1", + "zod": "^3.24.1", + "zustand": "^5.0.2" }, "devDependencies": { "@types/fs-extra": "^11.0.4", - "@types/node": "^22.0.0", - "@types/react": "^18.3.3", + "@types/node": "^22.10.3", + "@types/react": "^18.3.12", "@types/react-copy-to-clipboard": "^5.0.7", - "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^7.15.0", - "@typescript-eslint/parser": "^7.15.0", - "@vitejs/plugin-legacy": "^5.4.3", - "@vitejs/plugin-react": "^4.3.1", - "autoprefixer": "^10.4.19", + "@types/react-dom": "^18.3.1", + "@typescript-eslint/eslint-plugin": "^8.19.0", + "@typescript-eslint/parser": "^8.19.0", + "@vitejs/plugin-legacy": "^6.0.0", + "@vitejs/plugin-react": "^4.3.4", + "autoprefixer": "^10.4.20", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.7.0", + "eslint-plugin-import": "^2.31.0", "eslint-plugin-prettier": "^5.2.1", - "eslint-plugin-react-hooks": "^4.6.2", - "eslint-plugin-react-refresh": "^0.4.7", + "eslint-plugin-react-hooks": "^5.1.0", + "eslint-plugin-react-refresh": "^0.4.16", + "eslint-plugin-tailwindcss": "^3.17.5", "fs-extra": "^11.2.0", - "postcss": "^8.4.40", - "prettier": "^3.3.3", - "tailwindcss": "^3.4.7", - "typescript": "^5.6.2", - "vite": "^5.3.4" + "postcss": "^8.4.49", + "prettier": "^3.4.2", + "tailwindcss": "^3.4.17", + "tailwindcss-animate": "^1.0.7", + "typescript": "^5.7.2", + "vite": "^6.0.6" } }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmmirror.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, "engines": { "node": ">=10" }, @@ -117,9 +110,9 @@ } }, "node_modules/@ant-design/cssinjs-utils": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/@ant-design/cssinjs-utils/-/cssinjs-utils-1.1.1.tgz", - "integrity": "sha512-2HAiyGGGnM0es40SxdszeQAU5iWp41wBIInq+ONTCKjlSKOrzQfnw4JDtB8IBmqE6tQaEKwmzTP2LGdt5DSwYQ==", + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/@ant-design/cssinjs-utils/-/cssinjs-utils-1.1.3.tgz", + "integrity": "sha512-nOoQMLW1l+xR1Co8NFVYiP8pZp3VjIIzqV6D6ShYF2ljtdwWJn5WSsH+7kvCktXL/yhEtWURKOfH5Xz/gzlwsg==", "dependencies": { "@ant-design/cssinjs": "^1.21.0", "@babel/runtime": "^7.23.2", @@ -142,9 +135,9 @@ } }, "node_modules/@ant-design/icons": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@ant-design/icons/-/icons-5.5.1.tgz", - "integrity": "sha512-0UrM02MA2iDIgvLatWrj6YTCYe0F/cwXvVE0E2SqGrL7PZireQwgEKTKBisWpZyal5eXZLvuM98kju6YtYne8w==", + "version": "5.5.2", + "resolved": "https://registry.npmmirror.com/@ant-design/icons/-/icons-5.5.2.tgz", + "integrity": "sha512-xc53rjVBl9v2BqFxUjZGti/RfdDeA8/6KYglmInM2PNqSXc/WfuGDTifJI/ZsokJK0aeKvOIbXc9y2g8ILAhEA==", "dependencies": { "@ant-design/colors": "^7.0.0", "@ant-design/icons-svg": "^4.4.0", @@ -1566,12 +1559,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.24.7", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz", - "integrity": "sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==", + "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==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1581,12 +1574,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.24.7", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz", - "integrity": "sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==", + "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==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2036,9 +2029,9 @@ "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", "cpu": [ "ppc64" ], @@ -2048,13 +2041,13 @@ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.24.2.tgz", + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", "cpu": [ "arm" ], @@ -2064,13 +2057,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", "cpu": [ "arm64" ], @@ -2080,13 +2073,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.24.2.tgz", + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", "cpu": [ "x64" ], @@ -2096,13 +2089,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", "cpu": [ "arm64" ], @@ -2112,13 +2105,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", "cpu": [ "x64" ], @@ -2128,13 +2121,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", "cpu": [ "arm64" ], @@ -2144,13 +2137,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", "cpu": [ "x64" ], @@ -2160,13 +2153,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", "cpu": [ "arm" ], @@ -2176,13 +2169,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", "cpu": [ "arm64" ], @@ -2192,13 +2185,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", "cpu": [ "ia32" ], @@ -2208,13 +2201,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", "cpu": [ "loong64" ], @@ -2224,13 +2217,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", "cpu": [ "mips64el" ], @@ -2240,13 +2233,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", "cpu": [ "ppc64" ], @@ -2256,13 +2249,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", "cpu": [ "riscv64" ], @@ -2272,13 +2265,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", "cpu": [ "s390x" ], @@ -2288,13 +2281,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", "cpu": [ "x64" ], @@ -2304,13 +2297,29 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", + "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", "cpu": [ "x64" ], @@ -2320,13 +2329,29 @@ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", "cpu": [ "x64" ], @@ -2336,13 +2361,13 @@ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", "cpu": [ "x64" ], @@ -2352,13 +2377,13 @@ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", "cpu": [ "arm64" ], @@ -2368,13 +2393,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", "cpu": [ "ia32" ], @@ -2384,13 +2409,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", "cpu": [ "x64" ], @@ -2400,7 +2425,7 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { @@ -2496,48 +2521,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@floating-ui/core": { - "version": "1.6.5", - "resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.6.5.tgz", - "integrity": "sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA==", - "dependencies": { - "@floating-ui/utils": "^0.2.5" - } - }, - "node_modules/@floating-ui/dom": { - "version": "1.6.8", - "resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.6.8.tgz", - "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==", - "dependencies": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.5" - } - }, - "node_modules/@floating-ui/react-dom": { - "version": "2.1.1", - "resolved": "https://registry.npmmirror.com/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", - "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", - "dependencies": { - "@floating-ui/dom": "^1.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@floating-ui/utils": { - "version": "0.2.5", - "resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.5.tgz", - "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==" - }, - "node_modules/@hookform/resolvers": { - "version": "3.9.0", - "resolved": "https://registry.npmmirror.com/@hookform/resolvers/-/resolvers-3.9.0.tgz", - "integrity": "sha512-bU0Gr4EepJ/EQsH/IwEzYLsT/PEj5C0ynLQ4m+GSHS+xKH4TfSelhluTgOaoc4kA5s7eCsQbM4wvZLzELmWzUg==", - "peerDependencies": { - "react-hook-form": "^7.0.0" - } - }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmmirror.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -2595,6 +2578,7 @@ "version": "8.0.2", "resolved": "https://registry.npmmirror.com/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -2611,6 +2595,7 @@ "version": "6.0.1", "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, "engines": { "node": ">=12" }, @@ -2622,6 +2607,7 @@ "version": "7.1.0", "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -2636,6 +2622,7 @@ "version": "0.3.5", "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -2649,6 +2636,7 @@ "version": "3.1.2", "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -2657,6 +2645,7 @@ "version": "1.2.1", "resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -2675,12 +2664,14 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -2690,6 +2681,7 @@ "version": "2.1.5", "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -2702,6 +2694,7 @@ "version": "2.0.5", "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, "engines": { "node": ">= 8" } @@ -2710,6 +2703,7 @@ "version": "1.2.8", "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -2718,10 +2712,20 @@ "node": ">= 8" } }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmmirror.com/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "engines": { + "node": ">=12.4.0" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, "optional": true, "engines": { "node": ">=14" @@ -2739,789 +2743,6 @@ "url": "https://opencollective.com/unts" } }, - "node_modules/@radix-ui/number": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/number/-/number-1.1.0.tgz", - "integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==" - }, - "node_modules/@radix-ui/primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/primitive/-/primitive-1.1.0.tgz", - "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" - }, - "node_modules/@radix-ui/react-arrow": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", - "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-collection": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", - "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", - "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-context": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-context/-/react-context-1.1.0.tgz", - "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dialog": { - "version": "1.1.2", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-dialog/-/react-dialog-1.1.2.tgz", - "integrity": "sha512-Yj4dZtqa2o+kG61fzB0H2qUvmwBA2oyQroGLyNtBj1beo1khoQ3q1a2AO8rrQYjd8256CO9+N8L9tvsS+bnIyA==", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.1", - "@radix-ui/react-focus-guards": "1.1.1", - "@radix-ui/react-focus-scope": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-portal": "1.1.2", - "@radix-ui/react-presence": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.6.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-context": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-context/-/react-context-1.1.1.tgz", - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz", - "integrity": "sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-escape-keydown": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz", - "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-portal": { - "version": "1.1.2", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-portal/-/react-portal-1.1.2.tgz", - "integrity": "sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-presence": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-presence/-/react-presence-1.1.1.tgz", - "integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dialog/node_modules/react-remove-scroll": { - "version": "2.6.0", - "resolved": "https://registry.npmmirror.com/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz", - "integrity": "sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==", - "dependencies": { - "react-remove-scroll-bar": "^2.3.6", - "react-style-singleton": "^2.2.1", - "tslib": "^2.1.0", - "use-callback-ref": "^1.3.0", - "use-sidecar": "^1.1.2" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-direction": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", - "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz", - "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-escape-keydown": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dropdown-menu": { - "version": "2.1.1", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.1.tgz", - "integrity": "sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-menu": "2.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-controllable-state": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz", - "integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz", - "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-id": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-id/-/react-id-1.1.0.tgz", - "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-label": { - "version": "2.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-label/-/react-label-2.1.0.tgz", - "integrity": "sha512-peLblDlFw/ngk3UWq0VnYaOLy6agTZZ+MUO/WhVfm14vJGML+xH4FAl2XQGLqdefjNb7ApRg6Yn7U42ZhmYXdw==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-menu": { - "version": "2.1.1", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-menu/-/react-menu-2.1.1.tgz", - "integrity": "sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-collection": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-dismissable-layer": "1.1.0", - "@radix-ui/react-focus-guards": "1.1.0", - "@radix-ui/react-focus-scope": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-popper": "1.2.0", - "@radix-ui/react-portal": "1.1.1", - "@radix-ui/react-presence": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-roving-focus": "1.1.0", - "@radix-ui/react-slot": "1.1.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.7" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popper": { - "version": "1.2.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", - "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", - "dependencies": { - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0", - "@radix-ui/react-use-rect": "1.1.0", - "@radix-ui/react-use-size": "1.1.0", - "@radix-ui/rect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-portal": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-portal/-/react-portal-1.1.1.tgz", - "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-presence": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-presence/-/react-presence-1.1.0.tgz", - "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", - "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", - "dependencies": { - "@radix-ui/react-slot": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz", - "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-collection": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-scroll-area": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-scroll-area/-/react-scroll-area-1.1.0.tgz", - "integrity": "sha512-9ArIZ9HWhsrfqS765h+GZuLoxaRHD/j0ZWOWilsCvYTpYJp8XwCqNG7Dt9Nu/TItKOdgLGkOPCodQvDc+UMwYg==", - "dependencies": { - "@radix-ui/number": "1.1.0", - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-presence": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-select": { - "version": "2.1.1", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-select/-/react-select-2.1.1.tgz", - "integrity": "sha512-8iRDfyLtzxlprOo9IicnzvpsO1wNCkuwzzCM+Z5Rb5tNOpCdMvcc2AkzX0Fz+Tz9v6NJ5B/7EEgyZveo4FBRfQ==", - "dependencies": { - "@radix-ui/number": "1.1.0", - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-collection": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-dismissable-layer": "1.1.0", - "@radix-ui/react-focus-guards": "1.1.0", - "@radix-ui/react-focus-scope": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-popper": "1.2.0", - "@radix-ui/react-portal": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0", - "@radix-ui/react-use-previous": "1.1.0", - "@radix-ui/react-visually-hidden": "1.1.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.7" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", - "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", - "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", - "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", - "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", - "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", - "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", - "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-previous": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", - "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-rect": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", - "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", - "dependencies": { - "@radix-ui/rect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-size": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", - "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-visually-hidden": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", - "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/rect": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/@radix-ui/rect/-/rect-1.1.0.tgz", - "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" - }, "node_modules/@rc-component/async-validator": { "version": "5.0.4", "resolved": "https://registry.npmmirror.com/@rc-component/async-validator/-/async-validator-5.0.4.tgz", @@ -3643,16 +2864,16 @@ } }, "node_modules/@rc-component/trigger": { - "version": "2.2.5", - "resolved": "https://registry.npmmirror.com/@rc-component/trigger/-/trigger-2.2.5.tgz", - "integrity": "sha512-F1EJ4KjFpGAHAjuKvOyZB/6IZDkVx0bHl0M4fQM5wXcmm7lgTgVSSnR3bXwdmS6jOJGHOqfDxIJW3WUvwMIXhQ==", + "version": "2.2.6", + "resolved": "https://registry.npmmirror.com/@rc-component/trigger/-/trigger-2.2.6.tgz", + "integrity": "sha512-/9zuTnWwhQ3S3WT1T8BubuFTT46kvnXgaERR9f4BTKyn61/wpf/BvbImzYBubzJibU707FxwbKszLlHjcLiv1Q==", "dependencies": { "@babel/runtime": "^7.23.2", "@rc-component/portal": "^1.1.0", "classnames": "^2.3.2", "rc-motion": "^2.0.0", "rc-resize-observer": "^1.3.1", - "rc-util": "^5.38.0" + "rc-util": "^5.44.0" }, "engines": { "node": ">=8.x" @@ -3662,18 +2883,10 @@ "react-dom": ">=16.9.0" } }, - "node_modules/@remix-run/router": { - "version": "1.18.0", - "resolved": "https://registry.npmmirror.com/@remix-run/router/-/router-1.18.0.tgz", - "integrity": "sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", - "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz", + "integrity": "sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==", "cpu": [ "arm" ], @@ -3684,9 +2897,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", - "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz", + "integrity": "sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==", "cpu": [ "arm64" ], @@ -3697,9 +2910,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", - "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz", + "integrity": "sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==", "cpu": [ "arm64" ], @@ -3710,9 +2923,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", - "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz", + "integrity": "sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==", "cpu": [ "x64" ], @@ -3722,10 +2935,36 @@ "darwin" ] }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz", + "integrity": "sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz", + "integrity": "sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", - "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz", + "integrity": "sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==", "cpu": [ "arm" ], @@ -3736,9 +2975,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", - "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz", + "integrity": "sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==", "cpu": [ "arm" ], @@ -3749,9 +2988,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", - "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz", + "integrity": "sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==", "cpu": [ "arm64" ], @@ -3762,9 +3001,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", - "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz", + "integrity": "sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==", "cpu": [ "arm64" ], @@ -3774,10 +3013,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz", + "integrity": "sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", - "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz", + "integrity": "sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==", "cpu": [ "ppc64" ], @@ -3788,9 +3040,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", - "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz", + "integrity": "sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==", "cpu": [ "riscv64" ], @@ -3801,9 +3053,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", - "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz", + "integrity": "sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==", "cpu": [ "s390x" ], @@ -3814,9 +3066,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", - "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz", + "integrity": "sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==", "cpu": [ "x64" ], @@ -3827,9 +3079,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", - "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz", + "integrity": "sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==", "cpu": [ "x64" ], @@ -3840,9 +3092,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", - "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz", + "integrity": "sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==", "cpu": [ "arm64" ], @@ -3853,9 +3105,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", - "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz", + "integrity": "sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==", "cpu": [ "ia32" ], @@ -3866,9 +3118,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", - "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz", + "integrity": "sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==", "cpu": [ "x64" ], @@ -3878,36 +3130,11 @@ "win32" ] }, - "node_modules/@tanstack/react-table": { - "version": "8.20.5", - "resolved": "https://registry.npmmirror.com/@tanstack/react-table/-/react-table-8.20.5.tgz", - "integrity": "sha512-WEHopKw3znbUZ61s9i0+i9g8drmDo6asTWbrQh8Us63DAk/M0FkmIqERew6P71HI75ksZ2Pxyuf4vvKh9rAkiA==", - "dependencies": { - "@tanstack/table-core": "8.20.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8" - } - }, - "node_modules/@tanstack/table-core": { - "version": "8.20.5", - "resolved": "https://registry.npmmirror.com/@tanstack/table-core/-/table-core-8.20.5.tgz", - "integrity": "sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg==", - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -3950,10 +3177,15 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmmirror.com/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" + }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, "node_modules/@types/fs-extra": { @@ -3966,6 +3198,12 @@ "@types/node": "*" } }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmmirror.com/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, "node_modules/@types/jsonfile": { "version": "6.1.4", "resolved": "https://registry.npmmirror.com/@types/jsonfile/-/jsonfile-6.1.4.tgz", @@ -3976,12 +3214,12 @@ } }, "node_modules/@types/node": { - "version": "22.0.0", - "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.0.0.tgz", - "integrity": "sha512-VT7KSYudcPOzP5Q0wfbowyNLaVR8QWUdw+088uFWwfvpY6uCWaXpqV6ieLAu9WBcnTa7H4Z5RLK8I5t2FuOcqw==", + "version": "22.10.3", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.10.3.tgz", + "integrity": "sha512-DifAyw4BkrufCILvD3ucnuN8eydUfc/C1GlyrnI+LK6543w5/L3VeVgf05o3B4fqSXP1dKYLOZsKfutpxPzZrw==", "dev": true, "dependencies": { - "undici-types": "~6.11.1" + "undici-types": "~6.20.0" } }, "node_modules/@types/prop-types": { @@ -3991,9 +3229,9 @@ "devOptional": true }, "node_modules/@types/react": { - "version": "18.3.3", - "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.3.3.tgz", - "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "version": "18.3.18", + "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.3.18.tgz", + "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", "devOptional": true, "dependencies": { "@types/prop-types": "*", @@ -4010,86 +3248,78 @@ } }, "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmmirror.com/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", - "devOptional": true, - "dependencies": { - "@types/react": "*" + "version": "18.3.5", + "resolved": "https://registry.npmmirror.com/@types/react-dom/-/react-dom-18.3.5.tgz", + "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", + "dev": true, + "peerDependencies": { + "@types/react": "^18.0.0" } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.17.0", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz", - "integrity": "sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A==", + "version": "8.19.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.19.0.tgz", + "integrity": "sha512-NggSaEZCdSrFddbctrVjkVZvFC6KGfKfNK0CU7mNK/iKHGKbzT4Wmgm08dKpcZECBu9f5FypndoMyRHkdqfT1Q==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/type-utils": "7.17.0", - "@typescript-eslint/utils": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/scope-manager": "8.19.0", + "@typescript-eslint/type-utils": "8.19.0", + "@typescript-eslint/utils": "8.19.0", + "@typescript-eslint/visitor-keys": "8.19.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "7.17.0", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-7.17.0.tgz", - "integrity": "sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==", + "version": "8.19.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-8.19.0.tgz", + "integrity": "sha512-6M8taKyOETY1TKHp0x8ndycipTVgmp4xtg5QpEZzXxDhNvvHOJi5rLRkLr8SK3jTgD5l4fTlvBiRdfsuWydxBw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/scope-manager": "8.19.0", + "@typescript-eslint/types": "8.19.0", + "@typescript-eslint/typescript-estree": "8.19.0", + "@typescript-eslint/visitor-keys": "8.19.0", "debug": "^4.3.4" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.17.0", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz", - "integrity": "sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==", + "version": "8.19.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-8.19.0.tgz", + "integrity": "sha512-hkoJiKQS3GQ13TSMEiuNmSCvhz7ujyqD1x3ShbaETATHrck+9RaDdUbt+osXaUuns9OFwrDTTrjtwsU8gJyyRA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0" + "@typescript-eslint/types": "8.19.0", + "@typescript-eslint/visitor-keys": "8.19.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -4097,39 +3327,35 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.17.0", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-7.17.0.tgz", - "integrity": "sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA==", + "version": "8.19.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-8.19.0.tgz", + "integrity": "sha512-TZs0I0OSbd5Aza4qAMpp1cdCYVnER94IziudE3JU328YUHgWu9gwiwhag+fuLeJ2LkWLXI+F/182TbG+JaBdTg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/utils": "7.17.0", + "@typescript-eslint/typescript-estree": "8.19.0", + "@typescript-eslint/utils": "8.19.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/types": { - "version": "7.17.0", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/types/-/types-7.17.0.tgz", - "integrity": "sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==", + "version": "8.19.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/types/-/types-8.19.0.tgz", + "integrity": "sha512-8XQ4Ss7G9WX8oaYvD4OOLCjIQYgRQxO+qCiR2V2s2GxI9AUpo7riNwo6jDhKtTcaJjT8PY54j2Yb33kWtSJsmA==", "dev": true, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -4137,70 +3363,81 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.17.0", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz", - "integrity": "sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==", + "version": "8.19.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.19.0.tgz", + "integrity": "sha512-WW9PpDaLIFW9LCbucMSdYUuGeFUz1OkWYS/5fwZwTA+l2RwlWFdJvReQqMUMBw4yJWJOfqd7An9uwut2Oj8sLw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/types": "8.19.0", + "@typescript-eslint/visitor-keys": "8.19.0", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "7.17.0", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-7.17.0.tgz", - "integrity": "sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.17.0", - "resolved": "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz", - "integrity": "sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==", + "node_modules/@typescript-eslint/utils": { + "version": "8.19.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-8.19.0.tgz", + "integrity": "sha512-PTBG+0oEMPH9jCZlfg07LCB2nYI0I317yyvXGfxnvGvw4SHIOuRnQ3kadyyXY6tGdChusIHIbM5zfIbp4M6tCg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.17.0", - "eslint-visitor-keys": "^3.4.3" + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.19.0", + "@typescript-eslint/types": "8.19.0", + "@typescript-eslint/typescript-estree": "8.19.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.19.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.19.0.tgz", + "integrity": "sha512-mCFtBbFBJDCNCWUl5y6sZSCHXw1DEFEk3c/M3nRK2a4XUB8StGFtmcEMizdjKuBzB6e/smJAAWYug3VrdLMr1w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.19.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "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==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@umijs/route-utils": { @@ -4223,40 +3460,40 @@ "dev": true }, "node_modules/@vitejs/plugin-legacy": { - "version": "5.4.3", - "resolved": "https://registry.npmmirror.com/@vitejs/plugin-legacy/-/plugin-legacy-5.4.3.tgz", - "integrity": "sha512-wsyXK9mascyplcqvww1gA1xYiy29iRHfyciw+a0t7qRNdzX6PdfSWmOoCi74epr87DujM+5J+rnnSv+4PazqVg==", + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-legacy/-/plugin-legacy-6.0.0.tgz", + "integrity": "sha512-pWt9cWaGJAKYw+67VLpN8hSP+G+yAQnrf5Pqh/NzSDKFl/4KpxTtwb5OLQezHoZOxghahO/ha3IpvblBbX/t6A==", "dev": true, "dependencies": { - "@babel/core": "^7.25.8", - "@babel/preset-env": "^7.25.8", - "browserslist": "^4.24.0", + "@babel/core": "^7.26.0", + "@babel/preset-env": "^7.26.0", + "browserslist": "^4.24.2", "browserslist-to-esbuild": "^2.1.1", - "core-js": "^3.38.1", - "magic-string": "^0.30.12", + "core-js": "^3.39.0", + "magic-string": "^0.30.13", "regenerator-runtime": "^0.14.1", "systemjs": "^6.15.1" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" }, "peerDependencies": { - "terser": "^5.4.0", - "vite": "^5.0.0" + "terser": "^5.16.0", + "vite": "^6.0.0" } }, "node_modules/@vitejs/plugin-react": { - "version": "4.3.1", - "resolved": "https://registry.npmmirror.com/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz", - "integrity": "sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==", + "version": "4.3.4", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", + "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", "dev": true, "dependencies": { - "@babel/core": "^7.24.5", - "@babel/plugin-transform-react-jsx-self": "^7.24.5", - "@babel/plugin-transform-react-jsx-source": "^7.24.1", + "@babel/core": "^7.26.0", + "@babel/plugin-transform-react-jsx-self": "^7.25.9", + "@babel/plugin-transform-react-jsx-source": "^7.25.9", "@types/babel__core": "^7.20.5", "react-refresh": "^0.14.2" }, @@ -4264,7 +3501,7 @@ "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0" + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, "node_modules/acorn": { @@ -4338,19 +3575,20 @@ "version": "5.0.1", "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } }, "node_modules/antd": { - "version": "5.22.2", - "resolved": "https://registry.npmmirror.com/antd/-/antd-5.22.2.tgz", - "integrity": "sha512-vihhiJbm9VG3d6boUeD1q2MXMax+qBrXhgqCEC+45v8iGUF6m4Ct+lFiCW4oWaN3EABOsbVA6Svy3Rj/QkQFKw==", + "version": "5.22.7", + "resolved": "https://registry.npmmirror.com/antd/-/antd-5.22.7.tgz", + "integrity": "sha512-koT5QMliDgXc21yNcs4Uyuq6TeB5AJbzGZ2qjNExzE7Tjr8yYIX6sJsQfunsEV80wC1mpF7m9ldKuNj+PafcFA==", "dependencies": { "@ant-design/colors": "^7.1.0", "@ant-design/cssinjs": "^1.21.1", - "@ant-design/cssinjs-utils": "^1.1.1", - "@ant-design/icons": "^5.5.1", + "@ant-design/cssinjs-utils": "^1.1.3", + "@ant-design/icons": "^5.5.2", "@ant-design/react-slick": "~1.1.2", "@babel/runtime": "^7.25.7", "@ctrl/tinycolor": "^3.6.1", @@ -4358,7 +3596,7 @@ "@rc-component/mutate-observer": "^1.1.0", "@rc-component/qrcode": "~1.0.0", "@rc-component/tour": "~1.15.1", - "@rc-component/trigger": "^2.2.5", + "@rc-component/trigger": "^2.2.6", "classnames": "^2.5.1", "copy-to-clipboard": "^3.3.3", "dayjs": "^1.11.11", @@ -4367,33 +3605,33 @@ "rc-collapse": "~3.9.0", "rc-dialog": "~9.6.0", "rc-drawer": "~7.2.0", - "rc-dropdown": "~4.2.0", - "rc-field-form": "~2.5.1", + "rc-dropdown": "~4.2.1", + "rc-field-form": "~2.7.0", "rc-image": "~7.11.0", - "rc-input": "~1.6.3", + "rc-input": "~1.6.4", "rc-input-number": "~9.3.0", "rc-mentions": "~2.17.0", "rc-menu": "~9.16.0", - "rc-motion": "^2.9.3", + "rc-motion": "^2.9.5", "rc-notification": "~5.6.2", - "rc-pagination": "~4.3.0", - "rc-picker": "~4.8.1", + "rc-pagination": "~5.0.0", + "rc-picker": "~4.8.3", "rc-progress": "~4.0.0", "rc-rate": "~2.13.0", - "rc-resize-observer": "^1.4.0", + "rc-resize-observer": "^1.4.3", "rc-segmented": "~2.5.0", - "rc-select": "~14.16.3", + "rc-select": "~14.16.4", "rc-slider": "~11.1.7", "rc-steps": "~6.0.1", "rc-switch": "~4.1.0", - "rc-table": "~7.48.1", + "rc-table": "~7.49.0", "rc-tabs": "~15.4.0", "rc-textarea": "~1.8.2", "rc-tooltip": "~6.2.1", "rc-tree": "~5.10.1", - "rc-tree-select": "~5.24.4", + "rc-tree-select": "~5.24.5", "rc-upload": "~4.8.1", - "rc-util": "^5.43.0", + "rc-util": "^5.44.3", "scroll-into-view-if-needed": "^3.1.0", "throttle-debounce": "^5.0.2" }, @@ -4421,12 +3659,14 @@ "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmmirror.com/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -4438,7 +3678,8 @@ "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmmirror.com/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true }, "node_modules/argparse": { "version": "2.0.1", @@ -4446,30 +3687,123 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/aria-hidden": { - "version": "1.2.4", - "resolved": "https://registry.npmmirror.com/aria-hidden/-/aria-hidden-1.2.4.tgz", - "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, "dependencies": { - "tslib": "^2.0.0" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { - "node": ">=10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "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==", "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "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" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmmirror.com/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmmirror.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "version": "10.4.20", + "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", "dev": true, "funding": [ { @@ -4486,11 +3820,11 @@ } ], "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -4503,6 +3837,21 @@ "postcss": "^8.1.0" } }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.4.12", "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", @@ -4554,12 +3903,14 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, "engines": { "node": ">=8" }, @@ -4571,6 +3922,7 @@ "version": "2.0.1", "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -4579,6 +3931,7 @@ "version": "3.0.3", "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, "dependencies": { "fill-range": "^7.1.1" }, @@ -4643,6 +3996,53 @@ "dev": true, "peer": true }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz", @@ -4656,6 +4056,7 @@ "version": "2.0.1", "resolved": "https://registry.npmmirror.com/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, "engines": { "node": ">= 6" } @@ -4684,6 +4085,7 @@ "version": "3.6.0", "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -4707,6 +4109,7 @@ "version": "5.1.2", "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -4714,25 +4117,6 @@ "node": ">= 6" } }, - "node_modules/class-variance-authority": { - "version": "0.7.0", - "resolved": "https://registry.npmmirror.com/class-variance-authority/-/class-variance-authority-0.7.0.tgz", - "integrity": "sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==", - "dependencies": { - "clsx": "2.0.0" - }, - "funding": { - "url": "https://joebell.co.uk" - } - }, - "node_modules/class-variance-authority/node_modules/clsx": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/clsx/-/clsx-2.0.0.tgz", - "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", - "engines": { - "node": ">=6" - } - }, "node_modules/classnames": { "version": "2.5.1", "resolved": "https://registry.npmmirror.com/classnames/-/classnames-2.5.1.tgz", @@ -4743,18 +4127,11 @@ "resolved": "https://registry.npmmirror.com/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmmirror.com/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "engines": { - "node": ">=6" - } - }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, "engines": { "node": ">= 6" } @@ -4776,6 +4153,14 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "engines": { + "node": ">=18" + } + }, "node_modules/copy-to-clipboard": { "version": "3.3.3", "resolved": "https://registry.npmmirror.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", @@ -4824,18 +4209,11 @@ "node": ">=12.0.0" } }, - "node_modules/cross-fetch": { - "version": "4.0.0", - "resolved": "https://registry.npmmirror.com/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", - "dependencies": { - "node-fetch": "^2.6.12" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4849,6 +4227,7 @@ "version": "3.0.0", "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, "bin": { "cssesc": "bin/cssesc" }, @@ -4861,18 +4240,69 @@ "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/dayjs": { "version": "1.11.13", "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz", "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==" }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.4.0", + "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -4889,32 +4319,51 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/detect-node-es": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/detect-node-es/-/detect-node-es-1.1.0.tgz", - "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmmirror.com/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true }, "node_modules/doctrine": { "version": "3.0.0", @@ -4928,10 +4377,25 @@ "node": ">=6.0.0" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true }, "node_modules/electron-to-chromium": { "version": "1.5.74", @@ -4942,44 +4406,193 @@ "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/enhanced-resolve": { + "version": "5.18.0", + "resolved": "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", + "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "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==", + "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", + "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-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.6", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.0", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "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==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.24.2.tgz", + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" } }, "node_modules/escalade": { @@ -5058,6 +4671,172 @@ "eslint": ">=7.0.0" } }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmmirror.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.7.0", + "resolved": "https://registry.npmmirror.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.7.0.tgz", + "integrity": "sha512-Vrwyi8HHxY97K5ebydMtffsWAn1SCR9eol49eCd5fJS4O1WV7PaAjbcjmbfJJSMz/t4Mal212Uz/fQZrOB8mow==", + "dev": true, + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.3.7", + "enhanced-resolve": "^5.15.0", + "fast-glob": "^3.3.2", + "get-tsconfig": "^4.7.5", + "is-bun-module": "^1.0.2", + "is-glob": "^4.0.3", + "stable-hash": "^0.0.4" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "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==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "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==", + "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", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.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", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-plugin-prettier": { "version": "5.2.1", "resolved": "https://registry.npmmirror.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", @@ -5089,24 +4868,40 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.2", - "resolved": "https://registry.npmmirror.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz", + "integrity": "sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==", "dev": true, "engines": { "node": ">=10" }, "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.9", - "resolved": "https://registry.npmmirror.com/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.9.tgz", - "integrity": "sha512-QK49YrBAo5CLNLseZ7sZgvgTy21E6NEw22eZqc4teZfH8pxV3yXc9XXOYfUI6JNpw7mfHNkAeWtBxrTyykB6HA==", + "version": "0.4.16", + "resolved": "https://registry.npmmirror.com/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.16.tgz", + "integrity": "sha512-slterMlxAhov/DZO8NScf6mEeMBBXodFUolijDvrtTxyezyLoTQaa73FyYus/VbTdftd8wBgBxPMRk3poleXNQ==", "dev": true, "peerDependencies": { - "eslint": ">=7" + "eslint": ">=8.40" + } + }, + "node_modules/eslint-plugin-tailwindcss": { + "version": "3.17.5", + "resolved": "https://registry.npmmirror.com/eslint-plugin-tailwindcss/-/eslint-plugin-tailwindcss-3.17.5.tgz", + "integrity": "sha512-8Mi7p7dm+mO1dHgRHHFdPu4RDTBk69Cn4P0B40vRQR+MrguUpwmKwhZy1kqYe3Km8/4nb+cyrCF+5SodOEmaow==", + "dev": true, + "dependencies": { + "fast-glob": "^3.2.5", + "postcss": "^8.4.4" + }, + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "tailwindcss": "^3.4.0" } }, "node_modules/eslint-scope": { @@ -5331,6 +5126,7 @@ "version": "3.3.2", "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -5346,6 +5142,7 @@ "version": "5.1.2", "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -5369,6 +5166,7 @@ "version": "1.17.1", "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, "dependencies": { "reusify": "^1.0.4" } @@ -5389,6 +5187,7 @@ "version": "7.1.1", "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -5432,10 +5231,20 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "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==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/foreground-child": { "version": "3.2.1", "resolved": "https://registry.npmmirror.com/foreground-child/-/foreground-child-3.2.1.tgz", "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -5484,6 +5293,7 @@ "version": "2.3.3", "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -5497,6 +5307,36 @@ "version": "1.1.2", "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmmirror.com/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5510,12 +5350,57 @@ "node": ">=6.9.0" } }, - "node_modules/get-nonce": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/get-nonce/-/get-nonce-1.0.1.tgz", - "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "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==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.0.0" + }, "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.8.1", + "resolved": "https://registry.npmmirror.com/get-tsconfig/-/get-tsconfig-4.8.1.tgz", + "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, "node_modules/glob": { @@ -5543,6 +5428,7 @@ "version": "6.0.2", "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -5581,24 +5467,32 @@ "node": ">=4" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/graceful-fs": { @@ -5613,10 +5507,77 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -5633,9 +5594,9 @@ } }, "node_modules/i18next": { - "version": "23.15.1", - "resolved": "https://registry.npmmirror.com/i18next/-/i18next-23.15.1.tgz", - "integrity": "sha512-wB4abZ3uK7EWodYisHl/asf8UYEhrI/vj/8aoSsrj/ZDxj4/UXPOa1KvFt1Fq5hkUHquNqwFlDprmjZ8iySgYA==", + "version": "24.2.0", + "resolved": "https://registry.npmmirror.com/i18next/-/i18next-24.2.0.tgz", + "integrity": "sha512-ArJJTS1lV6lgKH7yEf4EpgNZ7+THl7bsGxxougPYiXRTJ/Fe1j08/TBpV9QsXCIYVfdE/HWG/xLezJ5DOlfBOA==", "funding": [ { "type": "individual", @@ -5652,24 +5613,24 @@ ], "dependencies": { "@babel/runtime": "^7.23.2" + }, + "peerDependencies": { + "typescript": "^5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/i18next-browser-languagedetector": { - "version": "8.0.0", - "resolved": "https://registry.npmmirror.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.0.0.tgz", - "integrity": "sha512-zhXdJXTTCoG39QsrOCiOabnWj2jecouOqbchu3EfhtSHxIB5Uugnm9JaizenOy39h7ne3+fLikIjeW88+rgszw==", + "version": "8.0.2", + "resolved": "https://registry.npmmirror.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.0.2.tgz", + "integrity": "sha512-shBvPmnIyZeD2VU5jVGIOWP7u9qNG3Lj7mpaiPFpbJ3LVfHZJvVzKR4v1Cb91wAOFpNw442N+LGPzHOHsten2g==", "dependencies": { "@babel/runtime": "^7.23.2" } }, - "node_modules/i18next-http-backend": { - "version": "2.6.1", - "resolved": "https://registry.npmmirror.com/i18next-http-backend/-/i18next-http-backend-2.6.1.tgz", - "integrity": "sha512-rCilMAnlEQNeKOZY1+x8wLM5IpYOj10guGvEpeC59tNjj6MMreLIjIW8D1RclhD3ifLwn6d/Y9HEM1RUE6DSog==", - "dependencies": { - "cross-fetch": "4.0.0" - } - }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.3.1.tgz", @@ -5734,23 +5695,77 @@ "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/intersection-observer": { "version": "0.12.2", "resolved": "https://registry.npmmirror.com/intersection-observer/-/intersection-observer-0.12.2.tgz", "integrity": "sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==" }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmmirror.com/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmmirror.com/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, "dependencies": { - "loose-envify": "^1.0.0" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -5758,10 +5773,48 @@ "node": ">=8" } }, + "node_modules/is-boolean-object": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/is-boolean-object/-/is-boolean-object-1.2.1.tgz", + "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bun-module": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/is-bun-module/-/is-bun-module-1.3.0.tgz", + "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==", + "dev": true, + "dependencies": { + "semver": "^7.6.3" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-core-module": { - "version": "2.15.0", - "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.15.0.tgz", - "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "version": "2.16.1", + "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, "dependencies": { "hasown": "^2.0.2" }, @@ -5772,26 +5825,92 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "engines": { "node": ">=8" } }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmmirror.com/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -5799,14 +5918,43 @@ "node": ">=0.10.0" } }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "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", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "engines": { "node": ">=0.12.0" } }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmmirror.com/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -5816,6 +5964,142 @@ "node": ">=8" } }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmmirror.com/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz", @@ -5824,12 +6108,14 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmmirror.com/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -5844,6 +6130,7 @@ "version": "1.21.6", "resolved": "https://registry.npmmirror.com/jiti/-/jiti-1.21.6.tgz", "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true, "bin": { "jiti": "bin/jiti.js" } @@ -5977,17 +6264,22 @@ } }, "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true }, "node_modules/locate-path": { "version": "6.0.0", @@ -6046,9 +6338,9 @@ } }, "node_modules/lucide-react": { - "version": "0.417.0", - "resolved": "https://registry.npmmirror.com/lucide-react/-/lucide-react-0.417.0.tgz", - "integrity": "sha512-F/MDUHDter8YMZ7JKQpW/5/+v38tdaoShKX3e+opYsqfCnaHwn+5zz3+lBrMDFMNtSsvxtNpchLIaMpEfsi/4w==", + "version": "0.469.0", + "resolved": "https://registry.npmmirror.com/lucide-react/-/lucide-react-0.469.0.tgz", + "integrity": "sha512-28vvUnnKQ/dBwiCQtwJw7QauYnE7yd2Cyp4tTTJpvglX4EMpbflcdBgrgToX2j71B3YvugK/NH3BGUk+E/p/Fw==", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } @@ -6070,6 +6362,15 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/meow": { "version": "13.2.0", "resolved": "https://registry.npmmirror.com/meow/-/meow-13.2.0.tgz", @@ -6086,6 +6387,7 @@ "version": "1.4.1", "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, "engines": { "node": ">= 8" } @@ -6094,6 +6396,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -6106,6 +6409,7 @@ "version": "9.0.5", "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -6116,34 +6420,35 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmmirror.com/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, "engines": { "node": ">=16 || 14 >=14.17" } }, - "node_modules/moment": { - "version": "2.30.1", - "resolved": "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", - "optional": true, - "peer": true, - "engines": { - "node": "*" - } - }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmmirror.com/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -6151,9 +6456,9 @@ } }, "node_modules/nanoid": { - "version": "5.0.7", - "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-5.0.7.tgz", - "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==", + "version": "5.0.9", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-5.0.9.tgz", + "integrity": "sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==", "funding": [ { "type": "github", @@ -6173,25 +6478,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.19.tgz", @@ -6202,6 +6488,7 @@ "version": "3.0.0", "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -6227,10 +6514,102 @@ "version": "3.0.0", "resolved": "https://registry.npmmirror.com/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, "engines": { "node": ">= 6" } }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmmirror.com/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmmirror.com/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/omit.js": { "version": "2.0.2", "resolved": "https://registry.npmmirror.com/omit.js/-/omit.js-2.0.2.tgz", @@ -6262,6 +6641,23 @@ "node": ">= 0.8.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz", @@ -6295,7 +6691,8 @@ "node_modules/package-json-from-dist": { "version": "1.0.0", "resolved": "https://registry.npmmirror.com/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true }, "node_modules/pako": { "version": "1.0.11", @@ -6336,6 +6733,7 @@ "version": "3.1.1", "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, "engines": { "node": ">=8" } @@ -6343,12 +6741,14 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmmirror.com/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -6363,7 +6763,8 @@ "node_modules/path-scurry/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true }, "node_modules/path-to-regexp": { "version": "8.0.0", @@ -6373,24 +6774,17 @@ "node": ">=16" } }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "engines": { "node": ">=8.6" }, @@ -6402,6 +6796,7 @@ "version": "2.3.0", "resolved": "https://registry.npmmirror.com/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -6410,19 +6805,30 @@ "version": "4.0.6", "resolved": "https://registry.npmmirror.com/pirates/-/pirates-4.0.6.tgz", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, "engines": { "node": ">= 6" } }, "node_modules/pocketbase": { - "version": "0.21.4", - "resolved": "https://registry.npmmirror.com/pocketbase/-/pocketbase-0.21.4.tgz", - "integrity": "sha512-WJHyaqdAt95JgZ1OCRD099+DST4IIG0M/jMrCckWYDSN/6ocp61qsz7m6h0xI0J2N79ScBljceEC0fFAaQrrAw==" + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/pocketbase/-/pocketbase-0.21.5.tgz", + "integrity": "sha512-bnI/uinnQps+ElSlzxkc4yvwuSFfKcoszDtXH/4QT2FhGq2mJVUvDlxn+rjRXVntUjPfmMG5LEPZ1eGqV6ssog==" + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } }, "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "version": "8.4.49", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "dev": true, "funding": [ { "type": "opencollective", @@ -6439,7 +6845,7 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.1.0", + "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { @@ -6450,6 +6856,7 @@ "version": "15.1.0", "resolved": "https://registry.npmmirror.com/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -6466,6 +6873,7 @@ "version": "4.0.1", "resolved": "https://registry.npmmirror.com/postcss-js/-/postcss-js-4.0.1.tgz", "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, "dependencies": { "camelcase-css": "^2.0.1" }, @@ -6484,6 +6892,7 @@ "version": "4.0.2", "resolved": "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz", "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, "funding": [ { "type": "opencollective", @@ -6514,21 +6923,11 @@ } } }, - "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, "node_modules/postcss-nested": { "version": "6.2.0", "resolved": "https://registry.npmmirror.com/postcss-nested/-/postcss-nested-6.2.0.tgz", "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, "funding": [ { "type": "opencollective", @@ -6550,9 +6949,10 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.1", - "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", - "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", + "version": "6.1.2", + "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -6564,12 +6964,14 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true }, "node_modules/postcss/node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, "funding": [ { "type": "github", @@ -6593,9 +6995,9 @@ } }, "node_modules/prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmmirror.com/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "version": "3.4.2", + "resolved": "https://registry.npmmirror.com/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -6652,6 +7054,7 @@ "version": "1.2.3", "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, "funding": [ { "type": "github", @@ -6667,6 +7070,14 @@ } ] }, + "node_modules/radash": { + "version": "12.1.0", + "resolved": "https://registry.npmmirror.com/radash/-/radash-12.1.0.tgz", + "integrity": "sha512-b0Zcf09AhqKS83btmUeYBS8tFK7XL2e3RvLmZcm0sTdF1/UUlHSsjXdCcWNxe7yfmAlPve5ym0DmKGtTzP6kVQ==", + "engines": { + "node": ">=14.18.0" + } + }, "node_modules/rc-cascader": { "version": "3.30.0", "resolved": "https://registry.npmmirror.com/rc-cascader/-/rc-cascader-3.30.0.tgz", @@ -6745,14 +7156,14 @@ } }, "node_modules/rc-dropdown": { - "version": "4.2.0", - "resolved": "https://registry.npmmirror.com/rc-dropdown/-/rc-dropdown-4.2.0.tgz", - "integrity": "sha512-odM8Ove+gSh0zU27DUj5cG1gNKg7mLWBYzB5E4nNLrLwBmYEgYP43vHKDGOVZcJSVElQBI0+jTQgjnq0NfLjng==", + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/rc-dropdown/-/rc-dropdown-4.2.1.tgz", + "integrity": "sha512-YDAlXsPv3I1n42dv1JpdM7wJ+gSUBfeyPK59ZpBD9jQhK9jVuxpjj3NmWQHOBceA1zEPVX84T2wbdb2SD0UjmA==", "dependencies": { "@babel/runtime": "^7.18.3", "@rc-component/trigger": "^2.0.0", "classnames": "^2.2.6", - "rc-util": "^5.17.0" + "rc-util": "^5.44.1" }, "peerDependencies": { "react": ">=16.11.0", @@ -6760,9 +7171,9 @@ } }, "node_modules/rc-field-form": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/rc-field-form/-/rc-field-form-2.5.1.tgz", - "integrity": "sha512-33hunXwynQJyeae7LS3hMGTXNeRBjiPyPYgB0824EbmLHiXC1EBGyUwRh6xjLRy9c+en5WARYN0gJz5+JAqwig==", + "version": "2.7.0", + "resolved": "https://registry.npmmirror.com/rc-field-form/-/rc-field-form-2.7.0.tgz", + "integrity": "sha512-hgKsCay2taxzVnBPZl+1n4ZondsV78G++XVsMIJCAoioMjlMQR9YwAp7JZDIECzIu2Z66R+f4SFIRrO2DjDNAA==", "dependencies": { "@babel/runtime": "^7.18.0", "@rc-component/async-validator": "^5.0.3", @@ -6794,9 +7205,9 @@ } }, "node_modules/rc-input": { - "version": "1.6.3", - "resolved": "https://registry.npmmirror.com/rc-input/-/rc-input-1.6.3.tgz", - "integrity": "sha512-wI4NzuqBS8vvKr8cljsvnTUqItMfG1QbJoxovCgL+DX4eVUcHIjVwharwevIxyy7H/jbLryh+K7ysnJr23aWIA==", + "version": "1.6.4", + "resolved": "https://registry.npmmirror.com/rc-input/-/rc-input-1.6.4.tgz", + "integrity": "sha512-lBZhfRD4NSAUW0zOKLUeI6GJuXkxeZYi0hr8VcJgJpyTNOvHw1ysrKWAHcEOAAHj7guxgmWYSi6xWrEdfrSAsA==", "dependencies": { "@babel/runtime": "^7.11.1", "classnames": "^2.2.1", @@ -6859,13 +7270,13 @@ } }, "node_modules/rc-motion": { - "version": "2.9.3", - "resolved": "https://registry.npmmirror.com/rc-motion/-/rc-motion-2.9.3.tgz", - "integrity": "sha512-rkW47ABVkic7WEB0EKJqzySpvDqwl60/tdkY7hWP7dYnh5pm0SzJpo54oW3TDUGXV5wfxXFmMkxrzRRbotQ0+w==", + "version": "2.9.5", + "resolved": "https://registry.npmmirror.com/rc-motion/-/rc-motion-2.9.5.tgz", + "integrity": "sha512-w+XTUrfh7ArbYEd2582uDrEhmBHwK1ZENJiSJVb7uRxdE7qJSYjbO2eksRXmndqyKqKoYPc9ClpPh5242mV1vA==", "dependencies": { "@babel/runtime": "^7.11.1", "classnames": "^2.2.1", - "rc-util": "^5.43.0" + "rc-util": "^5.44.0" }, "peerDependencies": { "react": ">=16.9.0", @@ -6906,9 +7317,9 @@ } }, "node_modules/rc-pagination": { - "version": "4.3.0", - "resolved": "https://registry.npmmirror.com/rc-pagination/-/rc-pagination-4.3.0.tgz", - "integrity": "sha512-UubEWA0ShnroQ1tDa291Fzw6kj0iOeF26IsUObxYTpimgj4/qPCWVFl18RLZE+0Up1IZg0IK4pMn6nB3mjvB7g==", + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/rc-pagination/-/rc-pagination-5.0.0.tgz", + "integrity": "sha512-QjrPvbAQwps93iluvFM62AEYglGYhWW2q/nliQqmvkTi4PXP4HHoh00iC1Sa5LLVmtWQHmG73fBi2x6H6vFHRg==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "^2.3.2", @@ -6920,9 +7331,9 @@ } }, "node_modules/rc-picker": { - "version": "4.8.2", - "resolved": "https://registry.npmmirror.com/rc-picker/-/rc-picker-4.8.2.tgz", - "integrity": "sha512-I6Nn4ngkRskSD//rsXDvjlEQ8CzX9kPQrUIb7+qTY49erJaa3/oKJWmi6JIxo/A7gy59phNmPTdhKosAa/NrQQ==", + "version": "4.8.3", + "resolved": "https://registry.npmmirror.com/rc-picker/-/rc-picker-4.8.3.tgz", + "integrity": "sha512-hJ45qoEs4mfxXPAJdp1n3sKwADul874Cd0/HwnsEOE60H+tgiJUGgbOD62As3EG/rFVNS5AWRfBCDJJfmRqOVQ==", "dependencies": { "@babel/runtime": "^7.24.7", "@rc-component/trigger": "^2.0.0", @@ -6989,13 +7400,13 @@ } }, "node_modules/rc-resize-observer": { - "version": "1.4.0", - "resolved": "https://registry.npmmirror.com/rc-resize-observer/-/rc-resize-observer-1.4.0.tgz", - "integrity": "sha512-PnMVyRid9JLxFavTjeDXEXo65HCRqbmLBw9xX9gfC4BZiSzbLXKzW3jPz+J0P71pLbD5tBMTT+mkstV5gD0c9Q==", + "version": "1.4.3", + "resolved": "https://registry.npmmirror.com/rc-resize-observer/-/rc-resize-observer-1.4.3.tgz", + "integrity": "sha512-YZLjUbyIWox8E9i9C3Tm7ia+W7euPItNWSPX5sCcQTYbnwDb5uNpnLHQCG1f22oZWUhLw4Mv2tFmeWe68CDQRQ==", "dependencies": { "@babel/runtime": "^7.20.7", "classnames": "^2.2.1", - "rc-util": "^5.38.0", + "rc-util": "^5.44.1", "resize-observer-polyfill": "^1.5.1" }, "peerDependencies": { @@ -7019,9 +7430,9 @@ } }, "node_modules/rc-select": { - "version": "14.16.3", - "resolved": "https://registry.npmmirror.com/rc-select/-/rc-select-14.16.3.tgz", - "integrity": "sha512-51+j6s3fJJJXB7E+B6W1hM4Tjzv1B/Decooz9ilgegDBt3ZAth1b/xMwYCTrT5BbG2e53XACQsyDib2+3Ro1fg==", + "version": "14.16.4", + "resolved": "https://registry.npmmirror.com/rc-select/-/rc-select-14.16.4.tgz", + "integrity": "sha512-jP6qf7+vjnxGvPpfPWbGYfFlSl3h8L2XcD4O7g2GYXmEeBC0mw+nPD7i++OOE8v3YGqP8xtYjRKAWCMLfjgxlw==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/trigger": "^2.1.1", @@ -7088,9 +7499,9 @@ } }, "node_modules/rc-table": { - "version": "7.48.1", - "resolved": "https://registry.npmmirror.com/rc-table/-/rc-table-7.48.1.tgz", - "integrity": "sha512-Z4mDKjWg+xz/Ezdw6ivWcbqRpaJ0QfCORRoRrlrw65KSGZLK8OcTdacH22/fyGb8L4It/0/9qcMm8VrVAk/WBw==", + "version": "7.49.0", + "resolved": "https://registry.npmmirror.com/rc-table/-/rc-table-7.49.0.tgz", + "integrity": "sha512-/FoPLX94muAQOxVpi1jhnpKjOIqUbT81eELQPAzSXOke4ky4oCWYUXOcVpL31ZCO90xScwVSXRd7coqtgtB1Ng==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/context": "^1.4.0", @@ -7208,9 +7619,9 @@ } }, "node_modules/rc-util": { - "version": "5.43.0", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.43.0.tgz", - "integrity": "sha512-AzC7KKOXFqAdIBqdGWepL9Xn7cm3vnAmjlHqUnoQaTMZYhM4VlXGLkkHHxj/BZ7Td0+SOPKB4RGPboBVKT9htw==", + "version": "5.44.3", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.44.3.tgz", + "integrity": "sha512-q6KCcOFk3rv/zD3MckhJteZxb0VjAIFuf622B7ElK4vfrZdAzs16XR5p3VTdy3+U5jfJU5ACz4QnhLSuAGe5dA==", "dependencies": { "@babel/runtime": "^7.18.3", "react-is": "^18.2.0" @@ -7278,25 +7689,10 @@ "resolved": "https://registry.npmmirror.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz", "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" }, - "node_modules/react-hook-form": { - "version": "7.52.1", - "resolved": "https://registry.npmmirror.com/react-hook-form/-/react-hook-form-7.52.1.tgz", - "integrity": "sha512-uNKIhaoICJ5KQALYZ4TOaOLElyM+xipord+Ha3crEFhTntdLvWZqVY49Wqd/0GiVCA/f9NjemLeiNPjG7Hpurg==", - "engines": { - "node": ">=12.22.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/react-hook-form" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17 || ^18 || ^19" - } - }, "node_modules/react-i18next": { - "version": "15.0.2", - "resolved": "https://registry.npmmirror.com/react-i18next/-/react-i18next-15.0.2.tgz", - "integrity": "sha512-z0W3/RES9Idv3MmJUcf0mDNeeMOUXe+xoL0kPfQPbDoZHmni/XsIoq5zgT2MCFUiau283GuBUK578uD/mkAbLQ==", + "version": "15.4.0", + "resolved": "https://registry.npmmirror.com/react-i18next/-/react-i18next-15.4.0.tgz", + "integrity": "sha512-Py6UkX3zV08RTvL6ZANRoBh9sL/ne6rQq79XlkHEdd82cZr2H9usbWpUNVadJntIZP2pu3M2rL1CN+5rQYfYFw==", "dependencies": { "@babel/runtime": "^7.25.0", "html-parse-stringify": "^3.0.1" @@ -7333,101 +7729,42 @@ "node": ">=0.10.0" } }, - "node_modules/react-remove-scroll": { - "version": "2.5.7", - "resolved": "https://registry.npmmirror.com/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz", - "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==", - "dependencies": { - "react-remove-scroll-bar": "^2.3.4", - "react-style-singleton": "^2.2.1", - "tslib": "^2.1.0", - "use-callback-ref": "^1.3.0", - "use-sidecar": "^1.1.2" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-remove-scroll-bar": { - "version": "2.3.6", - "resolved": "https://registry.npmmirror.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", - "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", - "dependencies": { - "react-style-singleton": "^2.2.1", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/react-router": { - "version": "6.25.1", - "resolved": "https://registry.npmmirror.com/react-router/-/react-router-6.25.1.tgz", - "integrity": "sha512-u8ELFr5Z6g02nUtpPAggP73Jigj1mRePSwhS/2nkTrlPU5yEkH1vYzWNyvSnSzeeE2DNqWdH+P8OhIh9wuXhTw==", + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/react-router/-/react-router-7.1.1.tgz", + "integrity": "sha512-39sXJkftkKWRZ2oJtHhCxmoCrBCULr/HAH4IT5DHlgu/Q0FCPV0S4Lx+abjDTx/74xoZzNYDYbOZWlJjruyuDQ==", "dependencies": { - "@remix-run/router": "1.18.0" + "@types/cookie": "^0.6.0", + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0", + "turbo-stream": "2.4.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=20.0.0" }, "peerDependencies": { - "react": ">=16.8" + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } } }, "node_modules/react-router-dom": { - "version": "6.25.1", - "resolved": "https://registry.npmmirror.com/react-router-dom/-/react-router-dom-6.25.1.tgz", - "integrity": "sha512-0tUDpbFvk35iv+N89dWNrJp+afLgd+y4VtorJZuOCXK0kkCWjEvb3vTJM++SYvMEpbVwXKf3FjeVveVEb6JpDQ==", + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/react-router-dom/-/react-router-dom-7.1.1.tgz", + "integrity": "sha512-vSrQHWlJ5DCfyrhgo0k6zViOe9ToK8uT5XGSmnuC2R3/g261IdIMpZVqfjD6vWSXdnf5Czs4VA/V60oVR6/jnA==", "dependencies": { - "@remix-run/router": "1.18.0", - "react-router": "6.25.1" + "react-router": "7.1.1" }, "engines": { - "node": ">=14.0.0" + "node": ">=20.0.0" }, "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8" - } - }, - "node_modules/react-style-singleton": { - "version": "2.2.1", - "resolved": "https://registry.npmmirror.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz", - "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", - "dependencies": { - "get-nonce": "^1.0.0", - "invariant": "^2.2.4", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "react": ">=18", + "react-dom": ">=18" } }, "node_modules/reactcss": { @@ -7442,6 +7779,7 @@ "version": "1.0.0", "resolved": "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, "dependencies": { "pify": "^2.3.0" } @@ -7464,6 +7802,7 @@ "version": "3.6.0", "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -7471,6 +7810,28 @@ "node": ">=8.10.0" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.9", + "resolved": "https://registry.npmmirror.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.9.tgz", + "integrity": "sha512-r0Ay04Snci87djAsI4U+WNRcSw5S4pOH7qFjd/veA5gC7TbqESR3tcj28ia95L/fYUDw11JKP7uqUKUAfVvV5Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "dunder-proto": "^1.0.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmmirror.com/regenerate/-/regenerate-1.4.2.tgz", @@ -7503,6 +7864,24 @@ "@babel/runtime": "^7.8.4" } }, + "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==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regexpu-core": { "version": "6.2.0", "resolved": "https://registry.npmmirror.com/regexpu-core/-/regexpu-core-6.2.0.tgz", @@ -7559,6 +7938,7 @@ "version": "1.22.8", "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -7580,10 +7960,20 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -7606,12 +7996,12 @@ } }, "node_modules/rollup": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", - "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.29.1.tgz", + "integrity": "sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==", "dev": true, "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.6" }, "bin": { "rollup": "dist/bin/rollup" @@ -7621,22 +8011,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.22.4", - "@rollup/rollup-android-arm64": "4.22.4", - "@rollup/rollup-darwin-arm64": "4.22.4", - "@rollup/rollup-darwin-x64": "4.22.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", - "@rollup/rollup-linux-arm-musleabihf": "4.22.4", - "@rollup/rollup-linux-arm64-gnu": "4.22.4", - "@rollup/rollup-linux-arm64-musl": "4.22.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", - "@rollup/rollup-linux-riscv64-gnu": "4.22.4", - "@rollup/rollup-linux-s390x-gnu": "4.22.4", - "@rollup/rollup-linux-x64-gnu": "4.22.4", - "@rollup/rollup-linux-x64-musl": "4.22.4", - "@rollup/rollup-win32-arm64-msvc": "4.22.4", - "@rollup/rollup-win32-ia32-msvc": "4.22.4", - "@rollup/rollup-win32-x64-msvc": "4.22.4", + "@rollup/rollup-android-arm-eabi": "4.29.1", + "@rollup/rollup-android-arm64": "4.29.1", + "@rollup/rollup-darwin-arm64": "4.29.1", + "@rollup/rollup-darwin-x64": "4.29.1", + "@rollup/rollup-freebsd-arm64": "4.29.1", + "@rollup/rollup-freebsd-x64": "4.29.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.29.1", + "@rollup/rollup-linux-arm-musleabihf": "4.29.1", + "@rollup/rollup-linux-arm64-gnu": "4.29.1", + "@rollup/rollup-linux-arm64-musl": "4.29.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.29.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.29.1", + "@rollup/rollup-linux-riscv64-gnu": "4.29.1", + "@rollup/rollup-linux-s390x-gnu": "4.29.1", + "@rollup/rollup-linux-x64-gnu": "4.29.1", + "@rollup/rollup-linux-x64-musl": "4.29.1", + "@rollup/rollup-win32-arm64-msvc": "4.29.1", + "@rollup/rollup-win32-ia32-msvc": "4.29.1", + "@rollup/rollup-win32-x64-msvc": "4.29.1", "fsevents": "~2.3.2" } }, @@ -7644,6 +8037,7 @@ "version": "1.2.0", "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, "funding": [ { "type": "github", @@ -7662,11 +8056,75 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-stable-stringify": { "version": "2.5.0", "resolved": "https://registry.npmmirror.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", @@ -7714,6 +8172,43 @@ "node": ">=10" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmmirror.com/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmmirror.com/setimmediate/-/setimmediate-1.0.5.tgz", @@ -7728,6 +8223,7 @@ "version": "2.0.0", "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -7739,14 +8235,88 @@ "version": "3.0.0", "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, "engines": { "node": ">=8" } }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, "engines": { "node": ">=14" }, @@ -7754,15 +8324,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", @@ -7777,6 +8338,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -7792,6 +8354,12 @@ "source-map": "^0.6.0" } }, + "node_modules/stable-hash": { + "version": "0.0.4", + "resolved": "https://registry.npmmirror.com/stable-hash/-/stable-hash-0.0.4.tgz", + "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", + "dev": true + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz", @@ -7809,6 +8377,7 @@ "version": "5.1.2", "resolved": "https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -7826,6 +8395,7 @@ "version": "4.2.3", "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -7838,12 +8408,14 @@ "node_modules/string-width-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/string-width/node_modules/ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, "engines": { "node": ">=12" }, @@ -7855,6 +8427,7 @@ "version": "7.1.0", "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -7865,10 +8438,67 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmmirror.com/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmmirror.com/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -7881,6 +8511,7 @@ "version": "6.0.1", "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -7888,6 +8519,15 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -7909,6 +8549,7 @@ "version": "3.35.0", "resolved": "https://registry.npmmirror.com/sucrase/-/sucrase-3.35.0.tgz", "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", @@ -7930,6 +8571,7 @@ "version": "10.4.5", "resolved": "https://registry.npmmirror.com/glob/-/glob-10.4.5.tgz", "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -7949,6 +8591,7 @@ "version": "1.0.0", "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -7990,42 +8633,34 @@ "integrity": "sha512-Nk8c4lXvMB98MtbmjX7JwJRgJOL8fluecYCfCeYBznwmpOs8Bf15hLM6z4z71EDAhQVrQrI+wt1aLWSXZq+hXA==", "dev": true }, - "node_modules/tailwind-merge": { - "version": "2.4.0", - "resolved": "https://registry.npmmirror.com/tailwind-merge/-/tailwind-merge-2.4.0.tgz", - "integrity": "sha512-49AwoOQNKdqKPd9CViyH5wJoSKsCDjUlzL8DxuGp3P1FsGY36NJDAa18jLZcaHAUUuTj+JB8IAo8zWgBNvBF7A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/dcastil" - } - }, "node_modules/tailwindcss": { - "version": "3.4.7", - "resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.4.7.tgz", - "integrity": "sha512-rxWZbe87YJb4OcSopb7up2Ba4U82BoiSGUdoDr3Ydrg9ckxFS/YWsvhN323GMcddgU65QRy7JndC7ahhInhvlQ==", + "version": "3.4.17", + "resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "dev": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", - "chokidar": "^3.5.3", + "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.3.0", + "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "jiti": "^1.21.0", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", @@ -8039,10 +8674,20 @@ "version": "1.0.7", "resolved": "https://registry.npmmirror.com/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", + "dev": true, "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmmirror.com/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/terser": { "version": "5.37.0", "resolved": "https://registry.npmmirror.com/terser/-/terser-5.37.0.tgz", @@ -8079,6 +8724,7 @@ "version": "3.3.1", "resolved": "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, "dependencies": { "any-promise": "^1.0.0" } @@ -8087,6 +8733,7 @@ "version": "1.6.0", "resolved": "https://registry.npmmirror.com/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -8111,6 +8758,7 @@ "version": "5.0.1", "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -8123,15 +8771,10 @@ "resolved": "https://registry.npmmirror.com/toggle-selection/-/toggle-selection-1.0.6.tgz", "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmmirror.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "version": "1.4.3", + "resolved": "https://registry.npmmirror.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", "dev": true, "engines": { "node": ">=16" @@ -8143,13 +8786,43 @@ "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmmirror.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } }, "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.6.3.tgz", "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, + "node_modules/turbo-stream": { + "version": "2.4.0", + "resolved": "https://registry.npmmirror.com/turbo-stream/-/turbo-stream-2.4.0.tgz", + "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz", @@ -8174,11 +8847,85 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "devOptional": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -8187,10 +8934,28 @@ "node": ">=14.17" } }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/undici-types": { - "version": "6.11.1", - "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.11.1.tgz", - "integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ==", + "version": "6.20.0", + "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "dev": true }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -8281,47 +9046,6 @@ "punycode": "^2.1.0" } }, - "node_modules/use-callback-ref": { - "version": "1.3.2", - "resolved": "https://registry.npmmirror.com/use-callback-ref/-/use-callback-ref-1.3.2.tgz", - "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/use-sidecar": { - "version": "1.1.2", - "resolved": "https://registry.npmmirror.com/use-sidecar/-/use-sidecar-1.1.2.tgz", - "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", - "dependencies": { - "detect-node-es": "^1.1.0", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/use-sync-external-store": { "version": "1.2.2", "resolved": "https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", @@ -8336,20 +9060,20 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/vite": { - "version": "5.4.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", - "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", + "version": "6.0.6", + "resolved": "https://registry.npmmirror.com/vite/-/vite-6.0.6.tgz", + "integrity": "sha512-NSjmUuckPmDU18bHz7QZ+bTYhRR0iA72cs2QAxCqDpafJ0S6qetco0LB3WW2OxlMHS0JmAv+yZ/R3uPmMyGTjQ==", "dev": true, "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" + "esbuild": "^0.24.2", + "postcss": "^8.4.49", + "rollup": "^4.23.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -8358,19 +9082,25 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", - "terser": "^5.4.0" + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "jiti": { + "optional": true + }, "less": { "optional": true }, @@ -8391,6 +9121,12 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, @@ -8410,24 +9146,11 @@ "loose-envify": "^1.0.0" } }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -8438,6 +9161,96 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz", @@ -8451,6 +9264,7 @@ "version": "8.1.0", "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -8468,6 +9282,7 @@ "version": "7.0.0", "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8484,6 +9299,7 @@ "version": "4.3.0", "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -8498,6 +9314,7 @@ "version": "2.0.1", "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -8508,17 +9325,20 @@ "node_modules/wrap-ansi-cjs/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -8532,6 +9352,7 @@ "version": "6.0.1", "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, "engines": { "node": ">=12" }, @@ -8543,6 +9364,7 @@ "version": "6.2.1", "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, "engines": { "node": ">=12" }, @@ -8554,6 +9376,7 @@ "version": "7.1.0", "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -8580,6 +9403,7 @@ "version": "2.5.0", "resolved": "https://registry.npmmirror.com/yaml/-/yaml-2.5.0.tgz", "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", + "dev": true, "bin": { "yaml": "bin.mjs" }, @@ -8600,17 +9424,17 @@ } }, "node_modules/zod": { - "version": "3.23.8", - "resolved": "https://registry.npmmirror.com/zod/-/zod-3.23.8.tgz", - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "version": "3.24.1", + "resolved": "https://registry.npmmirror.com/zod/-/zod-3.24.1.tgz", + "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", "funding": { "url": "https://github.com/sponsors/colinhacks" } }, "node_modules/zustand": { - "version": "5.0.1", - "resolved": "https://registry.npmmirror.com/zustand/-/zustand-5.0.1.tgz", - "integrity": "sha512-pRET7Lao2z+n5R/HduXMio35TncTlSW68WsYBq2Lg1ASspsNGjpwLAsij3RpouyV6+kHMwwwzP0bZPD70/Jx/w==", + "version": "5.0.2", + "resolved": "https://registry.npmmirror.com/zustand/-/zustand-5.0.2.tgz", + "integrity": "sha512-8qNdnJVJlHlrKXi50LDqqUNmUbuBjoKLrYQBnoChIbVph7vni+sY+YpvdjXG9YLd/Bxr6scMcR+rm5H3aSqPaw==", "engines": { "node": ">=12.20.0" }, diff --git a/ui/package.json b/ui/package.json index a2feb4ee..3d390b94 100644 --- a/ui/package.json +++ b/ui/package.json @@ -10,61 +10,53 @@ "preview": "vite preview" }, "dependencies": { + "@ant-design/icons": "^5.5.2", "@ant-design/pro-components": "^2.8.2", - "@hookform/resolvers": "^3.9.0", - "@radix-ui/react-dialog": "^1.1.2", - "@radix-ui/react-dropdown-menu": "^2.1.1", - "@radix-ui/react-label": "^2.1.0", - "@radix-ui/react-scroll-area": "^1.1.0", - "@radix-ui/react-select": "^2.1.1", - "@radix-ui/react-slot": "^1.1.0", - "@tanstack/react-table": "^8.20.5", "ahooks": "^3.8.4", - "antd": "^5.22.2", + "antd": "^5.22.7", "antd-zod": "^6.0.0", - "class-variance-authority": "^0.7.0", - "clsx": "^2.1.1", "cron-parser": "^4.9.0", - "i18next": "^23.15.1", - "i18next-browser-languagedetector": "^8.0.0", - "i18next-http-backend": "^2.6.1", + "i18next": "^24.2.0", + "i18next-browser-languagedetector": "^8.0.2", "immer": "^10.1.1", "jszip": "^3.10.1", - "lucide-react": "^0.417.0", - "nanoid": "^5.0.7", - "pocketbase": "^0.21.4", + "lucide-react": "^0.469.0", + "nanoid": "^5.0.9", + "pocketbase": "^0.21.5", + "radash": "^12.1.0", "react": "^18.3.1", "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.3.1", - "react-hook-form": "^7.52.1", - "react-i18next": "^15.0.2", - "react-router-dom": "^6.25.1", - "tailwind-merge": "^2.4.0", - "tailwindcss-animate": "^1.0.7", - "zod": "^3.23.8", - "zustand": "^5.0.1" + "react-i18next": "^15.4.0", + "react-router-dom": "^7.1.1", + "zod": "^3.24.1", + "zustand": "^5.0.2" }, "devDependencies": { "@types/fs-extra": "^11.0.4", - "@types/node": "^22.0.0", - "@types/react": "^18.3.3", + "@types/node": "^22.10.3", + "@types/react": "^18.3.12", "@types/react-copy-to-clipboard": "^5.0.7", - "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^7.15.0", - "@typescript-eslint/parser": "^7.15.0", - "@vitejs/plugin-legacy": "^5.4.3", - "@vitejs/plugin-react": "^4.3.1", - "autoprefixer": "^10.4.19", + "@types/react-dom": "^18.3.1", + "@typescript-eslint/eslint-plugin": "^8.19.0", + "@typescript-eslint/parser": "^8.19.0", + "@vitejs/plugin-legacy": "^6.0.0", + "@vitejs/plugin-react": "^4.3.4", + "autoprefixer": "^10.4.20", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.7.0", + "eslint-plugin-import": "^2.31.0", "eslint-plugin-prettier": "^5.2.1", - "eslint-plugin-react-hooks": "^4.6.2", - "eslint-plugin-react-refresh": "^0.4.7", + "eslint-plugin-react-hooks": "^5.1.0", + "eslint-plugin-react-refresh": "^0.4.16", + "eslint-plugin-tailwindcss": "^3.17.5", "fs-extra": "^11.2.0", - "postcss": "^8.4.40", - "prettier": "^3.3.3", - "tailwindcss": "^3.4.7", - "typescript": "^5.6.2", - "vite": "^5.3.4" + "postcss": "^8.4.49", + "prettier": "^3.4.2", + "tailwindcss": "^3.4.17", + "tailwindcss-animate": "^1.0.7", + "typescript": "^5.7.2", + "vite": "^6.0.6" } } diff --git a/ui/public/imgs/workflow/tpl-blank.png b/ui/public/imgs/workflow/tpl-blank.png new file mode 100644 index 00000000..8f683ce6 Binary files /dev/null and b/ui/public/imgs/workflow/tpl-blank.png differ diff --git a/ui/public/imgs/workflow/tpl-standard.png b/ui/public/imgs/workflow/tpl-standard.png new file mode 100644 index 00000000..46698a87 Binary files /dev/null and b/ui/public/imgs/workflow/tpl-standard.png differ diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 481631ff..939f7b3d 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -1,16 +1,16 @@ import { useEffect, useLayoutEffect, useMemo, useState } from "react"; -import { RouterProvider } from "react-router-dom"; import { useTranslation } from "react-i18next"; -import { App, ConfigProvider, theme, type ThemeConfig } from "antd"; +import { RouterProvider } from "react-router-dom"; +import { App, ConfigProvider, type ThemeConfig, theme } from "antd"; import { type Locale } from "antd/es/locale"; import AntdLocaleEnUs from "antd/locale/en_US"; import AntdLocaleZhCN from "antd/locale/zh_CN"; import dayjs from "dayjs"; import "dayjs/locale/zh-cn"; -import { localeNames } from "./i18n"; -import { useBrowserTheme } from "./hooks"; -import { router } from "./router.tsx"; +import { useBrowserTheme } from "@/hooks"; +import { localeNames } from "@/i18n"; +import { router } from "@/router.tsx"; const RootApp = () => { const { i18n } = useTranslation(); @@ -30,7 +30,13 @@ const RootApp = () => { dayjs.locale(i18n.language); }; i18n.on("languageChanged", handleLanguageChanged); - useLayoutEffect(handleLanguageChanged, [antdLocalesMap, i18n]); + useLayoutEffect(() => { + handleLanguageChanged(); + + return () => { + i18n.off("languageChanged", handleLanguageChanged); + }; + }, [antdLocalesMap, i18n]); const antdThemesMap: Record = useMemo( () => ({ @@ -54,7 +60,9 @@ const RootApp = () => { theme={{ ...antdTheme, token: { - colorPrimary: "hsl(24.6 95% 53.1%)", + /* @see tailwind.config.js */ + colorPrimary: browserTheme === "dark" ? "hsl(20.5 90.2% 48.2%)" : "hsl(24.6 95% 53.1%)", + colorLink: browserTheme === "dark" ? "hsl(20.5 90.2% 48.2%)" : "hsl(24.6 95% 53.1%)", }, }} > diff --git a/ui/src/api/notify.ts b/ui/src/api/notify.ts index 98a579c8..6eb078ab 100644 --- a/ui/src/api/notify.ts +++ b/ui/src/api/notify.ts @@ -1,3 +1,5 @@ +import { ClientResponseError } from "pocketbase"; + import { getPocketBase } from "@/repository/pocketbase"; export const notifyTest = async (channel: string) => { @@ -14,7 +16,7 @@ export const notifyTest = async (channel: string) => { }); if (resp.code != 0) { - throw new Error(resp.msg); + throw new ClientResponseError({ status: resp.code, response: resp, data: {} }); } return resp; diff --git a/ui/src/api/statistics.ts b/ui/src/api/statistics.ts index fb5e8b94..6c1d422c 100644 --- a/ui/src/api/statistics.ts +++ b/ui/src/api/statistics.ts @@ -1,4 +1,6 @@ -import { Statistics } from "@/domain/statistics"; +import { ClientResponseError } from "pocketbase"; + +import { type Statistics } from "@/domain/statistics"; import { getPocketBase } from "@/repository/pocketbase"; export const get = async () => { @@ -8,8 +10,8 @@ export const get = async () => { method: "GET", }); - if (resp.code !== 0) { - throw new Error(resp.msg); + if (resp.code != 0) { + throw new ClientResponseError({ status: resp.code, response: resp, data: {} }); } return resp.data as Statistics; diff --git a/ui/src/api/workflow.ts b/ui/src/api/workflow.ts index 9fcf94a4..f746e2c0 100644 --- a/ui/src/api/workflow.ts +++ b/ui/src/api/workflow.ts @@ -1,3 +1,6 @@ +import { ClientResponseError } from "pocketbase"; + +import { WORKFLOW_TRIGGERS } from "@/domain/workflow"; import { getPocketBase } from "@/repository/pocketbase"; export const run = async (id: string) => { @@ -9,12 +12,13 @@ export const run = async (id: string) => { "Content-Type": "application/json", }, body: { - id, + workflowId: id, + trigger: WORKFLOW_TRIGGERS.MANUAL, }, }); if (resp.code != 0) { - throw new Error(resp.msg); + throw new ClientResponseError({ status: resp.code, response: resp, data: {} }); } return resp; diff --git a/ui/src/components/DrawerForm.tsx b/ui/src/components/DrawerForm.tsx new file mode 100644 index 00000000..0c319fb6 --- /dev/null +++ b/ui/src/components/DrawerForm.tsx @@ -0,0 +1,136 @@ +import { useTranslation } from "react-i18next"; +import { useControllableValue } from "ahooks"; +import { Button, Drawer, type DrawerProps, Form, type FormProps, type ModalProps, Space } from "antd"; + +import { useAntdForm, useTriggerElement } from "@/hooks"; + +export interface DrawerFormProps = any> extends Omit, "title" | "onFinish"> { + className?: string; + style?: React.CSSProperties; + children?: React.ReactNode; + cancelButtonProps?: ModalProps["cancelButtonProps"]; + cancelText?: ModalProps["cancelText"]; + defaultOpen?: boolean; + drawerProps?: Omit; + okButtonProps?: ModalProps["okButtonProps"]; + okText?: ModalProps["okText"]; + open?: boolean; + title?: React.ReactNode; + trigger?: React.ReactNode; + width?: string | number; + onClose?: (e: React.MouseEvent | React.KeyboardEvent) => void | Promise; + onFinish?: (values: T) => unknown | Promise; + onOpenChange?: (open: boolean) => void; +} + +const DrawerForm = = any>({ + className, + style, + children, + cancelText, + cancelButtonProps, + form, + drawerProps, + okText, + okButtonProps, + title, + trigger, + width, + onFinish, + ...props +}: DrawerFormProps) => { + const { t } = useTranslation(); + + const [open, setOpen] = useControllableValue(props, { + valuePropName: "open", + defaultValuePropName: "defaultOpen", + trigger: "onOpenChange", + }); + + const triggerEl = useTriggerElement(trigger, { + onClick: () => { + console.log("click"); + setOpen(true); + console.log(open); + }, + }); + + const { + form: formInst, + formPending, + formProps, + submit, + } = useAntdForm({ + form, + onSubmit: (values) => { + return onFinish?.(values); + }, + }); + + const mergedFormProps: FormProps = { + clearOnDestroy: drawerProps?.destroyOnClose ? true : undefined, + ...formProps, + ...props, + }; + + const mergedDrawerProps: DrawerProps = { + ...drawerProps, + afterOpenChange: (open) => { + if (!open && !mergedFormProps.preserve) { + formInst.resetFields(); + } + + drawerProps?.afterOpenChange?.(open); + }, + onClose: async (e) => { + if (formPending) return; + + // 关闭 Drawer 时 Promise.reject 阻止关闭 + await drawerProps?.onClose?.(e); + setOpen(false); + }, + }; + + const handleOkClick = async () => { + // 提交表单返回 Promise.reject 时不关闭 Drawer + await submit(); + + setOpen(false); + }; + + const handleCancelClick = () => { + if (formPending) return; + + setOpen(false); + }; + + return ( + <> + {triggerEl} + + + + + + } + forceRender + open={open} + title={title} + width={width} + > +
+ {children} +
+
+ + ); +}; + +export default DrawerForm; diff --git a/ui/src/components/ModalForm.tsx b/ui/src/components/ModalForm.tsx new file mode 100644 index 00000000..1bf84c79 --- /dev/null +++ b/ui/src/components/ModalForm.tsx @@ -0,0 +1,142 @@ +import { useControllableValue } from "ahooks"; +import { Form, type FormProps, Modal, type ModalProps } from "antd"; + +import { useAntdForm, useTriggerElement } from "@/hooks"; + +export interface ModalFormProps = any> extends Omit, "title" | "onFinish"> { + className?: string; + style?: React.CSSProperties; + children?: React.ReactNode; + cancelButtonProps?: ModalProps["cancelButtonProps"]; + cancelText?: ModalProps["cancelText"]; + defaultOpen?: boolean; + modalProps?: Omit< + ModalProps, + | "cancelButtonProps" + | "cancelText" + | "confirmLoading" + | "defaultOpen" + | "forceRender" + | "okButtonProps" + | "okText" + | "okType" + | "open" + | "title" + | "width" + | "onCancel" + | "onOk" + | "onOpenChange" + >; + okButtonProps?: ModalProps["okButtonProps"]; + okText?: ModalProps["okText"]; + open?: boolean; + title?: ModalProps["title"]; + trigger?: React.ReactNode; + width?: ModalProps["width"]; + onClose?: (e: React.MouseEvent | React.KeyboardEvent) => void | Promise; + onFinish?: (values: T) => unknown | Promise; + onOpenChange?: (open: boolean) => void; +} + +const ModalForm = = any>({ + className, + style, + children, + cancelButtonProps, + cancelText, + form, + modalProps, + okButtonProps, + okText, + title, + trigger, + width, + onFinish, + ...props +}: ModalFormProps) => { + const [open, setOpen] = useControllableValue(props, { + valuePropName: "open", + defaultValuePropName: "defaultOpen", + trigger: "onOpenChange", + }); + + const triggerEl = useTriggerElement(trigger, { onClick: () => setOpen(true) }); + + const { + form: formInst, + formPending, + formProps, + submit: submitForm, + } = useAntdForm({ + form, + onSubmit: (values) => { + return onFinish?.(values); + }, + }); + + const mergedFormProps: FormProps = { + clearOnDestroy: modalProps?.destroyOnClose ? true : undefined, + ...formProps, + ...props, + }; + + const mergedModalProps: ModalProps = { + ...modalProps, + afterClose: () => { + if (!mergedFormProps.preserve) { + formInst.resetFields(); + } + + modalProps?.afterClose?.(); + }, + onClose: async (e) => { + if (formPending) return; + + // 关闭 Modal 时 Promise.reject 阻止关闭 + await modalProps?.onClose?.(e as React.MouseEvent | React.KeyboardEvent); + setOpen(false); + }, + }; + + const handleOkClick = async () => { + // 提交表单返回 Promise.reject 时不关闭 Modal + await submitForm(); + setOpen(false); + }; + + const handleCancelClick = () => { + if (formPending) return; + + setOpen(false); + }; + + return ( + <> + {triggerEl} + + +
+
+ {children} +
+
+
+ + ); +}; + +export default ModalForm; diff --git a/ui/src/components/MultipleInput.tsx b/ui/src/components/MultipleInput.tsx new file mode 100644 index 00000000..f1383e34 --- /dev/null +++ b/ui/src/components/MultipleInput.tsx @@ -0,0 +1,273 @@ +import { type ChangeEvent, forwardRef, useImperativeHandle, useMemo, useRef } from "react"; +import { useTranslation } from "react-i18next"; +import { + ArrowDownOutlined as ArrowDownOutlinedIcon, + ArrowUpOutlined as ArrowUpOutlinedIcon, + MinusOutlined as MinusOutlinedIcon, + PlusOutlined as PlusOutlinedIcon, +} from "@ant-design/icons"; +import { useControllableValue } from "ahooks"; +import { Button, Input, type InputProps, type InputRef, Space } from "antd"; +import { produce } from "immer"; + +export type MultipleInputProps = Omit & { + allowClear?: boolean; + defaultValue?: string[]; + maxCount?: number; + minCount?: number; + showSortButton?: boolean; + value?: string[]; + onChange?: (value: string[]) => void; + onValueChange?: (index: number, element: string) => void; + onValueCreate?: (index: number) => void; + onValueRemove?: (index: number) => void; + onValueSort?: (oldIndex: number, newIndex: number) => void; +}; + +const MultipleInput = ({ + allowClear = false, + disabled, + maxCount, + minCount, + showSortButton = true, + onValueChange, + onValueCreate, + onValueSort, + onValueRemove, + ...props +}: MultipleInputProps) => { + const { t } = useTranslation(); + + const itemRefs = useRef([]); + + const [value, setValue] = useControllableValue(props, { + valuePropName: "value", + defaultValue: [], + defaultValuePropName: "defaultValue", + trigger: "onChange", + }); + + const handleCreate = () => { + const newValue = produce(value ?? [], (draft) => { + draft.push(""); + }); + setValue(newValue); + setTimeout(() => itemRefs.current[newValue.length - 1]?.focus(), 0); + + onValueCreate?.(newValue.length - 1); + }; + + const handleChange = (index: number, element: string) => { + const newValue = produce(value, (draft) => { + draft[index] = element; + }); + setValue(newValue); + + onValueChange?.(index, element); + }; + + const handleInputBlur = (index: number) => { + if (!allowClear && !value[index]) { + const newValue = produce(value, (draft) => { + draft.splice(index, 1); + }); + setValue(newValue); + } + }; + + const handleClickUp = (index: number) => { + if (index === 0) { + return; + } + + const newValue = produce(value, (draft) => { + const temp = draft[index - 1]; + draft[index - 1] = draft[index]; + draft[index] = temp; + }); + setValue(newValue); + + onValueSort?.(index, index - 1); + }; + + const handleClickDown = (index: number) => { + if (index === value.length - 1) { + return; + } + + const newValue = produce(value, (draft) => { + const temp = draft[index + 1]; + draft[index + 1] = draft[index]; + draft[index] = temp; + }); + setValue(newValue); + + onValueSort?.(index, index + 1); + }; + + const handleClickAdd = (index: number) => { + const newValue = produce(value, (draft) => { + draft.splice(index + 1, 0, ""); + }); + setValue(newValue); + setTimeout(() => itemRefs.current[index + 1]?.focus(), 0); + + onValueCreate?.(index + 1); + }; + + const handleClickRemove = (index: number) => { + const newValue = produce(value, (draft) => { + draft.splice(index, 1); + }); + setValue(newValue); + + onValueRemove?.(index); + }; + + return value == null || value.length === 0 ? ( + + ) : ( + + {Array.from(value).map((element, index) => { + const allowUp = index > 0; + const allowDown = index < value.length - 1; + const allowRemove = minCount == null || value.length > minCount; + const allowAdd = maxCount == null || value.length < maxCount; + + return ( + (itemRefs.current[index] = ref!)} + allowAdd={allowAdd} + allowClear={allowClear} + allowDown={allowDown} + allowRemove={allowRemove} + allowUp={allowUp} + disabled={disabled} + defaultValue={undefined} + showSortButton={showSortButton} + value={element} + onBlur={() => handleInputBlur(index)} + onChange={(val) => handleChange(index, val)} + onClickAdd={() => handleClickAdd(index)} + onClickDown={() => handleClickDown(index)} + onClickUp={() => handleClickUp(index)} + onClickRemove={() => handleClickRemove(index)} + /> + ); + })} + + ); +}; + +type MultipleInputItemProps = Omit< + MultipleInputProps, + "defaultValue" | "maxCount" | "minCount" | "preset" | "value" | "onChange" | "onValueCreate" | "onValueRemove" | "onValueSort" | "onValueChange" +> & { + allowAdd: boolean; + allowRemove: boolean; + allowUp: boolean; + allowDown: boolean; + defaultValue?: string; + value?: string; + onChange?: (value: string) => void; + onClickAdd?: () => void; + onClickDown?: () => void; + onClickUp?: () => void; + onClickRemove?: () => void; +}; + +type MultipleInputItemInstance = { + focus: InputRef["focus"]; + blur: InputRef["blur"]; + select: InputRef["select"]; +}; + +const MultipleInputItem = forwardRef( + ( + { + allowAdd, + allowClear, + allowDown, + allowRemove, + allowUp, + disabled, + showSortButton, + size, + onClickAdd, + onClickDown, + onClickUp, + onClickRemove, + ...props + }: MultipleInputItemProps, + ref + ) => { + const inputRef = useRef(null); + + const [value, setValue] = useControllableValue(props, { + valuePropName: "value", + defaultValue: "", + defaultValuePropName: "defaultValue", + trigger: "onChange", + }); + + const upBtn = useMemo(() => { + if (!showSortButton) return null; + return - - - - ); -}; - -export default AccessEditFormKubernetesConfig; diff --git a/ui/src/components/access/AccessEditFormLocalConfig.tsx b/ui/src/components/access/AccessEditFormLocalConfig.tsx deleted file mode 100644 index 94e8e40a..00000000 --- a/ui/src/components/access/AccessEditFormLocalConfig.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { useState } from "react"; -import { useDeepCompareEffect } from "ahooks"; -import { Form, type FormInstance } from "antd"; - -import { type LocalAccessConfig } from "@/domain/access"; - -type AccessEditFormLocalConfigModelType = Partial; - -export type AccessEditFormLocalConfigProps = { - form: FormInstance; - formName: string; - disabled?: boolean; - loading?: boolean; - model?: AccessEditFormLocalConfigModelType; - onModelChange?: (model: AccessEditFormLocalConfigModelType) => void; -}; - -const initModel = () => { - return {} as AccessEditFormLocalConfigModelType; -}; - -const AccessEditFormLocalConfig = ({ form, formName, disabled, loading, model }: AccessEditFormLocalConfigProps) => { - const [initialValues, setInitialValues] = useState(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - return
; -}; - -export default AccessEditFormLocalConfig; diff --git a/ui/src/components/access/AccessEditFormNameSiloConfig.tsx b/ui/src/components/access/AccessEditFormNameSiloConfig.tsx deleted file mode 100644 index 7ac252bd..00000000 --- a/ui/src/components/access/AccessEditFormNameSiloConfig.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { useState } from "react"; -import { useTranslation } from "react-i18next"; -import { useDeepCompareEffect } from "ahooks"; -import { Form, Input, type FormInstance } from "antd"; -import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; - -import { type NameSiloAccessConfig } from "@/domain/access"; - -type AccessEditFormNameSiloConfigModelType = Partial; - -export type AccessEditFormNameSiloConfigProps = { - form: FormInstance; - formName: string; - disabled?: boolean; - loading?: boolean; - model?: AccessEditFormNameSiloConfigModelType; - onModelChange?: (model: AccessEditFormNameSiloConfigModelType) => void; -}; - -const initModel = () => { - return { - apiKey: "", - } as AccessEditFormNameSiloConfigModelType; -}; - -const AccessEditFormNameSiloConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormNameSiloConfigProps) => { - const { t } = useTranslation(); - - const formSchema = z.object({ - apiKey: z - .string() - .trim() - .min(1, t("access.form.namesilo_api_key.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), - }); - const formRule = createSchemaFieldRule(formSchema); - - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - const handleFormChange = (_: unknown, fields: AccessEditFormNameSiloConfigModelType) => { - onModelChange?.(fields); - }; - - return ( -
- } - > - - -
- ); -}; - -export default AccessEditFormNameSiloConfig; diff --git a/ui/src/components/access/AccessEditFormSSHConfig.tsx b/ui/src/components/access/AccessEditFormSSHConfig.tsx deleted file mode 100644 index e4843f9b..00000000 --- a/ui/src/components/access/AccessEditFormSSHConfig.tsx +++ /dev/null @@ -1,165 +0,0 @@ -import { useState } from "react"; -import { flushSync } from "react-dom"; -import { useTranslation } from "react-i18next"; -import { useDeepCompareEffect } from "ahooks"; -import { Button, Form, Input, InputNumber, Upload, type FormInstance, type UploadFile, type UploadProps } from "antd"; -import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; -import { Upload as UploadIcon } from "lucide-react"; - -import { type SSHAccessConfig } from "@/domain/access"; -import { readFileContent } from "@/utils/file"; - -type AccessEditFormSSHConfigModelType = Partial; - -export type AccessEditFormSSHConfigProps = { - form: FormInstance; - formName: string; - disabled?: boolean; - loading?: boolean; - model?: AccessEditFormSSHConfigModelType; - onModelChange?: (model: AccessEditFormSSHConfigModelType) => void; -}; - -const initModel = () => { - return { - host: "127.0.0.1", - port: 22, - username: "root", - } as AccessEditFormSSHConfigModelType; -}; - -const AccessEditFormSSHConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormSSHConfigProps) => { - const { t } = useTranslation(); - - const formSchema = z.object({ - host: z.string().refine( - (str) => { - const reIpv4 = - /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; - const reIpv6 = - /^([\da-fA-F]{1,4}:){6}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)|::([\da−fA−F]1,4:)0,4((25[0−5]|2[0−4]\d|[01]?\d\d?)\.)3(25[0−5]|2[0−4]\d|[01]?\d\d?)|::([\da−fA−F]1,4:)0,4((25[0−5]|2[0−4]\d|[01]?\d\d?)\.)3(25[0−5]|2[0−4]\d|[01]?\d\d?)|^([\da-fA-F]{1,4}:):([\da-fA-F]{1,4}:){0,3}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)|([\da−fA−F]1,4:)2:([\da−fA−F]1,4:)0,2((25[0−5]|2[0−4]\d|[01]?\d\d?)\.)3(25[0−5]|2[0−4]\d|[01]?\d\d?)|([\da−fA−F]1,4:)2:([\da−fA−F]1,4:)0,2((25[0−5]|2[0−4]\d|[01]?\d\d?)\.)3(25[0−5]|2[0−4]\d|[01]?\d\d?)|^([\da-fA-F]{1,4}:){3}:([\da-fA-F]{1,4}:){0,1}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)|([\da−fA−F]1,4:)4:((25[0−5]|2[0−4]\d|[01]?\d\d?)\.)3(25[0−5]|2[0−4]\d|[01]?\d\d?)|([\da−fA−F]1,4:)4:((25[0−5]|2[0−4]\d|[01]?\d\d?)\.)3(25[0−5]|2[0−4]\d|[01]?\d\d?)|^([\da-fA-F]{1,4}:){7}[\da-fA-F]{1,4}|:((:[\da−fA−F]1,4)1,6|:)|:((:[\da−fA−F]1,4)1,6|:)|^[\da-fA-F]{1,4}:((:[\da-fA-F]{1,4}){1,5}|:)|([\da−fA−F]1,4:)2((:[\da−fA−F]1,4)1,4|:)|([\da−fA−F]1,4:)2((:[\da−fA−F]1,4)1,4|:)|^([\da-fA-F]{1,4}:){3}((:[\da-fA-F]{1,4}){1,3}|:)|([\da−fA−F]1,4:)4((:[\da−fA−F]1,4)1,2|:)|([\da−fA−F]1,4:)4((:[\da−fA−F]1,4)1,2|:)|^([\da-fA-F]{1,4}:){5}:([\da-fA-F]{1,4})?|([\da−fA−F]1,4:)6:|([\da−fA−F]1,4:)6:/; - const reDomain = /^(?:\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$/; - return reIpv4.test(str) || reIpv6.test(str) || reDomain.test(str); - }, - { message: t("common.errmsg.host_invalid") } - ), - port: z - .number() - .int() - .gte(1, t("common.errmsg.port_invalid")) - .lte(65535, t("common.errmsg.port_invalid")) - .transform((v) => +v), - username: z - .string() - .min(1, "access.form.ssh_username.placeholder") - .max(64, t("common.errmsg.string_max", { max: 64 })), - password: z - .string() - .min(0, "access.form.ssh_password.placeholder") - .max(64, t("common.errmsg.string_max", { max: 64 })) - .nullish(), - key: z - .string() - .min(0, "access.form.ssh_key.placeholder") - .max(20480, t("common.errmsg.string_max", { max: 20480 })) - .nullish(), - keyPassphrase: z - .string() - .min(0, "access.form.ssh_key_passphrase.placeholder") - .max(20480, t("common.errmsg.string_max", { max: 20480 })) - .nullish() - .refine((v) => !v || form.getFieldValue("key"), { message: t("access.form.ssh_key.placeholder") }), - }); - const formRule = createSchemaFieldRule(formSchema); - - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - setKeyFileList(model?.key?.trim() ? [{ uid: "-1", name: "sshkey", status: "done" }] : []); - }, [model]); - - const [keyFileList, setKeyFileList] = useState([]); - - const handleFormChange = (_: unknown, fields: AccessEditFormSSHConfigModelType) => { - onModelChange?.(fields); - }; - - const handleUploadChange: UploadProps["onChange"] = async ({ file }) => { - if (file && file.status !== "removed") { - form.setFieldValue("kubeConfig", (await readFileContent(file.originFileObj ?? (file as unknown as File))).trim()); - setKeyFileList([file]); - } else { - form.setFieldValue("kubeConfig", ""); - setKeyFileList([]); - } - - flushSync(() => onModelChange?.(form.getFieldsValue(true))); - }; - - return ( -
-
-
- - - -
- -
- - - -
-
- -
-
- - - -
- -
- } - > - - -
-
- -
-
- } - > - -
- -
- } - > - - -
-
-
- ); -}; - -export default AccessEditFormSSHConfig; diff --git a/ui/src/components/access/AccessEditFormWebhookConfig.tsx b/ui/src/components/access/AccessEditFormWebhookConfig.tsx deleted file mode 100644 index 546dfc3b..00000000 --- a/ui/src/components/access/AccessEditFormWebhookConfig.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { useEffect, useState } from "react"; -import { useTranslation } from "react-i18next"; -import { Form, Input, type FormInstance } from "antd"; -import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; - -import { type WebhookAccessConfig } from "@/domain/access"; - -type AccessEditFormWebhookConfigModelType = Partial; - -export type AccessEditFormWebhookConfigProps = { - form: FormInstance; - formName: string; - disabled?: boolean; - loading?: boolean; - model?: AccessEditFormWebhookConfigModelType; - onModelChange?: (model: AccessEditFormWebhookConfigModelType) => void; -}; - -const initModel = () => { - return { - url: "", - } as AccessEditFormWebhookConfigModelType; -}; - -const AccessEditFormWebhookConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormWebhookConfigProps) => { - const { t } = useTranslation(); - - const formSchema = z.object({ - url: z - .string() - .min(1, { message: t("access.form.webhook_url.placeholder") }) - .url({ message: t("common.errmsg.url_invalid") }), - }); - const formRule = createSchemaFieldRule(formSchema); - - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - const handleFormChange = (_: unknown, fields: AccessEditFormWebhookConfigModelType) => { - onModelChange?.(fields); - }; - - return ( -
- - - -
- ); -}; - -export default AccessEditFormWebhookConfig; diff --git a/ui/src/components/access/AccessEditModal.tsx b/ui/src/components/access/AccessEditModal.tsx index 7e06cfb6..067dc339 100644 --- a/ui/src/components/access/AccessEditModal.tsx +++ b/ui/src/components/access/AccessEditModal.tsx @@ -1,28 +1,32 @@ -import { cloneElement, useMemo, useRef, useState } from "react"; +import { useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { useControllableValue } from "ahooks"; import { Modal, notification } from "antd"; import { type AccessModel } from "@/domain/access"; -import { useAccessStore } from "@/stores/access"; +import { accessProvidersMap } from "@/domain/provider"; +import { useTriggerElement, useZustandShallowSelector } from "@/hooks"; +import { useAccessesStore } from "@/stores/access"; import { getErrMsg } from "@/utils/error"; -import AccessEditForm, { type AccessEditFormInstance, type AccessEditFormProps } from "./AccessEditForm"; + +import AccessForm, { type AccessFormInstance, type AccessFormProps } from "./AccessForm"; export type AccessEditModalProps = { - data?: AccessEditFormProps["model"]; + data?: AccessFormProps["initialValues"]; loading?: boolean; - mode: AccessEditFormProps["mode"]; open?: boolean; - trigger?: React.ReactElement; + preset: AccessFormProps["preset"]; + trigger?: React.ReactNode; onOpenChange?: (open: boolean) => void; + afterSubmit?: (record: AccessModel) => void; }; -const AccessEditModal = ({ data, loading, mode, trigger, ...props }: AccessEditModalProps) => { +const AccessEditModal = ({ data, loading, trigger, preset, afterSubmit, ...props }: AccessEditModalProps) => { const { t } = useTranslation(); const [notificationApi, NotificationContextHolder] = notification.useNotification(); - const { createAccess, updateAccess } = useAccessStore(); + const { createAccess, updateAccess } = useAccessesStore(useZustandShallowSelector(["createAccess", "updateAccess"])); const [open, setOpen] = useControllableValue(props, { valuePropName: "open", @@ -30,47 +34,41 @@ const AccessEditModal = ({ data, loading, mode, trigger, ...props }: AccessEditM trigger: "onOpenChange", }); - const triggerEl = useMemo(() => { - if (!trigger) { - return null; - } + const triggerEl = useTriggerElement(trigger, { onClick: () => setOpen(true) }); - return cloneElement(trigger, { - ...trigger.props, - onClick: () => { - setOpen(true); - trigger.props?.onClick?.(); - }, - }); - }, [trigger, setOpen]); - - const formRef = useRef(null); + const formRef = useRef(null); const [formPending, setFormPending] = useState(false); - const handleClickOk = async () => { + const handleOkClick = async () => { setFormPending(true); try { await formRef.current!.validateFields(); } catch (err) { setFormPending(false); - return Promise.reject(); + throw err; } try { - if (mode === "add") { + let values: AccessModel = formRef.current!.getFieldsValue(); + values.usage = accessProvidersMap.get(values.provider)!.usage; + + if (preset === "add") { if (data?.id) { throw "Invalid props: `data`"; } - await createAccess(formRef.current!.getFieldsValue() as AccessModel); - } else if (mode === "edit") { + values = await createAccess(values); + } else if (preset === "edit") { if (!data?.id) { throw "Invalid props: `data`"; } - await updateAccess({ ...data, ...formRef.current!.getFieldsValue() } as AccessModel); + values = await updateAccess({ ...data, ...values }); + } else { + throw "Invalid props: `preset`"; } + afterSubmit?.(values); setOpen(false); } catch (err) { notificationApi.error({ message: t("common.text.request_error"), description: getErrMsg(err) }); @@ -81,8 +79,8 @@ const AccessEditModal = ({ data, loading, mode, trigger, ...props }: AccessEditM } }; - const handleClickCancel = () => { - if (formPending) return Promise.reject(); + const handleCancelClick = () => { + if (formPending) return; setOpen(false); }; @@ -100,14 +98,15 @@ const AccessEditModal = ({ data, loading, mode, trigger, ...props }: AccessEditM confirmLoading={formPending} destroyOnClose loading={loading} - okText={mode === "edit" ? t("common.button.save") : t("common.button.submit")} + okText={preset === "edit" ? t("common.button.save") : t("common.button.submit")} open={open} - title={t(`access.action.${mode}`)} - onOk={handleClickOk} - onCancel={handleClickCancel} + title={t(`access.action.${preset}`)} + width={480} + onOk={handleOkClick} + onCancel={handleCancelClick} > -
- +
+
diff --git a/ui/src/components/access/AccessForm.tsx b/ui/src/components/access/AccessForm.tsx new file mode 100644 index 00000000..d5bdf7ad --- /dev/null +++ b/ui/src/components/access/AccessForm.tsx @@ -0,0 +1,180 @@ +import { forwardRef, useImperativeHandle, useMemo } from "react"; +import { useTranslation } from "react-i18next"; +import { Form, type FormInstance, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import AccessProviderSelect from "@/components/provider/AccessProviderSelect"; +import { type AccessModel } from "@/domain/access"; +import { ACCESS_PROVIDERS } from "@/domain/provider"; +import { useAntdForm, useAntdFormName } from "@/hooks"; + +import AccessFormACMEHttpReqConfig from "./AccessFormACMEHttpReqConfig"; +import AccessFormAWSConfig from "./AccessFormAWSConfig"; +import AccessFormAliyunConfig from "./AccessFormAliyunConfig"; +import AccessFormBaiduCloudConfig from "./AccessFormBaiduCloudConfig"; +import AccessFormBytePlusConfig from "./AccessFormBytePlusConfig"; +import AccessFormCloudflareConfig from "./AccessFormCloudflareConfig"; +import AccessFormDogeCloudConfig from "./AccessFormDogeCloudConfig"; +import AccessFormGoDaddyConfig from "./AccessFormGoDaddyConfig"; +import AccessFormHuaweiCloudConfig from "./AccessFormHuaweiCloudConfig"; +import AccessFormKubernetesConfig from "./AccessFormKubernetesConfig"; +import AccessFormLocalConfig from "./AccessFormLocalConfig"; +import AccessFormNameDotComConfig from "./AccessFormNameDotComConfig"; +import AccessFormNameSiloConfig from "./AccessFormNameSiloConfig"; +import AccessFormPowerDNSConfig from "./AccessFormPowerDNSConfig"; +import AccessFormQiniuConfig from "./AccessFormQiniuConfig"; +import AccessFormSSHConfig from "./AccessFormSSHConfig"; +import AccessFormTencentCloudConfig from "./AccessFormTencentCloudConfig"; +import AccessFormVolcEngineConfig from "./AccessFormVolcEngineConfig"; +import AccessFormWebhookConfig from "./AccessFormWebhookConfig"; + +type AccessFormFieldValues = Partial>; +type AccessFormPresets = "add" | "edit"; + +export type AccessFormProps = { + className?: string; + style?: React.CSSProperties; + disabled?: boolean; + initialValues?: AccessFormFieldValues; + preset: AccessFormPresets; + onValuesChange?: (values: AccessFormFieldValues) => void; +}; + +export type AccessFormInstance = { + getFieldsValue: () => ReturnType["getFieldsValue"]>; + resetFields: FormInstance["resetFields"]; + validateFields: FormInstance["validateFields"]; +}; + +const AccessForm = forwardRef(({ className, style, disabled, initialValues, preset, onValuesChange }, ref) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + name: z + .string({ message: t("access.form.name.placeholder") }) + .min(1, t("access.form.name.placeholder")) + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), + provider: z.nativeEnum(ACCESS_PROVIDERS, { message: t("access.form.provider.placeholder") }), + config: z.any(), + }); + const formRule = createSchemaFieldRule(formSchema); + const { form: formInst, formProps } = useAntdForm({ + initialValues: initialValues, + }); + + const fieldProvider = Form.useWatch("provider", formInst); + + const [nestedFormInst] = Form.useForm(); + const nestedFormName = useAntdFormName({ form: nestedFormInst, name: "accessEditFormConfigForm" }); + const nestedFormEl = useMemo(() => { + const nestedFormProps = { + form: nestedFormInst, + formName: nestedFormName, + disabled: disabled, + initialValues: initialValues?.config, + }; + + /* + 注意:如果追加新的子组件,请保持以 ASCII 排序。 + NOTICE: If you add new child component, please keep ASCII order. + */ + switch (fieldProvider) { + case ACCESS_PROVIDERS.ACMEHTTPREQ: + return ; + case ACCESS_PROVIDERS.ALIYUN: + return ; + case ACCESS_PROVIDERS.AWS: + return ; + case ACCESS_PROVIDERS.BAIDUCLOUD: + return ; + case ACCESS_PROVIDERS.BYTEPLUS: + return ; + case ACCESS_PROVIDERS.CLOUDFLARE: + return ; + case ACCESS_PROVIDERS.DOGECLOUD: + return ; + case ACCESS_PROVIDERS.GODADDY: + return ; + case ACCESS_PROVIDERS.HUAWEICLOUD: + return ; + case ACCESS_PROVIDERS.KUBERNETES: + return ; + case ACCESS_PROVIDERS.LOCAL: + return ; + case ACCESS_PROVIDERS.NAMEDOTCOM: + return ; + case ACCESS_PROVIDERS.NAMESILO: + return ; + case ACCESS_PROVIDERS.POWERDNS: + return ; + case ACCESS_PROVIDERS.QINIU: + return ; + case ACCESS_PROVIDERS.SSH: + return ; + case ACCESS_PROVIDERS.TENCENTCLOUD: + return ; + case ACCESS_PROVIDERS.VOLCENGINE: + return ; + case ACCESS_PROVIDERS.WEBHOOK: + return ; + } + }, [disabled, initialValues?.config, fieldProvider, nestedFormInst, nestedFormName]); + + const handleFormProviderChange = (name: string) => { + if (name === nestedFormName) { + formInst.setFieldValue("config", nestedFormInst.getFieldsValue()); + onValuesChange?.(formInst.getFieldsValue(true)); + } + }; + + const handleFormChange = (_: unknown, values: AccessFormFieldValues) => { + if (values.provider !== fieldProvider) { + formInst.setFieldValue("provider", values.provider); + } + + onValuesChange?.(values); + }; + + useImperativeHandle(ref, () => { + return { + getFieldsValue: () => { + return formInst.getFieldsValue(true); + }, + resetFields: (fields) => { + return formInst.resetFields(fields); + }, + validateFields: (nameList, config) => { + const t1 = formInst.validateFields(nameList, config); + const t2 = nestedFormInst.validateFields(undefined, config); + return Promise.all([t1, t2]).then(() => t1); + }, + } as AccessFormInstance; + }); + + return ( + +
+
+ + + + + } + > + + +
+ + {nestedFormEl} +
+
+ ); +}); + +export default AccessForm; diff --git a/ui/src/components/access/AccessEditFormACMEHttpReqConfig.tsx b/ui/src/components/access/AccessFormACMEHttpReqConfig.tsx similarity index 61% rename from ui/src/components/access/AccessEditFormACMEHttpReqConfig.tsx rename to ui/src/components/access/AccessFormACMEHttpReqConfig.tsx index d52e67c2..03cf163a 100644 --- a/ui/src/components/access/AccessEditFormACMEHttpReqConfig.tsx +++ b/ui/src/components/access/AccessFormACMEHttpReqConfig.tsx @@ -1,64 +1,59 @@ -import { useState } from "react"; import { useTranslation } from "react-i18next"; -import { useDeepCompareEffect } from "ahooks"; -import { Form, Input, Select, type FormInstance } from "antd"; +import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type ACMEHttpReqAccessConfig } from "@/domain/access"; +import { type AccessConfigForACMEHttpReq } from "@/domain/access"; -type AccessEditFormACMEHttpReqConfigModelType = Partial; +type AccessFormACMEHttpReqConfigFieldValues = Nullish; -export type AccessEditFormACMEHttpReqConfigProps = { +export type AccessFormACMEHttpReqConfigProps = { form: FormInstance; formName: string; disabled?: boolean; - loading?: boolean; - model?: AccessEditFormACMEHttpReqConfigModelType; - onModelChange?: (model: AccessEditFormACMEHttpReqConfigModelType) => void; + initialValues?: AccessFormACMEHttpReqConfigFieldValues; + onValuesChange?: (values: AccessFormACMEHttpReqConfigFieldValues) => void; }; -const initModel = () => { +const initFormModel = (): AccessFormACMEHttpReqConfigFieldValues => { return { endpoint: "https://example.com/api/", mode: "", - username: "", - password: "", - } as AccessEditFormACMEHttpReqConfigModelType; + }; }; -const AccessEditFormACMEHttpReqConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormACMEHttpReqConfigProps) => { +const AccessFormACMEHttpReqConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormACMEHttpReqConfigProps) => { const { t } = useTranslation(); const formSchema = z.object({ endpoint: z.string().url(t("common.errmsg.url_invalid")), - mode: z.string().min(0, t("access.form.acmehttpreq_mode.placeholder")).nullish(), + mode: z.string().nullish(), username: z .string() - .trim() - .min(0, t("access.form.acmehttpreq_username.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })) + .trim() .nullish(), password: z .string() - .trim() - .min(0, t("access.form.acmehttpreq_password.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })) + .trim() .nullish(), }); const formRule = createSchemaFieldRule(formSchema); - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - const handleFormChange = (_: unknown, fields: AccessEditFormACMEHttpReqConfigModelType) => { - onModelChange?.(fields); + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); }; return ( -
+ ; +type AccessFormAWSConfigFieldValues = Nullish; -export type AccessEditFormAWSConfigProps = { +export type AccessFormAWSConfigProps = { form: FormInstance; formName: string; disabled?: boolean; - loading?: boolean; - model?: AccessEditFormAWSConfigModelType; - onModelChange?: (model: AccessEditFormAWSConfigModelType) => void; + initialValues?: AccessFormAWSConfigFieldValues; + onValuesChange?: (values: AccessFormAWSConfigFieldValues) => void; }; -const initModel = () => { +const initFormModel = (): AccessFormAWSConfigFieldValues => { return { accessKeyId: "", secretAccessKey: "", region: "us-east-1", hostedZoneId: "", - } as AccessEditFormAWSConfigModelType; + }; }; -const AccessEditFormAWSConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormAWSConfigProps) => { +const AccessFormAWSConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormAWSConfigProps) => { const { t } = useTranslation(); const formSchema = z.object({ accessKeyId: z .string() - .trim() .min(1, t("access.form.aws_access_key_id.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), secretAccessKey: z .string() - .trim() .min(1, t("access.form.aws_secret_access_key.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), // TODO: 该字段仅用于申请证书,后续迁移到工作流表单中 region: z .string() - .trim() - .min(0, t("access.form.aws_region.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim() .nullish(), // TODO: 该字段仅用于申请证书,后续迁移到工作流表单中 hostedZoneId: z .string() - .trim() - .min(0, t("access.form.aws_hosted_zone_id.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim() .nullish(), }); const formRule = createSchemaFieldRule(formSchema); - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - const handleFormChange = (_: unknown, fields: AccessEditFormAWSConfigModelType) => { - onModelChange?.(fields); + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); }; return ( - + ; +type AccessFormAliyunConfigFieldValues = Nullish; -export type AccessEditFormAliyunConfigProps = { +export type AccessFormAliyunConfigProps = { form: FormInstance; formName: string; disabled?: boolean; - loading?: boolean; - model?: AccessEditFormAliyunConfigModelType; - onModelChange?: (model: AccessEditFormAliyunConfigModelType) => void; + initialValues?: AccessFormAliyunConfigFieldValues; + onValuesChange?: (values: AccessFormAliyunConfigFieldValues) => void; }; -const initModel = () => { +const initFormModel = (): AccessFormAliyunConfigFieldValues => { return { accessKeyId: "", accessKeySecret: "", - } as AccessEditFormAliyunConfigModelType; + }; }; -const AccessEditFormAliyunConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormAliyunConfigProps) => { +const AccessFormAliyunConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange: onValuesChange }: AccessFormAliyunConfigProps) => { const { t } = useTranslation(); const formSchema = z.object({ accessKeyId: z .string() - .trim() .min(1, t("access.form.aliyun_access_key_id.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), accessKeySecret: z .string() - .trim() .min(1, t("access.form.aliyun_access_key_secret.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), }); const formRule = createSchemaFieldRule(formSchema); - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - const handleFormChange = (_: unknown, fields: AccessEditFormAliyunConfigModelType) => { - onModelChange?.(fields); + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); }; return ( - + ; +type AccessFormBaiduCloudConfigFieldValues = Nullish; -export type AccessEditFormBaiduCloudConfigProps = { +export type AccessFormBaiduCloudConfigProps = { form: FormInstance; formName: string; disabled?: boolean; - loading?: boolean; - model?: AccessEditFormBaiduCloudConfigModelType; - onModelChange?: (model: AccessEditFormBaiduCloudConfigModelType) => void; + initialValues?: AccessFormBaiduCloudConfigFieldValues; + onValuesChange?: (values: AccessFormBaiduCloudConfigFieldValues) => void; }; -const initModel = () => { +const initFormModel = (): AccessFormBaiduCloudConfigFieldValues => { return { accessKeyId: "", secretAccessKey: "", - } as AccessEditFormBaiduCloudConfigModelType; + }; }; -const AccessEditFormBaiduCloudConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormBaiduCloudConfigProps) => { +const AccessFormBaiduCloudConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormBaiduCloudConfigProps) => { const { t } = useTranslation(); const formSchema = z.object({ @@ -36,23 +33,25 @@ const AccessEditFormBaiduCloudConfig = ({ form, formName, disabled, loading, mod .max(64, t("common.errmsg.string_max", { max: 64 })), secretAccessKey: z .string() - .trim() .min(1, t("access.form.baiducloud_secret_access_key.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), }); const formRule = createSchemaFieldRule(formSchema); - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - const handleFormChange = (_: unknown, fields: AccessEditFormBaiduCloudConfigModelType) => { - onModelChange?.(fields); + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); }; return ( - + ; +type AccessFormBytePlusConfigFieldValues = Nullish; -export type AccessEditFormBytePlusConfigProps = { +export type AccessFormBytePlusConfigProps = { form: FormInstance; formName: string; disabled?: boolean; - loading?: boolean; - model?: AccessEditFormBytePlusConfigModelType; - onModelChange?: (model: AccessEditFormBytePlusConfigModelType) => void; + initialValues?: AccessFormBytePlusConfigFieldValues; + onValuesChange?: (values: AccessFormBytePlusConfigFieldValues) => void; }; -const initModel = () => { +const initFormModel = (): AccessFormBytePlusConfigFieldValues => { return { accessKey: "", secretKey: "", - } as AccessEditFormBytePlusConfigModelType; + }; }; -const AccessEditFormBytePlusConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormBytePlusConfigProps) => { +const AccessFormBytePlusConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormBytePlusConfigProps) => { const { t } = useTranslation(); const formSchema = z.object({ @@ -36,23 +33,25 @@ const AccessEditFormBytePlusConfig = ({ form, formName, disabled, loading, model .max(64, t("common.errmsg.string_max", { max: 64 })), secretKey: z .string() - .trim() .min(1, t("access.form.byteplus_secret_key.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), }); const formRule = createSchemaFieldRule(formSchema); - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - const handleFormChange = (_: unknown, fields: AccessEditFormBytePlusConfigModelType) => { - onModelChange?.(fields); + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); }; return ( - + ; + +export type AccessFormCloudflareConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: AccessFormCloudflareConfigFieldValues; + onValuesChange?: (values: AccessFormCloudflareConfigFieldValues) => void; +}; + +const initFormModel = (): AccessFormCloudflareConfigFieldValues => { + return { + dnsApiToken: "", + }; +}; + +const AccessFormCloudflareConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormCloudflareConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + dnsApiToken: z + .string() + .min(1, t("access.form.cloudflare_dns_api_token.placeholder")) + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), + }); + const formRule = createSchemaFieldRule(formSchema); + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( + + } + > + + + + ); +}; + +export default AccessFormCloudflareConfig; diff --git a/ui/src/components/access/AccessEditFormDogeCloudConfig.tsx b/ui/src/components/access/AccessFormDogeCloudConfig.tsx similarity index 50% rename from ui/src/components/access/AccessEditFormDogeCloudConfig.tsx rename to ui/src/components/access/AccessFormDogeCloudConfig.tsx index c5f3502b..36b73f9f 100644 --- a/ui/src/components/access/AccessEditFormDogeCloudConfig.tsx +++ b/ui/src/components/access/AccessFormDogeCloudConfig.tsx @@ -1,58 +1,57 @@ -import { useState } from "react"; import { useTranslation } from "react-i18next"; -import { useDeepCompareEffect } from "ahooks"; -import { Form, Input, type FormInstance } from "antd"; +import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type DogeCloudAccessConfig } from "@/domain/access"; +import { type AccessConfigForDogeCloud } from "@/domain/access"; -type AccessEditFormDogeCloudConfigModelType = Partial; +type AccessFormDogeCloudConfigFieldValues = Nullish; -export type AccessEditFormDogeCloudConfigProps = { +export type AccessFormDogeCloudConfigProps = { form: FormInstance; formName: string; disabled?: boolean; - loading?: boolean; - model?: AccessEditFormDogeCloudConfigModelType; - onModelChange?: (model: AccessEditFormDogeCloudConfigModelType) => void; + initialValues?: AccessFormDogeCloudConfigFieldValues; + onValuesChange?: (values: AccessFormDogeCloudConfigFieldValues) => void; }; -const initModel = () => { +const initFormModel = (): AccessFormDogeCloudConfigFieldValues => { return { accessKey: "", secretKey: "", - } as AccessEditFormDogeCloudConfigModelType; + }; }; -const AccessEditFormDogeCloudConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormDogeCloudConfigProps) => { +const AccessFormDogeCloudConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormDogeCloudConfigProps) => { const { t } = useTranslation(); const formSchema = z.object({ accessKey: z .string() - .trim() .min(1, t("access.form.dogecloud_access_key.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), secretKey: z .string() - .trim() .min(1, t("access.form.dogecloud_secret_key.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), }); const formRule = createSchemaFieldRule(formSchema); - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - const handleFormChange = (_: unknown, fields: AccessEditFormDogeCloudConfigModelType) => { - onModelChange?.(fields); + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); }; return ( -
+ ; +type AccessFormGoDaddyConfigFieldValues = Nullish; -export type AccessEditFormGoDaddyConfigProps = { +export type AccessFormGoDaddyConfigProps = { form: FormInstance; formName: string; disabled?: boolean; - loading?: boolean; - model?: AccessEditFormGoDaddyConfigModelType; - onModelChange?: (model: AccessEditFormGoDaddyConfigModelType) => void; + initialValues?: AccessFormGoDaddyConfigFieldValues; + onValuesChange?: (values: AccessFormGoDaddyConfigFieldValues) => void; }; -const initModel = () => { +const initFormModel = (): AccessFormGoDaddyConfigFieldValues => { return { apiKey: "", apiSecret: "", - } as AccessEditFormGoDaddyConfigModelType; + }; }; -const AccessEditFormGoDaddyConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormGoDaddyConfigProps) => { +const AccessFormGoDaddyConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormGoDaddyConfigProps) => { const { t } = useTranslation(); const formSchema = z.object({ apiKey: z .string() - .trim() .min(1, t("access.form.godaddy_api_key.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), apiSecret: z .string() - .trim() .min(1, t("access.form.godaddy_api_secret.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), }); const formRule = createSchemaFieldRule(formSchema); - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - const handleFormChange = (_: unknown, fields: AccessEditFormGoDaddyConfigModelType) => { - onModelChange?.(fields); + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); }; return ( - + ; +type AccessFormHuaweiCloudConfigFieldValues = Nullish; -export type AccessEditFormHuaweiCloudConfigProps = { +export type AccessFormHuaweiCloudConfigProps = { form: FormInstance; formName: string; disabled?: boolean; - loading?: boolean; - model?: AccessEditFormHuaweiCloudConfigModelType; - onModelChange?: (model: AccessEditFormHuaweiCloudConfigModelType) => void; + initialValues?: AccessFormHuaweiCloudConfigFieldValues; + onValuesChange?: (values: AccessFormHuaweiCloudConfigFieldValues) => void; }; -const initModel = () => { +const initFormModel = (): AccessFormHuaweiCloudConfigFieldValues => { return { accessKeyId: "", secretAccessKey: "", region: "cn-north-1", - } as AccessEditFormHuaweiCloudConfigModelType; + }; }; -const AccessEditFormHuaweiCloudConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormHuaweiCloudConfigProps) => { +const AccessFormHuaweiCloudConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormHuaweiCloudConfigProps) => { const { t } = useTranslation(); const formSchema = z.object({ accessKeyId: z .string() - .trim() .min(1, t("access.form.huaweicloud_access_key_id.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), secretAccessKey: z .string() - .trim() .min(1, t("access.form.huaweicloud_secret_access_key.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), // TODO: 该字段仅用于申请证书,后续迁移到工作流表单中 region: z .string() - .trim() - .min(0, t("access.form.huaweicloud_region.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim() .nullish(), }); const formRule = createSchemaFieldRule(formSchema); - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - const handleFormChange = (_: unknown, fields: AccessEditFormHuaweiCloudConfigModelType) => { - onModelChange?.(fields); + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); }; return ( - + ; + +export type AccessFormKubernetesConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: AccessFormKubernetesConfigFieldValues; + onValuesChange?: (values: AccessFormKubernetesConfigFieldValues) => void; +}; + +const initFormModel = (): AccessFormKubernetesConfigFieldValues => { + return {}; +}; + +const AccessFormKubernetesConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormKubernetesConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + kubeConfig: z + .string() + .trim() + .max(20480, t("common.errmsg.string_max", { max: 20480 })) + .nullish(), + }); + const formRule = createSchemaFieldRule(formSchema); + + const fieldKubeConfig = Form.useWatch("kubeConfig", formInst); + const [fieldKubeFileList, setFieldKubeFileList] = useState([]); + useEffect(() => { + setFieldKubeFileList(initialValues?.kubeConfig?.trim() ? [{ uid: "-1", name: "kubeconfig", status: "done" }] : []); + }, [initialValues?.kubeConfig]); + + const handleKubeFileChange: UploadProps["onChange"] = async ({ file }) => { + if (file && file.status !== "removed") { + formInst.setFieldValue("kubeConfig", await readFileContent(file.originFileObj ?? (file as unknown as File))); + setFieldKubeFileList([file]); + } else { + formInst.setFieldValue("kubeConfig", ""); + setFieldKubeFileList([]); + } + + onValuesChange?.(formInst.getFieldsValue(true)); + }; + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( + + + + } + > + false} fileList={fieldKubeFileList} maxCount={1} onChange={handleKubeFileChange}> + + + + + ); +}; + +export default AccessFormKubernetesConfig; diff --git a/ui/src/components/access/AccessFormLocalConfig.tsx b/ui/src/components/access/AccessFormLocalConfig.tsx new file mode 100644 index 00000000..cde72374 --- /dev/null +++ b/ui/src/components/access/AccessFormLocalConfig.tsx @@ -0,0 +1,36 @@ +import { Form, type FormInstance } from "antd"; + +import { type AccessConfigForLocal } from "@/domain/access"; + +type AccessFormLocalConfigFieldValues = Nullish; + +export type AccessFormLocalConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: AccessFormLocalConfigFieldValues; + onValuesChange?: (values: AccessFormLocalConfigFieldValues) => void; +}; + +const initFormModel = (): AccessFormLocalConfigFieldValues => { + return {}; +}; + +const AccessFormLocalConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormLocalConfigProps) => { + const handleFormChange = (_: unknown, values: any) => { + onValuesChange?.(values); + }; + + return ( +
+ ); +}; + +export default AccessFormLocalConfig; diff --git a/ui/src/components/access/AccessEditFormNameDotComConfig.tsx b/ui/src/components/access/AccessFormNameDotComConfig.tsx similarity index 50% rename from ui/src/components/access/AccessEditFormNameDotComConfig.tsx rename to ui/src/components/access/AccessFormNameDotComConfig.tsx index 5b810ce8..0048de52 100644 --- a/ui/src/components/access/AccessEditFormNameDotComConfig.tsx +++ b/ui/src/components/access/AccessFormNameDotComConfig.tsx @@ -1,58 +1,57 @@ -import { useState } from "react"; import { useTranslation } from "react-i18next"; -import { useDeepCompareEffect } from "ahooks"; -import { Form, Input, type FormInstance } from "antd"; +import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type NameDotComAccessConfig } from "@/domain/access"; +import { type AccessConfigForNameDotCom } from "@/domain/access"; -type AccessEditFormNameDotComConfigModelType = Partial; +type AccessFormNameDotComConfigFieldValues = Nullish; -export type AccessEditFormNameDotComConfigProps = { +export type AccessFormNameDotComConfigProps = { form: FormInstance; formName: string; disabled?: boolean; - loading?: boolean; - model?: AccessEditFormNameDotComConfigModelType; - onModelChange?: (model: AccessEditFormNameDotComConfigModelType) => void; + initialValues?: AccessFormNameDotComConfigFieldValues; + onValuesChange?: (values: AccessFormNameDotComConfigFieldValues) => void; }; -const initModel = () => { +const initFormModel = (): AccessFormNameDotComConfigFieldValues => { return { username: "", apiToken: "", - } as AccessEditFormNameDotComConfigModelType; + }; }; -const AccessEditFormNameDotComConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormNameDotComConfigProps) => { +const AccessFormNameDotComConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormNameDotComConfigProps) => { const { t } = useTranslation(); const formSchema = z.object({ username: z .string() - .trim() .min(1, t("access.form.namedotcom_username.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), apiToken: z .string() - .trim() .min(1, t("access.form.namedotcom_api_token.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), }); const formRule = createSchemaFieldRule(formSchema); - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - const handleFormChange = (_: unknown, fields: AccessEditFormNameDotComConfigModelType) => { - onModelChange?.(fields); + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); }; return ( -
+ ; + +export type AccessFormNameSiloConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: AccessFormNameSiloConfigFieldValues; + onValuesChange?: (values: AccessFormNameSiloConfigFieldValues) => void; +}; + +const initFormModel = (): AccessFormNameSiloConfigFieldValues => { + return { + apiKey: "", + }; +}; + +const AccessFormNameSiloConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormNameSiloConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + apiKey: z + .string() + .min(1, t("access.form.namesilo_api_key.placeholder")) + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), + }); + const formRule = createSchemaFieldRule(formSchema); + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( + + } + > + + + + ); +}; + +export default AccessFormNameSiloConfig; diff --git a/ui/src/components/access/AccessEditFormPowerDNSConfig.tsx b/ui/src/components/access/AccessFormPowerDNSConfig.tsx similarity index 50% rename from ui/src/components/access/AccessEditFormPowerDNSConfig.tsx rename to ui/src/components/access/AccessFormPowerDNSConfig.tsx index 5677c781..83a22b9b 100644 --- a/ui/src/components/access/AccessEditFormPowerDNSConfig.tsx +++ b/ui/src/components/access/AccessFormPowerDNSConfig.tsx @@ -1,54 +1,53 @@ -import { useState } from "react"; import { useTranslation } from "react-i18next"; -import { useDeepCompareEffect } from "ahooks"; -import { Form, Input, type FormInstance } from "antd"; +import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type PowerDNSAccessConfig } from "@/domain/access"; +import { type AccessConfigForPowerDNS } from "@/domain/access"; -type AccessEditFormPowerDNSConfigModelType = Partial; +type AccessFormPowerDNSConfigFieldValues = Nullish; -export type AccessEditFormPowerDNSConfigProps = { +export type AccessFormPowerDNSConfigProps = { form: FormInstance; formName: string; disabled?: boolean; - loading?: boolean; - model?: AccessEditFormPowerDNSConfigModelType; - onModelChange?: (model: AccessEditFormPowerDNSConfigModelType) => void; + initialValues?: AccessFormPowerDNSConfigFieldValues; + onValuesChange?: (values: AccessFormPowerDNSConfigFieldValues) => void; }; -const initModel = () => { +const initFormModel = (): AccessFormPowerDNSConfigFieldValues => { return { apiUrl: "", apiKey: "", - } as AccessEditFormPowerDNSConfigModelType; + }; }; -const AccessEditFormPowerDNSConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormPowerDNSConfigProps) => { +const AccessFormPowerDNSConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormPowerDNSConfigProps) => { const { t } = useTranslation(); const formSchema = z.object({ apiUrl: z.string().url(t("common.errmsg.url_invalid")), apiKey: z .string() - .trim() .min(1, t("access.form.powerdns_api_key.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), }); const formRule = createSchemaFieldRule(formSchema); - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - const handleFormChange = (_: unknown, fields: AccessEditFormPowerDNSConfigModelType) => { - onModelChange?.(fields); + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); }; return ( -
+ ; +type AccessFormQiniuConfigFieldValues = Nullish; -export type AccessEditFormQiniuConfigProps = { +export type AccessFormQiniuConfigProps = { form: FormInstance; formName: string; disabled?: boolean; - loading?: boolean; - model?: AccessEditFormQiniuConfigModelType; - onModelChange?: (model: AccessEditFormQiniuConfigModelType) => void; + initialValues?: AccessFormQiniuConfigFieldValues; + onValuesChange?: (values: AccessFormQiniuConfigFieldValues) => void; }; -const initModel = () => { +const initFormModel = (): AccessFormQiniuConfigFieldValues => { return { accessKey: "", secretKey: "", - } as AccessEditFormQiniuConfigModelType; + }; }; -const AccessEditFormQiniuConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormQiniuConfigProps) => { +const AccessFormQiniuConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormQiniuConfigProps) => { const { t } = useTranslation(); const formSchema = z.object({ accessKey: z .string() - .trim() .min(1, t("access.form.qiniu_access_key.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), secretKey: z .string() - .trim() .min(1, t("access.form.qiniu_secret_key.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), }); const formRule = createSchemaFieldRule(formSchema); - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - const handleFormChange = (_: unknown, fields: AccessEditFormQiniuConfigModelType) => { - onModelChange?.(fields); + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); }; return ( - + ; + +export type AccessFormSSHConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: AccessFormSSHConfigFieldValues; + onValuesChange?: (values: AccessFormSSHConfigFieldValues) => void; +}; + +const initFormModel = (): AccessFormSSHConfigFieldValues => { + return { + host: "127.0.0.1", + port: 22, + username: "root", + }; +}; + +const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormSSHConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + host: z + .string({ message: t("access.form.ssh_host.placeholder") }) + .refine((v) => validDomainName(v) || validIPv4Address(v) || validIPv6Address(v), t("common.errmsg.host_invalid")), + port: z + .number({ message: t("access.form.ssh_port.placeholder") }) + .int() + .gte(1, t("common.errmsg.port_invalid")) + .lte(65535, t("common.errmsg.port_invalid")), + username: z + .string() + .min(1, "access.form.ssh_username.placeholder") + .max(64, t("common.errmsg.string_max", { max: 64 })), + password: z + .string() + .max(64, t("common.errmsg.string_max", { max: 64 })) + .nullish(), + key: z + .string() + .max(20480, t("common.errmsg.string_max", { max: 20480 })) + .nullish(), + keyPassphrase: z + .string() + .max(20480, t("common.errmsg.string_max", { max: 20480 })) + .nullish() + .refine((v) => !v || formInst.getFieldValue("key"), t("access.form.ssh_key.placeholder")), + }); + const formRule = createSchemaFieldRule(formSchema); + + const fieldKey = Form.useWatch("key", formInst); + const [fieldKeyFileList, setFieldKeyFileList] = useState([]); + useEffect(() => { + setFieldKeyFileList(initialValues?.key?.trim() ? [{ uid: "-1", name: "sshkey", status: "done" }] : []); + }, [initialValues?.key]); + + const handleKeyFileChange: UploadProps["onChange"] = async ({ file }) => { + if (file && file.status !== "removed") { + formInst.setFieldValue("key", await readFileContent(file.originFileObj ?? (file as unknown as File))); + setFieldKeyFileList([file]); + } else { + formInst.setFieldValue("key", ""); + setFieldKeyFileList([]); + } + + onValuesChange?.(formInst.getFieldsValue(true)); + }; + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( + +
+
+ + + +
+ +
+ + + +
+
+ +
+
+ + + +
+ +
+ } + > + + +
+
+ +
+
+ + + }> + false} fileList={fieldKeyFileList} maxCount={1} onChange={handleKeyFileChange}> + + + +
+ +
+ } + > + + +
+
+ + ); +}; + +export default AccessFormSSHConfig; diff --git a/ui/src/components/access/AccessEditFormTencentCloudConfig.tsx b/ui/src/components/access/AccessFormTencentCloudConfig.tsx similarity index 50% rename from ui/src/components/access/AccessEditFormTencentCloudConfig.tsx rename to ui/src/components/access/AccessFormTencentCloudConfig.tsx index 78c311e1..11de6d6d 100644 --- a/ui/src/components/access/AccessEditFormTencentCloudConfig.tsx +++ b/ui/src/components/access/AccessFormTencentCloudConfig.tsx @@ -1,58 +1,57 @@ -import { useState } from "react"; import { useTranslation } from "react-i18next"; -import { useDeepCompareEffect } from "ahooks"; -import { Form, Input, type FormInstance } from "antd"; +import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type TencentCloudAccessConfig } from "@/domain/access"; +import { type AccessConfigForTencentCloud } from "@/domain/access"; -type AccessEditFormTencentCloudConfigModelType = Partial; +type AccessFormTencentCloudConfigFieldValues = Nullish; -export type AccessEditFormTencentCloudConfigProps = { +export type AccessFormTencentCloudConfigProps = { form: FormInstance; formName: string; disabled?: boolean; - loading?: boolean; - model?: AccessEditFormTencentCloudConfigModelType; - onModelChange?: (model: AccessEditFormTencentCloudConfigModelType) => void; + initialValues?: AccessFormTencentCloudConfigFieldValues; + onValuesChange?: (values: AccessFormTencentCloudConfigFieldValues) => void; }; -const initModel = () => { +const initFormModel = (): AccessFormTencentCloudConfigFieldValues => { return { secretId: "", secretKey: "", - } as AccessEditFormTencentCloudConfigModelType; + }; }; -const AccessEditFormTencentCloudConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormTencentCloudConfigProps) => { +const AccessFormTencentCloudConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormTencentCloudConfigProps) => { const { t } = useTranslation(); const formSchema = z.object({ secretId: z .string() - .trim() .min(1, t("access.form.tencentcloud_secret_id.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), secretKey: z .string() - .trim() .min(1, t("access.form.tencentcloud_secret_key.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), }); const formRule = createSchemaFieldRule(formSchema); - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - const handleFormChange = (_: unknown, fields: AccessEditFormTencentCloudConfigModelType) => { - onModelChange?.(fields); + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); }; return ( -
+ ; +type AccessFormVolcEngineConfigFieldValues = Nullish; -export type AccessEditFormVolcEngineConfigProps = { +export type AccessFormVolcEngineConfigProps = { form: FormInstance; formName: string; disabled?: boolean; - loading?: boolean; - model?: AccessEditFormVolcEngineConfigModelType; - onModelChange?: (model: AccessEditFormVolcEngineConfigModelType) => void; + initialValues?: AccessFormVolcEngineConfigFieldValues; + onValuesChange?: (values: AccessFormVolcEngineConfigFieldValues) => void; }; -const initModel = () => { +const initFormModel = (): AccessFormVolcEngineConfigFieldValues => { return { accessKeyId: "", secretAccessKey: "", - } as AccessEditFormVolcEngineConfigModelType; + }; }; -const AccessEditFormVolcEngineConfig = ({ form, formName, disabled, loading, model, onModelChange }: AccessEditFormVolcEngineConfigProps) => { +const AccessFormVolcEngineConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormVolcEngineConfigProps) => { const { t } = useTranslation(); const formSchema = z.object({ @@ -36,23 +33,25 @@ const AccessEditFormVolcEngineConfig = ({ form, formName, disabled, loading, mod .max(64, t("common.errmsg.string_max", { max: 64 })), secretAccessKey: z .string() - .trim() .min(1, t("access.form.volcengine_secret_access_key.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), }); const formRule = createSchemaFieldRule(formSchema); - const [initialValues, setInitialValues] = useState>>(model ?? initModel()); - useDeepCompareEffect(() => { - setInitialValues(model ?? initModel()); - }, [model]); - - const handleFormChange = (_: unknown, fields: AccessEditFormVolcEngineConfigModelType) => { - onModelChange?.(fields); + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); }; return ( - + ; + +export type AccessFormWebhookConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: AccessFormWebhookConfigFieldValues; + onValuesChange?: (values: AccessFormWebhookConfigFieldValues) => void; +}; + +const initFormModel = (): AccessFormWebhookConfigFieldValues => { + return { + url: "", + }; +}; + +const AccessFormWebhookConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormWebhookConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + url: z.string({ message: t("access.form.webhook_url.placeholder") }).url(t("common.errmsg.url_invalid")), + }); + const formRule = createSchemaFieldRule(formSchema); + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( + + + + + + ); +}; + +export default AccessFormWebhookConfig; diff --git a/ui/src/components/access/AccessSelect.tsx b/ui/src/components/access/AccessSelect.tsx index 3cbca057..3ad60348 100644 --- a/ui/src/components/access/AccessSelect.tsx +++ b/ui/src/components/access/AccessSelect.tsx @@ -1,8 +1,10 @@ import { useEffect, useState } from "react"; -import { Avatar, Select, Space, Typography, type SelectProps } from "antd"; +import { Avatar, Select, type SelectProps, Space, Typography } from "antd"; -import { accessProvidersMap, type AccessModel } from "@/domain/access"; -import { useAccessStore } from "@/stores/access"; +import { type AccessModel } from "@/domain/access"; +import { accessProvidersMap } from "@/domain/provider"; +import { useZustandShallowSelector } from "@/hooks"; +import { useAccessesStore } from "@/stores/access"; export type AccessTypeSelectProps = Omit< SelectProps, @@ -12,10 +14,10 @@ export type AccessTypeSelectProps = Omit< }; const AccessSelect = ({ filter, ...props }: AccessTypeSelectProps) => { - const { initialized, accesses, fetchAccesses } = useAccessStore(); + const { accesses, loadedAtOnce, fetchAccesses } = useAccessesStore(useZustandShallowSelector(["accesses", "loadedAtOnce", "fetchAccesses"])); useEffect(() => { fetchAccesses(); - }, [fetchAccesses]); + }, []); const [options, setOptions] = useState>([]); useEffect(() => { @@ -34,7 +36,7 @@ const AccessSelect = ({ filter, ...props }: AccessTypeSelectProps) => { const access = accesses.find((e) => e.id === key); if (!access) { return ( - + {key} @@ -43,9 +45,9 @@ const AccessSelect = ({ filter, ...props }: AccessTypeSelectProps) => { ); } - const provider = accessProvidersMap.get(access.configType); + const provider = accessProvidersMap.get(access.provider); return ( - + {access.name} @@ -64,7 +66,7 @@ const AccessSelect = ({ filter, ...props }: AccessTypeSelectProps) => { return {props.placeholder}; }} - loading={!initialized} + loading={!loadedAtOnce} options={options} optionFilterProp="label" optionLabelProp={undefined} diff --git a/ui/src/components/certificate/CertificateDetail.tsx b/ui/src/components/certificate/CertificateDetail.tsx index c242344c..b82cb8db 100644 --- a/ui/src/components/certificate/CertificateDetail.tsx +++ b/ui/src/components/certificate/CertificateDetail.tsx @@ -1,7 +1,7 @@ -import { useTranslation } from "react-i18next"; -import { Button, Dropdown, Form, Input, message, Space, Tooltip } from "antd"; import { CopyToClipboard } from "react-copy-to-clipboard"; -import { ChevronDown as ChevronDownIcon, Clipboard as ClipboardIcon, ThumbsUp as ThumbsUpIcon } from "lucide-react"; +import { useTranslation } from "react-i18next"; +import { CopyOutlined as CopyOutlinedIcon, DownOutlined as DownOutlinedIcon, LikeOutlined as LikeOutlinedIcon } from "@ant-design/icons"; +import { Button, Dropdown, Form, Input, Space, Tooltip, message } from "antd"; import dayjs from "dayjs"; import { type CertificateModel } from "@/domain/certificate"; @@ -19,14 +19,14 @@ const CertificateDetail = ({ data, ...props }: CertificateDetailProps) => { const [messageApi, MessageContextHolder] = message.useMessage(); const handleDownloadPEMClick = async () => { - const zipName = `${data.id}-${data.san}.zip`; + const zipName = `${data.id}-${data.subjectAltNames}.zip`; const files = [ { - name: `${data.san}.pem`, + name: `${data.subjectAltNames}.pem`, content: data.certificate ?? "", }, { - name: `${data.san}.key`, + name: `${data.subjectAltNames}.key`, content: data.privateKey ?? "", }, ]; @@ -39,13 +39,17 @@ const CertificateDetail = ({ data, ...props }: CertificateDetailProps) => { {MessageContextHolder}
- {data.san} + + + - {dayjs(data.expireAt).format("YYYY-MM-DD HH:mm:ss")} + + + -
- +
+ { messageApi.success(t("common.text.copied")); }} > - +
@@ -61,8 +65,8 @@ const CertificateDetail = ({ data, ...props }: CertificateDetailProps) => { -
- +
+ { messageApi.success(t("common.text.copied")); }} > - +
@@ -85,23 +89,21 @@ const CertificateDetail = ({ data, ...props }: CertificateDetailProps) => { { key: "PEM", label: "PEM", - extra: , + extra: , onClick: () => handleDownloadPEMClick(), }, { key: "PFX", label: "PFX", onClick: () => { - // TODO: 下载 PFX 格式证书 - alert("TODO"); + alert("TODO: 暂时不支持下载 PFX 证书"); }, }, { key: "JKS", label: "JKS", onClick: () => { - // TODO: 下载 JKS 格式证书 - alert("TODO"); + alert("TODO: 暂时不支持下载 JKS 证书"); }, }, ], @@ -110,7 +112,7 @@ const CertificateDetail = ({ data, ...props }: CertificateDetailProps) => { diff --git a/ui/src/components/certificate/CertificateDetailDrawer.tsx b/ui/src/components/certificate/CertificateDetailDrawer.tsx index 0966f611..9db04ab6 100644 --- a/ui/src/components/certificate/CertificateDetailDrawer.tsx +++ b/ui/src/components/certificate/CertificateDetailDrawer.tsx @@ -1,15 +1,16 @@ -import { cloneElement, useMemo } from "react"; import { useControllableValue } from "ahooks"; import { Drawer } from "antd"; +import Show from "@/components/Show"; import { type CertificateModel } from "@/domain/certificate"; +import { useTriggerElement } from "@/hooks"; import CertificateDetail from "./CertificateDetail"; export type CertificateDetailDrawerProps = { data?: CertificateModel; loading?: boolean; open?: boolean; - trigger?: React.ReactElement; + trigger?: React.ReactNode; onOpenChange?: (open: boolean) => void; }; @@ -20,26 +21,26 @@ const CertificateDetailDrawer = ({ data, loading, trigger, ...props }: Certifica trigger: "onOpenChange", }); - const triggerEl = useMemo(() => { - if (!trigger) { - return null; - } - - return cloneElement(trigger, { - ...trigger.props, - onClick: () => { - setOpen(true); - trigger.props?.onClick?.(); - }, - }); - }, [trigger, setOpen]); + const triggerEl = useTriggerElement(trigger, { onClick: () => setOpen(true) }); return ( <> {triggerEl} - setOpen(false)}> - {data ? : <>} + setOpen(false)} + > + + + ); diff --git a/ui/src/components/certimate/EmailsEdit.tsx b/ui/src/components/certimate/EmailsEdit.tsx deleted file mode 100644 index 49bad862..00000000 --- a/ui/src/components/certimate/EmailsEdit.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { useTranslation } from "react-i18next"; -import { z } from "zod"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { ClientResponseError } from "pocketbase"; - -import { cn } from "@/components/ui/utils"; -import { Button } from "@/components/ui/button"; -import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; -import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; -import { Input } from "@/components/ui/input"; -import { type PbErrorData } from "@/domain/base"; -import { useContactStore } from "@/stores/contact"; - -type EmailsEditProps = { - className?: string; - trigger: React.ReactNode; -}; - -const EmailsEdit = ({ className, trigger }: EmailsEditProps) => { - const { emails, setEmails, fetchEmails } = useContactStore(); - - const [open, setOpen] = useState(false); - const { t } = useTranslation(); - - const formSchema = z.object({ - email: z.string().email("common.errmsg.email_invalid"), - }); - - const form = useForm>({ - resolver: zodResolver(formSchema), - defaultValues: { - email: "", - }, - }); - - useEffect(() => { - fetchEmails(); - }, []); - - const onSubmit = async (data: z.infer) => { - if (emails.includes(data.email)) { - form.setError("email", { - message: "common.errmsg.email_duplicate", - }); - return; - } - - try { - await setEmails([...emails, data.email]); - - form.reset(); - form.clearErrors(); - - setOpen(false); - } catch (e) { - const err = e as ClientResponseError; - - Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => { - form.setError(key as keyof z.infer, { - type: "manual", - message: value.message, - }); - }); - } - }; - - return ( - - - {trigger} - - - - {t("domain.application.form.email.add")} - - -
- - { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("domain.application.form.email.label")} - - - - - - - )} - /> - -
- -
- - -
-
-
- ); -}; - -export default EmailsEdit; diff --git a/ui/src/components/certimate/KVList.tsx b/ui/src/components/certimate/KVList.tsx deleted file mode 100644 index 9c0800f4..00000000 --- a/ui/src/components/certimate/KVList.tsx +++ /dev/null @@ -1,243 +0,0 @@ -import { useEffect, useState } from "react"; -import { useTranslation } from "react-i18next"; -import { produce } from "immer"; -import { Edit, Plus, Trash2 } from "lucide-react"; - -import Show from "@/components/Show"; -import { Button } from "@/components/ui/button"; -import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; -import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; -import { KVType } from "@/domain/domain"; - -type KVListProps = { - variables?: KVType[]; - onValueChange?: (variables: KVType[]) => void; -}; - -const KVList = ({ variables, onValueChange }: KVListProps) => { - const [locVariables, setLocVariables] = useState([]); - - const { t } = useTranslation(); - - useEffect(() => { - if (variables) { - setLocVariables(variables); - } - }, [variables]); - - const handleAddClick = (variable: KVType) => { - // 查看是否存在key,存在则更新,不存在则添加 - const index = locVariables.findIndex((item) => { - return item.key === variable.key; - }); - - const newList = produce(locVariables, (draft) => { - if (index === -1) { - draft.push(variable); - } else { - draft[index] = variable; - } - }); - - setLocVariables(newList); - - onValueChange?.(newList); - }; - - const handleDeleteClick = (index: number) => { - const newList = [...locVariables]; - newList.splice(index, 1); - setLocVariables(newList); - - onValueChange?.(newList); - }; - - const handleEditClick = (index: number, variable: KVType) => { - const newList = [...locVariables]; - newList[index] = variable; - setLocVariables(newList); - - onValueChange?.(newList); - }; - - return ( - <> -
- - - - - -
{t("common.button.add")}
-
- } - onSave={(variable) => { - handleAddClick(variable); - }} - /> - -
- - -
{t("domain.deployment.form.variables.empty")}
- - - - -
{t("common.button.add")}
-
- } - variable={{ - key: "", - value: "", - }} - onSave={(variable) => { - handleAddClick(variable); - }} - /> -
- } - > -
- {locVariables?.map((item, index) => ( -
-
- {item.key}={item.value} -
-
- } - variable={item} - onSave={(variable) => { - handleEditClick(index, variable); - }} - /> - - { - handleDeleteClick(index); - }} - /> -
-
- ))} -
- - - ); -}; - -type KVEditProps = { - variable?: KVType; - trigger: React.ReactNode; - onSave: (variable: KVType) => void; -}; - -const KVEdit = ({ variable, trigger, onSave }: KVEditProps) => { - const [locVariable, setLocVariable] = useState({ - key: "", - value: "", - }); - - useEffect(() => { - if (variable) setLocVariable(variable!); - }, [variable]); - - const { t } = useTranslation(); - - const [open, setOpen] = useState(false); - - const [err, setErr] = useState>({}); - - const handleSaveClick = () => { - if (!locVariable.key) { - setErr({ - key: t("domain.deployment.form.variables.key.required"), - }); - return; - } - - if (!locVariable.value) { - setErr({ - value: t("domain.deployment.form.variables.value.required"), - }); - return; - } - - onSave?.(locVariable); - - setOpen(false); - - setErr({}); - }; - - return ( - { - setOpen(!open); - }} - > - {trigger} - - - {t("domain.deployment.form.variables.label")} - -
- - { - setLocVariable({ ...locVariable, key: e.target.value }); - }} - className="w-full mt-1" - /> -
{err?.key}
-
- -
- - { - setLocVariable({ ...locVariable, value: e.target.value }); - }} - className="w-full mt-1" - /> - -
{err?.value}
-
-
- -
- -
-
-
-
- ); -}; - -export default KVList; diff --git a/ui/src/components/certimate/StringList.tsx b/ui/src/components/certimate/StringList.tsx deleted file mode 100644 index 8c8293d6..00000000 --- a/ui/src/components/certimate/StringList.tsx +++ /dev/null @@ -1,217 +0,0 @@ -import { useCallback, useEffect, useMemo, useState } from "react"; -import { z } from "zod"; -import { useTranslation } from "react-i18next"; -import { Edit, Plus, Trash2 } from "lucide-react"; - -import { cn } from "@/components/ui/utils"; -import Show from "@/components/Show"; -import { Button } from "@/components/ui/button"; -import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; -import { FormControl, FormItem, FormLabel } from "@/components/ui/form"; -import { Input } from "@/components/ui/input"; - -type StringListProps = { - className?: string; - value: string; - valueType?: ValueType; - onValueChange: (value: string) => void; -}; - -const titles: Record = { - domain: "common.text.domain", - ip: "common.text.ip", - dns: "common.text.dns", -}; - -const StringList = ({ value, className, onValueChange, valueType = "domain" }: StringListProps) => { - const [list, setList] = useState([]); - - const { t } = useTranslation(); - - useMemo(() => { - if (value) { - setList(value.split(";")); - } - }, [value]); - - useEffect(() => { - const changeList = () => { - onValueChange(list.join(";")); - }; - changeList(); - }, [list]); - - const addVal = (val: string) => { - if (list.includes(val)) { - return; - } - setList([...list, val]); - }; - - const editVal = (index: number, val: string) => { - const newList = [...list]; - newList[index] = val; - setList(newList); - }; - - const onRemoveClick = (index: number) => { - const newList = [...list]; - newList.splice(index, 1); - setList(newList); - }; - - return ( - <> -
- - -
{t(titles[valueType])}
- - 0}> - { - addVal(val); - }} - valueType={valueType} - value={""} - trigger={ -
- - -
{t("common.button.add")}
-
- } - /> -
-
- - 0} - fallback={ -
-
{t("common.text." + valueType + ".empty")}
- - -
- } - > -
- {list.map((item, index) => ( -
-
{item}
-
- } - value={item} - onValueChange={(val: string) => { - editVal(index, val); - }} - /> - { - onRemoveClick(index); - }} - /> -
-
- ))} -
-
-
-
-
- - ); -}; - -export default StringList; - -type ValueType = "domain" | "dns" | "host"; - -type StringEditProps = { - value: string; - trigger: React.ReactNode; - onValueChange: (value: string) => void; - valueType: ValueType; - op?: "add" | "edit"; -}; - -const StringEdit = ({ trigger, value, onValueChange, op = "add", valueType }: StringEditProps) => { - const [currentValue, setCurrentValue] = useState(""); - const [open, setOpen] = useState(false); - const [error, setError] = useState(""); - const { t } = useTranslation(); - - useEffect(() => { - setCurrentValue(value); - }, [value]); - - const domainSchema = z.string().regex(/^(?:\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$/, { - message: t("common.errmsg.domain_invalid"), - }); - - const ipSchema = z.string().ip({ message: t("common.errmsg.ip_invalid") }); - - const schedules: Record = { - domain: domainSchema, - dns: ipSchema, - host: ipSchema, - }; - - const onSaveClick = useCallback(() => { - const schema = schedules[valueType]; - - const resp = schema.safeParse(currentValue); - if (!resp.success) { - setError(JSON.parse(resp.error.message)[0].message); - return; - } - - setCurrentValue(""); - setOpen(false); - setError(""); - - onValueChange(currentValue); - }, [currentValue]); - - return ( - { - setOpen(open); - }} - > - {trigger} - - - {t(titles[valueType])} - - { - setCurrentValue(e.target.value); - }} - /> - 0}> -
{error}
-
- - - - -
-
- ); -}; diff --git a/ui/src/components/notification/NotifyChannelEditForm.tsx b/ui/src/components/notification/NotifyChannelEditForm.tsx index d93a6732..2fa9b5b3 100644 --- a/ui/src/components/notification/NotifyChannelEditForm.tsx +++ b/ui/src/components/notification/NotifyChannelEditForm.tsx @@ -1,40 +1,42 @@ -import { forwardRef, useImperativeHandle, useMemo, useState } from "react"; -import { useCreation, useDeepCompareEffect } from "ahooks"; -import { Form } from "antd"; +import { forwardRef, useImperativeHandle, useMemo } from "react"; +import { Form, type FormInstance } from "antd"; import { NOTIFY_CHANNELS, type NotifyChannelsSettingsContent } from "@/domain/settings"; +import { useAntdForm } from "@/hooks"; + import NotifyChannelEditFormBarkFields from "./NotifyChannelEditFormBarkFields"; import NotifyChannelEditFormDingTalkFields from "./NotifyChannelEditFormDingTalkFields"; import NotifyChannelEditFormEmailFields from "./NotifyChannelEditFormEmailFields"; import NotifyChannelEditFormLarkFields from "./NotifyChannelEditFormLarkFields"; import NotifyChannelEditFormServerChanFields from "./NotifyChannelEditFormServerChanFields"; import NotifyChannelEditFormTelegramFields from "./NotifyChannelEditFormTelegramFields"; -import NotifyChannelEditFormWebhookFields from "./NotifyChannelEditFormWebhookFields"; import NotifyChannelEditFormWeComFields from "./NotifyChannelEditFormWeComFields"; +import NotifyChannelEditFormWebhookFields from "./NotifyChannelEditFormWebhookFields"; -type NotifyChannelEditFormModelType = NotifyChannelsSettingsContent[keyof NotifyChannelsSettingsContent]; +type NotifyChannelEditFormFieldValues = NotifyChannelsSettingsContent[keyof NotifyChannelsSettingsContent]; export type NotifyChannelEditFormProps = { className?: string; style?: React.CSSProperties; channel: string; disabled?: boolean; - loading?: boolean; - model?: NotifyChannelEditFormModelType; - onModelChange?: (model: NotifyChannelEditFormModelType) => void; + initialValues?: NotifyChannelEditFormFieldValues; + onValuesChange?: (values: NotifyChannelEditFormFieldValues) => void; }; export type NotifyChannelEditFormInstance = { - getFieldsValue: () => NotifyChannelEditFormModelType; - resetFields: () => void; - validateFields: () => Promise; + getFieldsValue: () => ReturnType["getFieldsValue"]>; + resetFields: FormInstance["resetFields"]; + validateFields: FormInstance["validateFields"]; }; const NotifyChannelEditForm = forwardRef( - ({ className, style, channel, disabled, loading, model, onModelChange }, ref) => { - const [form] = Form.useForm(); - const formName = useCreation(() => `notifyChannelEditForm_${Math.random().toString(36).substring(2, 10)}${new Date().getTime()}`, []); - const formFieldsComponent = useMemo(() => { + ({ className, style, channel, disabled, initialValues, onValuesChange }, ref) => { + const { form: formInst, formProps } = useAntdForm({ + initialValues: initialValues, + name: "notifyChannelEditForm", + }); + const formFieldsEl = useMemo(() => { /* 注意:如果追加新的子组件,请保持以 ASCII 排序。 NOTICE: If you add new child component, please keep ASCII order. @@ -59,39 +61,36 @@ const NotifyChannelEditForm = forwardRef { - setInitialValues(model); - }, [model]); - - const handleFormChange = (_: unknown, fields: NotifyChannelEditFormModelType) => { - onModelChange?.(fields); + const handleFormChange = (_: unknown, values: NotifyChannelEditFormFieldValues) => { + onValuesChange?.(values); }; - useImperativeHandle(ref, () => ({ - getFieldsValue: () => { - return form.getFieldsValue(true); - }, - resetFields: () => { - return form.resetFields(); - }, - validateFields: () => { - return form.validateFields(); - }, - })); + useImperativeHandle(ref, () => { + return { + getFieldsValue: () => { + return formInst.getFieldsValue(true); + }, + resetFields: (fields) => { + return formInst.resetFields(fields); + }, + validateFields: (nameList, config) => { + return formInst.validateFields(nameList, config); + }, + } as NotifyChannelEditFormInstance; + }); return (
- {formFieldsComponent} + {formFieldsEl}
); } diff --git a/ui/src/components/notification/NotifyChannelEditFormBarkFields.tsx b/ui/src/components/notification/NotifyChannelEditFormBarkFields.tsx index dd7ae6c5..f5e4944d 100644 --- a/ui/src/components/notification/NotifyChannelEditFormBarkFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormBarkFields.tsx @@ -9,7 +9,7 @@ const NotifyChannelEditFormBarkFields = () => { const formSchema = z.object({ serverUrl: z .string({ message: t("settings.notification.channel.form.bark_server_url.placeholder") }) - .url({ message: t("common.errmsg.url_invalid") }) + .url(t("common.errmsg.url_invalid")) .nullish(), deviceKey: z .string({ message: t("settings.notification.channel.form.bark_device_key.placeholder") }) diff --git a/ui/src/components/notification/NotifyChannelEditFormEmailFields.tsx b/ui/src/components/notification/NotifyChannelEditFormEmailFields.tsx index 524d84ae..615950bb 100644 --- a/ui/src/components/notification/NotifyChannelEditFormEmailFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormEmailFields.tsx @@ -15,8 +15,7 @@ const NotifyChannelEditFormEmailFields = () => { .number({ message: t("settings.notification.channel.form.email_smtp_port.placeholder") }) .int() .gte(1, t("common.errmsg.port_invalid")) - .lte(65535, t("common.errmsg.port_invalid")) - .transform((v) => +v), + .lte(65535, t("common.errmsg.port_invalid")), smtpTLS: z.boolean().nullish(), username: z .string({ message: t("settings.notification.channel.form.email_username.placeholder") }) @@ -26,23 +25,17 @@ const NotifyChannelEditFormEmailFields = () => { .string({ message: 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") }) - .min(1, t("settings.notification.channel.form.email_sender_address.placeholder")) - .email({ message: t("common.errmsg.email_invalid") }), - receiverAddress: z - .string({ message: t("settings.notification.channel.form.email_receiver_address.placeholder") }) - .min(1, t("settings.notification.channel.form.email_receiver_address.placeholder")) - .email({ message: t("common.errmsg.email_invalid") }), + 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")), }); const formRule = createSchemaFieldRule(formSchema); - const form = Form.useFormInstance(); + const formInst = Form.useFormInstance>(); const handleTLSSwitchChange = (checked: boolean) => { - const oldPort = form.getFieldValue("smtpPort"); + const oldPort = formInst.getFieldValue("smtpPort"); const newPort = checked && (oldPort == null || oldPort === 25) ? 465 : !checked && (oldPort == null || oldPort === 465) ? 25 : oldPort; if (newPort !== oldPort) { - form.setFieldValue("smtpPort", newPort); + formInst.setFieldValue("smtpPort", newPort); } }; @@ -56,13 +49,13 @@ const NotifyChannelEditFormEmailFields = () => {
- +
- +
diff --git a/ui/src/components/notification/NotifyChannelEditFormLarkFields.tsx b/ui/src/components/notification/NotifyChannelEditFormLarkFields.tsx index 1feaccce..bd683824 100644 --- a/ui/src/components/notification/NotifyChannelEditFormLarkFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormLarkFields.tsx @@ -7,10 +7,7 @@ const NotifyChannelEditFormLarkFields = () => { const { t } = useTranslation(); const formSchema = z.object({ - webhookUrl: z - .string({ message: t("settings.notification.channel.form.lark_webhook_url.placeholder") }) - .min(1, t("settings.notification.channel.form.lark_webhook_url.placeholder")) - .url({ message: t("common.errmsg.url_invalid") }), + webhookUrl: z.string({ message: t("settings.notification.channel.form.lark_webhook_url.placeholder") }).url(t("common.errmsg.url_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/notification/NotifyChannelEditFormServerChanFields.tsx b/ui/src/components/notification/NotifyChannelEditFormServerChanFields.tsx index bf6b49b9..b820f925 100644 --- a/ui/src/components/notification/NotifyChannelEditFormServerChanFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormServerChanFields.tsx @@ -7,10 +7,7 @@ const NotifyChannelEditFormServerChanFields = () => { const { t } = useTranslation(); const formSchema = z.object({ - url: z - .string({ message: t("settings.notification.channel.form.serverchan_url.placeholder") }) - .min(1, t("settings.notification.channel.form.serverchan_url.placeholder")) - .url({ message: t("common.errmsg.url_invalid") }), + url: z.string({ message: t("settings.notification.channel.form.serverchan_url.placeholder") }).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 322781cb..abf935c2 100644 --- a/ui/src/components/notification/NotifyChannelEditFormWebhookFields.tsx +++ b/ui/src/components/notification/NotifyChannelEditFormWebhookFields.tsx @@ -7,10 +7,7 @@ const NotifyChannelEditFormWebhookFields = () => { const { t } = useTranslation(); const formSchema = z.object({ - url: z - .string({ message: t("settings.notification.channel.form.webhook_url.placeholder") }) - .min(1, t("settings.notification.channel.form.webhook_url.placeholder")) - .url({ message: t("common.errmsg.url_invalid") }), + url: z.string({ message: t("settings.notification.channel.form.webhook_url.placeholder") }).url(t("common.errmsg.url_invalid")), }); const formRule = createSchemaFieldRule(formSchema); diff --git a/ui/src/components/notification/NotifyChannels.tsx b/ui/src/components/notification/NotifyChannels.tsx index 76d09817..8dacecb9 100644 --- a/ui/src/components/notification/NotifyChannels.tsx +++ b/ui/src/components/notification/NotifyChannels.tsx @@ -1,13 +1,16 @@ import { useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { useDeepCompareMemo } from "@ant-design/pro-components"; -import { Button, Collapse, message, notification, Skeleton, Space, Switch, type CollapseProps } from "antd"; +import { Button, Collapse, type CollapseProps, Skeleton, Space, Switch, message, notification } from "antd"; + +import Show from "@/components/Show"; +import { notifyChannelsMap } from "@/domain/settings"; +import { useZustandShallowSelector } from "@/hooks"; +import { useNotifyChannelsStore } from "@/stores/notify"; +import { getErrMsg } from "@/utils/error"; import NotifyChannelEditForm, { type NotifyChannelEditFormInstance } from "./NotifyChannelEditForm"; import NotifyTestButton from "./NotifyTestButton"; -import { notifyChannelsMap } from "@/domain/settings"; -import { useNotifyChannelStore } from "@/stores/notify"; -import { getErrMsg } from "@/utils/error"; type NotifyChannelProps = { className?: string; @@ -21,13 +24,13 @@ const NotifyChannel = ({ className, style, channel }: NotifyChannelProps) => { const [messageApi, MessageContextHolder] = message.useMessage(); const [notificationApi, NotificationContextHolder] = notification.useNotification(); - const { channels, setChannel } = useNotifyChannelStore(); + const { channels, setChannel } = useNotifyChannelsStore(useZustandShallowSelector(["channels", "setChannel"])); const channelConfig = useDeepCompareMemo(() => channels[channel], [channels, channel]); - const [channelFormChanged, setChannelFormChanged] = useState(false); const channelFormRef = useRef(null); + const [channelFormChanged, setChannelFormChanged] = useState(false); - const handleClickSubmit = async () => { + const handleSubmit = async () => { await channelFormRef.current!.validateFields(); try { @@ -45,10 +48,16 @@ const NotifyChannel = ({ className, style, channel }: NotifyChannelProps) => { {MessageContextHolder} {NotificationContextHolder} - setChannelFormChanged(true)} /> + setChannelFormChanged(true)} + /> - @@ -70,10 +79,12 @@ export type NotifyChannelsProps = { const NotifyChannels = ({ className, classNames, style, styles }: NotifyChannelsProps) => { const { t, i18n } = useTranslation(); - const { initialized, channels, setChannel, fetchChannels } = useNotifyChannelStore(); + const { channels, loadedAtOnce, setChannel, fetchChannels } = useNotifyChannelsStore( + useZustandShallowSelector(["channels", "loadedAtOnce", "setChannel", "fetchChannels"]) + ); useEffect(() => { fetchChannels(); - }, [fetchChannels]); + }, []); const channelCollapseItems: CollapseProps["items"] = useDeepCompareMemo( () => @@ -105,11 +116,9 @@ const NotifyChannels = ({ className, classNames, style, styles }: NotifyChannels return (
- {!initialized ? ( - - ) : ( - - )} + }> + +
); }; diff --git a/ui/src/components/notification/NotifyTemplate.tsx b/ui/src/components/notification/NotifyTemplate.tsx index 21a29cd3..b7cf4e6d 100644 --- a/ui/src/components/notification/NotifyTemplate.tsx +++ b/ui/src/components/notification/NotifyTemplate.tsx @@ -1,12 +1,14 @@ import { useState } from "react"; import { useTranslation } from "react-i18next"; import { useRequest } from "ahooks"; -import { Button, Form, Input, message, notification, Skeleton } from "antd"; +import { Button, Form, Input, Skeleton, message, notification } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; import { ClientResponseError } from "pocketbase"; +import { z } from "zod"; -import { defaultNotifyTemplate, SETTINGS_NAMES, type NotifyTemplatesSettingsContent } from "@/domain/settings"; +import Show from "@/components/Show"; +import { type NotifyTemplatesSettingsContent, SETTINGS_NAMES, defaultNotifyTemplate } from "@/domain/settings"; +import { useAntdForm } from "@/hooks"; import { get as getSettings, save as saveSettings } from "@/repository/settings"; import { getErrMsg } from "@/utils/error"; @@ -24,21 +26,41 @@ const NotifyTemplateForm = ({ className, style }: NotifyTemplateFormProps) => { const formSchema = z.object({ subject: z .string() - .trim() .min(1, t("settings.notification.template.form.subject.placeholder")) - .max(1000, t("common.errmsg.string_max", { max: 1000 })), + .max(1000, t("common.errmsg.string_max", { max: 1000 })) + .trim(), message: z .string() - .trim() .min(1, t("settings.notification.template.form.message.placeholder")) - .max(1000, t("common.errmsg.string_max", { max: 1000 })), + .max(1000, t("common.errmsg.string_max", { max: 1000 })) + .trim(), }); const formRule = createSchemaFieldRule(formSchema); - const [form] = Form.useForm>(); - const [formPending, setFormPending] = useState(false); + const { + form: formInst, + formPending, + formProps, + } = useAntdForm>({ + initialValues: defaultNotifyTemplate, + onSubmit: async (values) => { + try { + const settings = await getSettings(SETTINGS_NAMES.NOTIFY_TEMPLATES); + await saveSettings({ + ...settings, + content: { + notifyTemplates: [values], + }, + }); - const [initialValues, setInitialValues] = useState>>(); - const [initialChanged, setInitialChanged] = useState(false); + messageApi.success(t("common.text.operation_succeeded")); + } catch (err) { + notificationApi.error({ message: t("common.text.request_error"), description: getErrMsg(err) }); + + throw err; + } + }, + }); + const [formChanged, setFormChanged] = useState(false); const { loading } = useRequest( () => { @@ -54,33 +76,13 @@ const NotifyTemplateForm = ({ className, style }: NotifyTemplateFormProps) => { }, onFinally: (_, resp) => { const template = resp?.content?.notifyTemplates?.[0] ?? defaultNotifyTemplate; - setInitialValues({ ...template }); + formInst.setFieldsValue(template); }, } ); const handleInputChange = () => { - setInitialChanged(true); - }; - - const handleFormFinish = async (fields: z.infer) => { - setFormPending(true); - - try { - const settings = await getSettings(SETTINGS_NAMES.NOTIFY_TEMPLATES); - await saveSettings({ - ...settings, - content: { - notifyTemplates: [fields], - }, - }); - - messageApi.success(t("common.text.operation_succeeded")); - } catch (err) { - notificationApi.error({ message: t("common.text.request_error"), description: getErrMsg(err) }); - } finally { - setFormPending(false); - } + setFormChanged(true); }; return ( @@ -88,14 +90,12 @@ const NotifyTemplateForm = ({ className, style }: NotifyTemplateFormProps) => { {MessageContextHolder} {NotificationContextHolder} - {loading ? ( - - ) : ( -
+ }> + @@ -104,7 +104,7 @@ const NotifyTemplateForm = ({ className, style }: NotifyTemplateFormProps) => { { - - )} +
); }; diff --git a/ui/src/components/notification/NotifyTestButton.tsx b/ui/src/components/notification/NotifyTestButton.tsx index f6667aa8..7bc9352b 100644 --- a/ui/src/components/notification/NotifyTestButton.tsx +++ b/ui/src/components/notification/NotifyTestButton.tsx @@ -1,6 +1,6 @@ -import { useRequest } from "ahooks"; import { useTranslation } from "react-i18next"; -import { Button, message, notification, type ButtonProps } from "antd"; +import { useRequest } from "ahooks"; +import { Button, type ButtonProps, message, notification } from "antd"; import { notifyTest } from "@/api/notify"; import { getErrMsg } from "@/utils/error"; diff --git a/ui/src/components/access/AccessTypeSelect.tsx b/ui/src/components/provider/AccessProviderSelect.tsx similarity index 71% rename from ui/src/components/access/AccessTypeSelect.tsx rename to ui/src/components/provider/AccessProviderSelect.tsx index 1899d165..ffba5c8a 100644 --- a/ui/src/components/access/AccessTypeSelect.tsx +++ b/ui/src/components/provider/AccessProviderSelect.tsx @@ -1,15 +1,15 @@ import { memo } from "react"; import { useTranslation } from "react-i18next"; -import { Avatar, Select, Space, Tag, Typography, type SelectProps } from "antd"; +import { Avatar, Select, type SelectProps, Space, Tag, Typography } from "antd"; -import { ACCESS_PROVIDER_USAGES, accessProvidersMap } from "@/domain/access"; +import { ACCESS_USAGES, accessProvidersMap } from "@/domain/provider"; -export type AccessTypeSelectProps = Omit< +export type AccessProviderSelectProps = Omit< SelectProps, "filterOption" | "filterSort" | "labelRender" | "options" | "optionFilterProp" | "optionLabelProp" | "optionRender" >; -const AccessTypeSelect = memo((props: AccessTypeSelectProps) => { +const AccessProviderSelect = (props: AccessProviderSelectProps) => { const { t } = useTranslation(); const options = Array.from(accessProvidersMap.values()).map((item) => ({ @@ -21,25 +21,25 @@ const AccessTypeSelect = memo((props: AccessTypeSelectProps) => { const renderOption = (key: string) => { const provider = accessProvidersMap.get(key); return ( -
- +
+ {t(provider?.name ?? "")}
- {provider?.usage === ACCESS_PROVIDER_USAGES.APPLY && ( + {provider?.usage === ACCESS_USAGES.APPLY && ( <> {t("access.props.provider.usage.dns")} )} - {provider?.usage === ACCESS_PROVIDER_USAGES.DEPLOY && ( + {provider?.usage === ACCESS_USAGES.DEPLOY && ( <> {t("access.props.provider.usage.host")} )} - {provider?.usage === ACCESS_PROVIDER_USAGES.ALL && ( + {provider?.usage === ACCESS_USAGES.ALL && ( <> {t("access.props.provider.usage.dns")} {t("access.props.provider.usage.host")} @@ -66,6 +66,6 @@ const AccessTypeSelect = memo((props: AccessTypeSelectProps) => { optionRender={(option) => renderOption(option.data.value)} /> ); -}); +}; -export default AccessTypeSelect; +export default memo(AccessProviderSelect); diff --git a/ui/src/components/provider/DeployProviderPicker.tsx b/ui/src/components/provider/DeployProviderPicker.tsx new file mode 100644 index 00000000..c6daf18d --- /dev/null +++ b/ui/src/components/provider/DeployProviderPicker.tsx @@ -0,0 +1,66 @@ +import { memo, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { Avatar, Card, Col, Empty, Flex, Input, Row, Typography } from "antd"; + +import Show from "@/components/Show"; +import { deployProvidersMap } from "@/domain/provider"; + +export type DeployProviderPickerProps = { + className?: string; + style?: React.CSSProperties; + onSelect?: (value: string) => void; +}; + +const DeployProviderPicker = ({ className, style, onSelect }: DeployProviderPickerProps) => { + const { t } = useTranslation(); + + const [keyword, setKeyword] = useState(); + + const providers = Array.from(deployProvidersMap.values()); + const filteredProviders = providers.filter((provider) => { + if (keyword) { + const value = keyword.toLowerCase(); + return provider.type.toLowerCase().includes(value) || provider.name.toLowerCase().includes(value); + } + + return true; + }); + + const handleProviderTypeSelect = (value: string) => { + onSelect?.(value); + }; + + return ( +
+ setKeyword(e.target.value.trim())} /> + +
+ 0} fallback={}> + + {filteredProviders.map((provider, index) => { + return ( + + { + handleProviderTypeSelect(provider.type); + }} + > + + + {t(provider.name)} + + + + ); + })} + + +
+
+ ); +}; + +export default memo(DeployProviderPicker); diff --git a/ui/src/components/provider/DeployProviderSelect.tsx b/ui/src/components/provider/DeployProviderSelect.tsx new file mode 100644 index 00000000..54e3643b --- /dev/null +++ b/ui/src/components/provider/DeployProviderSelect.tsx @@ -0,0 +1,51 @@ +import { memo } from "react"; +import { useTranslation } from "react-i18next"; +import { Avatar, Select, type SelectProps, Space, Typography } from "antd"; + +import { deployProvidersMap } from "@/domain/provider"; + +export type DeployProviderSelectProps = Omit< + SelectProps, + "filterOption" | "filterSort" | "labelRender" | "options" | "optionFilterProp" | "optionLabelProp" | "optionRender" +>; + +const DeployProviderSelect = (props: DeployProviderSelectProps) => { + const { t } = useTranslation(); + + const options = Array.from(deployProvidersMap.values()).map((item) => ({ + key: item.type, + value: item.type, + label: t(item.name), + })); + + const renderOption = (key: string) => { + const provider = deployProvidersMap.get(key); + return ( + + + + {t(provider?.name ?? "")} + + + ); + }; + + return ( + - ); -}); -Input.displayName = "Input"; - -export { Input }; diff --git a/ui/src/components/ui/label.tsx b/ui/src/components/ui/label.tsx deleted file mode 100644 index 1887eee3..00000000 --- a/ui/src/components/ui/label.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from "react"; -import * as LabelPrimitive from "@radix-ui/react-label"; -import { cva, type VariantProps } from "class-variance-authority"; - -import { cn } from "./utils"; - -const labelVariants = cva("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"); - -const Label = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & VariantProps ->(({ className, ...props }, ref) => ); -Label.displayName = LabelPrimitive.Root.displayName; - -export { Label }; diff --git a/ui/src/components/ui/scroll-area.tsx b/ui/src/components/ui/scroll-area.tsx deleted file mode 100644 index c6ba88af..00000000 --- a/ui/src/components/ui/scroll-area.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import * as React from "react"; -import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"; - -import { cn } from "./utils"; - -const ScrollArea = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, children, ...props }, ref) => ( - - {children} - - - - ) -); -ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName; - -const ScrollBar = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, orientation = "vertical", ...props }, ref) => ( - - - -)); -ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName; - -export { ScrollArea, ScrollBar }; diff --git a/ui/src/components/ui/select.tsx b/ui/src/components/ui/select.tsx deleted file mode 100644 index 06b20fd6..00000000 --- a/ui/src/components/ui/select.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import * as React from "react"; -import * as SelectPrimitive from "@radix-ui/react-select"; -import { Check, ChevronDown, ChevronUp } from "lucide-react"; - -import { cn } from "./utils"; - -const Select = SelectPrimitive.Root; - -const SelectGroup = SelectPrimitive.Group; - -const SelectValue = SelectPrimitive.Value; - -const SelectTrigger = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, children, ...props }, ref) => ( - span]:line-clamp-1", - className - )} - {...props} - > - {children} - - - - - ) -); -SelectTrigger.displayName = SelectPrimitive.Trigger.displayName; - -const SelectScrollUpButton = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - - - -)); -SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName; - -const SelectScrollDownButton = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - - - -)); -SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName; - -const SelectContent = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, children, position = "popper", ...props }, ref) => ( - - - - - {children} - - - - - ) -); -SelectContent.displayName = SelectPrimitive.Content.displayName; - -const SelectLabel = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, ...props }, ref) => -); -SelectLabel.displayName = SelectPrimitive.Label.displayName; - -const SelectItem = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, children, ...props }, ref) => ( - - - - - - - - {children} - - ) -); -SelectItem.displayName = SelectPrimitive.Item.displayName; - -const SelectSeparator = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, ...props }, ref) => -); -SelectSeparator.displayName = SelectPrimitive.Separator.displayName; - -export { - Select, - SelectGroup, - SelectValue, - SelectTrigger, - SelectContent, - SelectLabel, - SelectItem, - SelectSeparator, - SelectScrollUpButton, - SelectScrollDownButton, -}; diff --git a/ui/src/components/ui/sheet.tsx b/ui/src/components/ui/sheet.tsx deleted file mode 100644 index 145732c8..00000000 --- a/ui/src/components/ui/sheet.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import * as React from "react"; -import * as SheetPrimitive from "@radix-ui/react-dialog"; -import { X } from "lucide-react"; -import { cva, type VariantProps } from "class-variance-authority"; - -import { cn } from "./utils"; - -const Sheet = SheetPrimitive.Root; - -const SheetTrigger = SheetPrimitive.Trigger; - -const SheetClose = SheetPrimitive.Close; - -const SheetPortal = SheetPrimitive.Portal; - -const SheetOverlay = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, ...props }, ref) => ( - - ) -); -SheetOverlay.displayName = SheetPrimitive.Overlay.displayName; - -const sheetVariants = cva( - "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500", - { - variants: { - side: { - top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top", - bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom", - left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm", - right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm", - }, - }, - defaultVariants: { - side: "right", - }, - } -); - -interface SheetContentProps extends React.ComponentPropsWithoutRef, VariantProps {} - -const SheetContent = React.forwardRef, SheetContentProps>( - ({ side = "right", className, children, ...props }, ref) => ( - - - - {children} - - - Close - - - - ) -); -SheetContent.displayName = SheetPrimitive.Content.displayName; - -const SheetHeader = ({ className, ...props }: React.HTMLAttributes) => ( -
-); -SheetHeader.displayName = "SheetHeader"; - -const SheetFooter = ({ className, ...props }: React.HTMLAttributes) => ( -
-); -SheetFooter.displayName = "SheetFooter"; - -const SheetTitle = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, ...props }, ref) => -); -SheetTitle.displayName = SheetPrimitive.Title.displayName; - -const SheetDescription = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ); -SheetDescription.displayName = SheetPrimitive.Description.displayName; - -export { Sheet, SheetPortal, SheetOverlay, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription }; diff --git a/ui/src/components/ui/table.tsx b/ui/src/components/ui/table.tsx deleted file mode 100644 index dbd959ad..00000000 --- a/ui/src/components/ui/table.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import * as React from "react"; - -import { cn } from "./utils"; - -const Table = React.forwardRef>(({ className, ...props }, ref) => ( -
- - -)); -Table.displayName = "Table"; - -const TableHeader = React.forwardRef>(({ className, ...props }, ref) => ( - -)); -TableHeader.displayName = "TableHeader"; - -const TableBody = React.forwardRef>(({ className, ...props }, ref) => ( - -)); -TableBody.displayName = "TableBody"; - -const TableFooter = React.forwardRef>(({ className, ...props }, ref) => ( - tr]:last:border-b-0", className)} {...props} /> -)); -TableFooter.displayName = "TableFooter"; - -const TableRow = React.forwardRef>(({ className, ...props }, ref) => ( - -)); -TableRow.displayName = "TableRow"; - -const TableHead = React.forwardRef>(({ className, ...props }, ref) => ( -
-)); -TableHead.displayName = "TableHead"; - -const TableCell = React.forwardRef>(({ className, ...props }, ref) => ( - -)); -TableCell.displayName = "TableCell"; - -const TableCaption = React.forwardRef>(({ className, ...props }, ref) => ( -
-)); -TableCaption.displayName = "TableCaption"; - -export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption }; diff --git a/ui/src/components/ui/textarea.tsx b/ui/src/components/ui/textarea.tsx deleted file mode 100644 index 6df000eb..00000000 --- a/ui/src/components/ui/textarea.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from "react"; - -import { cn } from "./utils"; - -export interface TextareaProps extends React.TextareaHTMLAttributes {} - -const Textarea = React.forwardRef(({ className, ...props }, ref) => { - return ( -