From b9b5aadb6c10cc369bb5b13c275e90f956d7a1c5 Mon Sep 17 00:00:00 2001 From: "github-action[bot]" Date: Sat, 15 Jun 2024 20:30:12 +0200 Subject: [PATCH] Update On Sat Jun 15 20:30:11 CEST 2024 --- .github/update.log | 1 + .../github/kr328/clash/core/model/Proxy.kt | 2 + clash-meta/adapter/outbound/direct.go | 3 +- clash-meta/adapter/outboundgroup/relay.go | 2 + clash-meta/dns/client.go | 25 +- clash-meta/tunnel/dns_dialer.go | 155 ++++----- clash-nyanpasu/manifest/version.json | 4 +- clash-nyanpasu/package.json | 4 +- clash-nyanpasu/pnpm-lock.yaml | 329 +++++++++++++++++- clash-nyanpasu/scripts/check.ts | 1 + .../scripts/generate-latest-version.ts | 176 ++-------- clash-nyanpasu/scripts/package.json | 3 + clash-nyanpasu/scripts/tsconfig.json | 2 +- clash-nyanpasu/scripts/types/index.d.ts | 18 - clash-nyanpasu/scripts/types/index.ts | 44 +++ clash-nyanpasu/scripts/utils/env.ts | 1 + clash-nyanpasu/scripts/utils/manifest.ts | 113 ++++++ clash-nyanpasu/scripts/utils/octokit.ts | 8 + clash-verge-rev/.github/workflows/alpha.yml | 4 + .../src/components/profile/editor-viewer.tsx | 10 +- clash-verge-rev/src/pages/logs.tsx | 10 +- clash-verge-rev/src/services/api.ts | 42 ++- clash-verge-rev/src/services/cmds.ts | 31 +- echo/examples/web.json | 2 +- echo/internal/cli/config.go | 2 +- echo/internal/glue/interface.go | 14 + echo/internal/relay/health_check.go | 19 + echo/internal/relay/server_reloader.go | 4 +- echo/internal/reloader/reloader.go | 5 - echo/internal/transporter/base.go | 14 +- echo/internal/transporter/interface.go | 40 ++- echo/internal/transporter/raw.go | 32 +- echo/internal/transporter/raw_mux.go | 8 +- echo/internal/transporter/ws.go | 30 +- echo/internal/transporter/ws_mux.go | 5 +- echo/internal/transporter/wss.go | 5 +- echo/internal/transporter/wss_mux.go | 5 +- echo/internal/web/handlers.go | 27 +- echo/internal/web/server.go | 30 +- echo/internal/web/templates/connection.html | 8 +- echo/internal/web/templates/index.html | 17 +- echo/internal/web/types.go | 5 + .../package/lean/autocore/files/arm/index.htm | 2 +- .../lean/autocore/files/arm/sbin/usage | 4 +- lede/package/lean/default-settings/Makefile | 3 +- .../files/zzz-default-settings | 2 +- .../lean/default-settings/po/zh-cn/default.po | 9 +- lede/package/qca/qca-mcs/Makefile | 27 +- lede/package/qca/qca-nss-clients/Makefile | 42 +-- lede/package/qca/qca-ssdk-shell/Makefile | 3 +- .../arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi | 271 +++++++++++++++ .../etc/hotplug.d/firmware/11-ath11k-caldata | 3 +- mihomo/adapter/outbound/direct.go | 3 +- mihomo/adapter/outboundgroup/relay.go | 2 + mihomo/dns/client.go | 25 +- mihomo/tunnel/dns_dialer.go | 155 ++++----- openwrt-packages/luci-app-amlogic/Makefile | 6 +- .../root/usr/sbin/openwrt-kernel | 4 +- .../root/usr/sbin/openwrt-update-amlogic | 2 +- .../root/usr/sbin/openwrt-update-kvm | 2 +- shadowsocks-rust/README.md | 2 - yass/.github/workflows/releases-deb.yml | 20 +- yass/.github/workflows/releases-rpm.yml | 23 +- yass/CMakeLists.txt | 23 +- yass/README.md | 16 +- yass/debian/changelog | 5 + yass/docker/opensuse15.Dockerfile | 4 +- yass/yass.spec.in | 7 +- 68 files changed, 1297 insertions(+), 628 deletions(-) delete mode 100644 clash-nyanpasu/scripts/types/index.d.ts create mode 100644 clash-nyanpasu/scripts/types/index.ts create mode 100644 clash-nyanpasu/scripts/utils/manifest.ts create mode 100644 clash-nyanpasu/scripts/utils/octokit.ts create mode 100644 echo/internal/glue/interface.go create mode 100644 echo/internal/relay/health_check.go delete mode 100644 echo/internal/reloader/reloader.go create mode 100644 echo/internal/web/types.go create mode 100644 lede/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi diff --git a/.github/update.log b/.github/update.log index 94d90db19a..8e218b43dc 100644 --- a/.github/update.log +++ b/.github/update.log @@ -673,3 +673,4 @@ Update On Tue Jun 11 20:31:29 CEST 2024 Update On Wed Jun 12 20:32:18 CEST 2024 Update On Thu Jun 13 20:31:26 CEST 2024 Update On Fri Jun 14 20:32:58 CEST 2024 +Update On Sat Jun 15 20:30:01 CEST 2024 diff --git a/clash-meta-android/core/src/main/java/com/github/kr328/clash/core/model/Proxy.kt b/clash-meta-android/core/src/main/java/com/github/kr328/clash/core/model/Proxy.kt index ceff284433..fecbb43036 100644 --- a/clash-meta-android/core/src/main/java/com/github/kr328/clash/core/model/Proxy.kt +++ b/clash-meta-android/core/src/main/java/com/github/kr328/clash/core/model/Proxy.kt @@ -33,6 +33,8 @@ data class Proxy( Hysteria2(false), Tuic(false), WireGuard(false), + Dns(false), + Ssh(false), Relay(true), diff --git a/clash-meta/adapter/outbound/direct.go b/clash-meta/adapter/outbound/direct.go index 09b9696b2f..c904d3b62a 100644 --- a/clash-meta/adapter/outbound/direct.go +++ b/clash-meta/adapter/outbound/direct.go @@ -3,7 +3,6 @@ package outbound import ( "context" "errors" - "net/netip" "os" "strconv" @@ -58,7 +57,7 @@ func (d *Direct) ListenPacketContext(ctx context.Context, metadata *C.Metadata, } metadata.DstIP = ip } - pc, err := dialer.NewDialer(d.Base.DialOptions(opts...)...).ListenPacket(ctx, "udp", "", netip.AddrPortFrom(metadata.DstIP, metadata.DstPort)) + pc, err := dialer.NewDialer(d.Base.DialOptions(opts...)...).ListenPacket(ctx, "udp", "", metadata.AddrPort()) if err != nil { return nil, err } diff --git a/clash-meta/adapter/outboundgroup/relay.go b/clash-meta/adapter/outboundgroup/relay.go index 07fbcd9588..29aa9c6a74 100644 --- a/clash-meta/adapter/outboundgroup/relay.go +++ b/clash-meta/adapter/outboundgroup/relay.go @@ -9,6 +9,7 @@ import ( "github.com/metacubex/mihomo/component/proxydialer" C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/constant/provider" + "github.com/metacubex/mihomo/log" ) type Relay struct { @@ -149,6 +150,7 @@ func (r *Relay) Addr() string { } func NewRelay(option *GroupCommonOption, providers []provider.ProxyProvider) *Relay { + log.Warnln("The group [%s] with relay type is deprecated, please using dialer-proxy instead", option.Name) return &Relay{ GroupBase: NewGroupBase(GroupBaseOption{ outbound.BaseOption{ diff --git a/clash-meta/dns/client.go b/clash-meta/dns/client.go index ff545c9087..096b96a7f5 100644 --- a/clash-meta/dns/client.go +++ b/clash-meta/dns/client.go @@ -5,20 +5,16 @@ import ( "crypto/tls" "fmt" "net" - "net/netip" "strings" "github.com/metacubex/mihomo/component/ca" - "github.com/metacubex/mihomo/component/resolver" "github.com/metacubex/mihomo/log" - "github.com/metacubex/randv2" D "github.com/miekg/dns" ) type client struct { *D.Client - r *Resolver port string host string dialer *dnsDialer @@ -45,31 +41,12 @@ func (c *client) Address() string { } func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error) { - var ( - ip netip.Addr - err error - ) - if c.r == nil { - // a default ip dns - if ip, err = netip.ParseAddr(c.host); err != nil { - return nil, fmt.Errorf("dns %s not a valid ip", c.host) - } - } else { - ips, err := resolver.LookupIPWithResolver(ctx, c.host, c.r) - if err != nil { - return nil, fmt.Errorf("use default dns resolve failed: %w", err) - } else if len(ips) == 0 { - return nil, fmt.Errorf("%w: %s", resolver.ErrIPNotFound, c.host) - } - ip = ips[randv2.IntN(len(ips))] - } - network := "udp" if strings.HasPrefix(c.Client.Net, "tcp") { network = "tcp" } - addr := net.JoinHostPort(ip.String(), c.port) + addr := net.JoinHostPort(c.host, c.port) conn, err := c.dialer.DialContext(ctx, network, addr) if err != nil { return nil, err diff --git a/clash-meta/tunnel/dns_dialer.go b/clash-meta/tunnel/dns_dialer.go index 00e287fee7..1839869b4a 100644 --- a/clash-meta/tunnel/dns_dialer.go +++ b/clash-meta/tunnel/dns_dialer.go @@ -6,7 +6,6 @@ import ( "context" "fmt" "net" - "net/netip" "strings" N "github.com/metacubex/mihomo/common/net" @@ -34,102 +33,98 @@ func (d *DNSDialer) DialContext(ctx context.Context, network, addr string) (net. proxyName := d.proxyName proxyAdapter := d.proxyAdapter opts := d.opts - if len(proxyName) == 0 && proxyAdapter == nil { - opts = append(opts, dialer.WithResolver(r)) - return dialer.DialContext(ctx, network, addr, opts...) - } else { - metadata := &C.Metadata{ - NetWork: C.TCP, - Type: C.INNER, + var rule C.Rule + metadata := &C.Metadata{ + NetWork: C.TCP, + Type: C.INNER, + } + err := metadata.SetRemoteAddress(addr) // tcp can resolve host by remote + if err != nil { + return nil, err + } + if !strings.Contains(network, "tcp") { + metadata.NetWork = C.UDP + if !metadata.Resolved() { + // udp must resolve host first + dstIP, err := resolver.ResolveIPWithResolver(ctx, metadata.Host, r) + if err != nil { + return nil, err + } + metadata.DstIP = dstIP } - err := metadata.SetRemoteAddress(addr) // tcp can resolve host by remote - if err != nil { - return nil, err - } - if !strings.Contains(network, "tcp") { - metadata.NetWork = C.UDP + } + + if proxyAdapter == nil && len(proxyName) != 0 { + if proxyName == DnsRespectRules { if !metadata.Resolved() { - // udp must resolve host first + // resolve here before resolveMetadata to avoid its inner resolver.ResolveIP dstIP, err := resolver.ResolveIPWithResolver(ctx, metadata.Host, r) if err != nil { return nil, err } metadata.DstIP = dstIP } + proxyAdapter, rule, err = resolveMetadata(metadata) + if err != nil { + return nil, err + } + } else { + var ok bool + proxyAdapter, ok = Proxies()[proxyName] + if !ok { + opts = append(opts, dialer.WithInterface(proxyName)) + } + } + } + + if metadata.NetWork == C.TCP { + if proxyAdapter == nil { + opts = append(opts, dialer.WithResolver(r)) + return dialer.DialContext(ctx, network, addr, opts...) } - var rule C.Rule - if proxyAdapter == nil { - if proxyName == DnsRespectRules { - if !metadata.Resolved() { - // resolve here before resolveMetadata to avoid its inner resolver.ResolveIP - dstIP, err := resolver.ResolveIPWithResolver(ctx, metadata.Host, r) - if err != nil { - return nil, err - } - metadata.DstIP = dstIP - } - proxyAdapter, rule, err = resolveMetadata(metadata) + if proxyAdapter.IsL3Protocol(metadata) { // L3 proxy should resolve domain before to avoid loopback + if !metadata.Resolved() { + dstIP, err := resolver.ResolveIPWithResolver(ctx, metadata.Host, r) if err != nil { return nil, err } - } else { - var ok bool - proxyAdapter, ok = Proxies()[proxyName] - if !ok { - opts = append(opts, dialer.WithInterface(proxyName)) - } + metadata.DstIP = dstIP } + metadata.Host = "" // clear host to avoid double resolve in proxy } - if strings.Contains(network, "tcp") { - if proxyAdapter == nil { - opts = append(opts, dialer.WithResolver(r)) - return dialer.DialContext(ctx, network, addr, opts...) - } - - if proxyAdapter.IsL3Protocol(metadata) { // L3 proxy should resolve domain before to avoid loopback - if !metadata.Resolved() { - dstIP, err := resolver.ResolveIPWithResolver(ctx, metadata.Host, r) - if err != nil { - return nil, err - } - metadata.DstIP = dstIP - } - metadata.Host = "" // clear host to avoid double resolve in proxy - } - - conn, err := proxyAdapter.DialContext(ctx, metadata, opts...) - if err != nil { - logMetadataErr(metadata, rule, proxyAdapter, err) - return nil, err - } - logMetadata(metadata, rule, conn) - - conn = statistic.NewTCPTracker(conn, statistic.DefaultManager, metadata, rule, 0, 0, false) - - return conn, nil - } else { - if proxyAdapter == nil { - return dialer.DialContext(ctx, network, addr, opts...) - } - - if !proxyAdapter.SupportUDP() { - return nil, fmt.Errorf("proxy adapter [%s] UDP is not supported", proxyAdapter) - } - - packetConn, err := proxyAdapter.ListenPacketContext(ctx, metadata, opts...) - if err != nil { - logMetadataErr(metadata, rule, proxyAdapter, err) - return nil, err - } - logMetadata(metadata, rule, packetConn) - - packetConn = statistic.NewUDPTracker(packetConn, statistic.DefaultManager, metadata, rule, 0, 0, false) - - return N.NewBindPacketConn(packetConn, metadata.UDPAddr()), nil + conn, err := proxyAdapter.DialContext(ctx, metadata, opts...) + if err != nil { + logMetadataErr(metadata, rule, proxyAdapter, err) + return nil, err } + logMetadata(metadata, rule, conn) + + conn = statistic.NewTCPTracker(conn, statistic.DefaultManager, metadata, rule, 0, 0, false) + + return conn, nil + } else { + if proxyAdapter == nil { + return dialer.DialContext(ctx, network, metadata.AddrPort().String(), opts...) + } + + if !proxyAdapter.SupportUDP() { + return nil, fmt.Errorf("proxy adapter [%s] UDP is not supported", proxyAdapter) + } + + packetConn, err := proxyAdapter.ListenPacketContext(ctx, metadata, opts...) + if err != nil { + logMetadataErr(metadata, rule, proxyAdapter, err) + return nil, err + } + logMetadata(metadata, rule, packetConn) + + packetConn = statistic.NewUDPTracker(packetConn, statistic.DefaultManager, metadata, rule, 0, 0, false) + + return N.NewBindPacketConn(packetConn, metadata.UDPAddr()), nil } + } func (d *DNSDialer) ListenPacket(ctx context.Context, network, addr string) (net.PacketConn, error) { @@ -171,7 +166,7 @@ func (d *DNSDialer) ListenPacket(ctx context.Context, network, addr string) (net } if proxyAdapter == nil { - return dialer.NewDialer(opts...).ListenPacket(ctx, network, "", netip.AddrPortFrom(metadata.DstIP, metadata.DstPort)) + return dialer.NewDialer(opts...).ListenPacket(ctx, network, "", metadata.AddrPort()) } if !proxyAdapter.SupportUDP() { diff --git a/clash-nyanpasu/manifest/version.json b/clash-nyanpasu/manifest/version.json index df50a8152e..2154e44c15 100644 --- a/clash-nyanpasu/manifest/version.json +++ b/clash-nyanpasu/manifest/version.json @@ -2,7 +2,7 @@ "manifest_version": 1, "latest": { "mihomo": "v1.18.5", - "mihomo_alpha": "alpha-d96d765", + "mihomo_alpha": "alpha-9b02d91", "clash_rs": "v0.1.18", "clash_premium": "2023-09-05-gdcc8d87" }, @@ -36,5 +36,5 @@ "darwin-x64": "clash-darwin-amd64-n{}.gz" } }, - "updated_at": "2024-06-13T05:37:49.210Z" + "updated_at": "2024-06-14T22:20:16.949Z" } diff --git a/clash-nyanpasu/package.json b/clash-nyanpasu/package.json index cb6f012e75..f57ca83bf6 100644 --- a/clash-nyanpasu/package.json +++ b/clash-nyanpasu/package.json @@ -29,7 +29,7 @@ "fmt": "run-p fmt:*", "fmt:backend": "cargo fmt --manifest-path ./backend/Cargo.toml --all", "fmt:prettier": "prettier --write .", - "check": "tsx scripts/check.ts", + "check": "pnpm generate:manifest && tsx scripts/check.ts", "updater": "tsx scripts/updater.ts", "updater:nightly": "tsx scripts/updater-nightly.ts", "send-notify": "tsx scripts/telegram-notify.ts", @@ -106,7 +106,7 @@ "stylelint-order": "6.0.4", "stylelint-scss": "6.3.1", "tailwindcss": "3.4.4", - "tsx": "4.15.4", + "tsx": "4.15.5", "typescript": "5.4.5" }, "packageManager": "pnpm@9.3.0", diff --git a/clash-nyanpasu/pnpm-lock.yaml b/clash-nyanpasu/pnpm-lock.yaml index 9aa1182de4..e86370bfe7 100644 --- a/clash-nyanpasu/pnpm-lock.yaml +++ b/clash-nyanpasu/pnpm-lock.yaml @@ -134,8 +134,8 @@ importers: specifier: 3.4.4 version: 3.4.4 tsx: - specifier: 4.15.4 - version: 4.15.4 + specifier: 4.15.5 + version: 4.15.5 typescript: specifier: 5.4.5 version: 5.4.5 @@ -374,6 +374,9 @@ importers: specifier: 1.7.0 version: 1.7.0 devDependencies: + '@octokit/types': + specifier: 13.5.0 + version: 13.5.0 '@types/adm-zip': specifier: 0.5.5 version: 0.5.5 @@ -395,6 +398,9 @@ importers: node-fetch: specifier: 3.3.2 version: 3.3.2 + octokit: + specifier: 4.0.2 + version: 4.0.2 picocolors: specifier: 1.0.1 version: 1.0.1 @@ -1252,14 +1258,50 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@octokit/app@15.1.0': + resolution: {integrity: sha512-TkBr7QgOmE6ORxvIAhDbZsqPkF7RSqTY4pLTtUQCvr6dTXqvi2fFo46q3h1lxlk/sGMQjqyZ0kEahkD/NyzOHg==} + engines: {node: '>= 18'} + + '@octokit/auth-app@7.1.0': + resolution: {integrity: sha512-cazGaJPSgeZ8NkVYeM/C5l/6IQ5vZnsI8p1aMucadCkt/bndI+q+VqwrlnWbASRmenjOkf1t1RpCKrif53U8gw==} + engines: {node: '>= 18'} + + '@octokit/auth-oauth-app@8.1.1': + resolution: {integrity: sha512-5UtmxXAvU2wfcHIPPDWzVSAWXVJzG3NWsxb7zCFplCWEmMCArSZV0UQu5jw5goLQXbFyOr5onzEH37UJB3zQQg==} + engines: {node: '>= 18'} + + '@octokit/auth-oauth-device@7.1.1': + resolution: {integrity: sha512-HWl8lYueHonuyjrKKIup/1tiy0xcmQCdq5ikvMO1YwkNNkxb6DXfrPjrMYItNLyCP/o2H87WuijuE+SlBTT8eg==} + engines: {node: '>= 18'} + + '@octokit/auth-oauth-user@5.1.1': + resolution: {integrity: sha512-rRkMz0ErOppdvEfnemHJXgZ9vTPhBuC6yASeFaB7I2yLMd7QpjfrL1mnvRPlyKo+M6eeLxrKanXJ9Qte29SRsw==} + engines: {node: '>= 18'} + '@octokit/auth-token@4.0.0': resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==} engines: {node: '>= 18'} + '@octokit/auth-token@5.1.1': + resolution: {integrity: sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==} + engines: {node: '>= 18'} + + '@octokit/auth-unauthenticated@6.1.0': + resolution: {integrity: sha512-zPSmfrUAcspZH/lOFQnVnvjQZsIvmfApQH6GzJrkIunDooU1Su2qt2FfMTSVPRp7WLTQyC20Kd55lF+mIYaohQ==} + engines: {node: '>= 18'} + '@octokit/core@5.2.0': resolution: {integrity: sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==} engines: {node: '>= 18'} + '@octokit/core@6.1.2': + resolution: {integrity: sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==} + engines: {node: '>= 18'} + + '@octokit/endpoint@10.1.1': + resolution: {integrity: sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==} + engines: {node: '>= 18'} + '@octokit/endpoint@9.0.5': resolution: {integrity: sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==} engines: {node: '>= 18'} @@ -1268,12 +1310,43 @@ packages: resolution: {integrity: sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==} engines: {node: '>= 18'} + '@octokit/graphql@8.1.1': + resolution: {integrity: sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg==} + engines: {node: '>= 18'} + + '@octokit/oauth-app@7.1.2': + resolution: {integrity: sha512-4ntCOZIiTozKwuYQroX/ZD722tzMH8Eicv/cgDM/3F3lyrlwENHDv4flTCBpSJbfK546B2SrkKMWB+/HbS84zQ==} + engines: {node: '>= 18'} + + '@octokit/oauth-authorization-url@7.1.1': + resolution: {integrity: sha512-ooXV8GBSabSWyhLUowlMIVd9l1s2nsOGQdlP2SQ4LnkEsGXzeCvbSbCPdZThXhEFzleGPwbapT0Sb+YhXRyjCA==} + engines: {node: '>= 18'} + + '@octokit/oauth-methods@5.1.2': + resolution: {integrity: sha512-C5lglRD+sBlbrhCUTxgJAFjWgJlmTx5bQ7Ch0+2uqRjYv7Cfb5xpX4WuSC9UgQna3sqRGBL9EImX9PvTpMaQ7g==} + engines: {node: '>= 18'} + '@octokit/openapi-types@20.0.0': resolution: {integrity: sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==} '@octokit/openapi-types@22.2.0': resolution: {integrity: sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==} + '@octokit/openapi-webhooks-types@8.2.1': + resolution: {integrity: sha512-msAU1oTSm0ZmvAE0xDemuF4tVs5i0xNnNGtNmr4EuATi+1Rn8cZDetj6NXioSf5LwnxEc209COa/WOSbjuhLUA==} + + '@octokit/plugin-paginate-graphql@5.2.2': + resolution: {integrity: sha512-7znSVvlNAOJisCqAnjN1FtEziweOHSjPGAuc5W58NeGNAr/ZB57yCsjQbXDlWsVryA7hHQaEQPcBbJYFawlkyg==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-paginate-rest@11.3.0': + resolution: {integrity: sha512-n4znWfRinnUQF6TPyxs7EctSAA3yVSP4qlJP2YgI3g9d4Ae2n5F3XDOjbUluKRxPU3rfsgpOboI4O4VtPc6Ilg==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=6' + '@octokit/plugin-paginate-rest@9.2.1': resolution: {integrity: sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==} engines: {node: '>= 18'} @@ -1286,20 +1359,54 @@ packages: peerDependencies: '@octokit/core': '5' + '@octokit/plugin-rest-endpoint-methods@13.2.1': + resolution: {integrity: sha512-YMWBw6Exh1ZBs5cCE0AnzYxSQDIJS00VlBqISTgNYmu5MBdeM07K/MAJjy/VkNaH5jpJmD/5HFUvIZ+LDB5jSQ==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-retry@7.1.1': + resolution: {integrity: sha512-G9Ue+x2odcb8E1XIPhaFBnTTIrrUDfXN05iFXiqhR+SeeeDMMILcAnysOsxUpEWcQp2e5Ft397FCXTcPkiPkLw==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-throttling@9.3.0': + resolution: {integrity: sha512-B5YTToSRTzNSeEyssnrT7WwGhpIdbpV9NKIs3KyTWHX6PhpYn7gqF/+lL3BvsASBM3Sg5BAUYk7KZx5p/Ec77w==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': ^6.0.0 + '@octokit/request-error@5.1.0': resolution: {integrity: sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==} engines: {node: '>= 18'} + '@octokit/request-error@6.1.1': + resolution: {integrity: sha512-1mw1gqT3fR/WFvnoVpY/zUM2o/XkMs/2AszUUG9I69xn0JFLv6PGkPhNk5lbfvROs79wiS0bqiJNxfCZcRJJdg==} + engines: {node: '>= 18'} + '@octokit/request@8.4.0': resolution: {integrity: sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==} engines: {node: '>= 18'} + '@octokit/request@9.1.1': + resolution: {integrity: sha512-pyAguc0p+f+GbQho0uNetNQMmLG1e80WjkIaqqgUkihqUp0boRU6nKItXO4VWnr+nbZiLGEyy4TeKRwqaLvYgw==} + engines: {node: '>= 18'} + '@octokit/types@12.6.0': resolution: {integrity: sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==} '@octokit/types@13.5.0': resolution: {integrity: sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==} + '@octokit/webhooks-methods@5.1.0': + resolution: {integrity: sha512-yFZa3UH11VIxYnnoOYCVoJ3q4ChuSOk2IVBBQ0O3xtKX4x9bmKb/1t+Mxixv2iUhzMdOl1qeWJqEhouXXzB3rQ==} + engines: {node: '>= 18'} + + '@octokit/webhooks@13.2.7': + resolution: {integrity: sha512-sPHCyi9uZuCs1gg0yF53FFocM+GsiiBEhQQV/itGzzQ8gjyv2GMJ1YvgdDY4lC0ePZeiV3juEw4GbS6w1VHhRw==} + engines: {node: '>= 18'} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -1561,6 +1668,9 @@ packages: '@types/adm-zip@0.5.5': resolution: {integrity: sha512-YCGstVMjc4LTY5uK9/obvxBya93axZOVOyf2GSUulADzmLhYE45u2nAssCs/fWBs1Ifq5Vat75JTPwd5XZoPJw==} + '@types/aws-lambda@8.10.138': + resolution: {integrity: sha512-71EHMl70TPWIAsFuHd85NHq6S6T2OOjiisPTrH7RgcjzpJpPh4RQJv7PvVvIxc6PIp8CLV7F9B+TdjcAES5vcA==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -1749,6 +1859,10 @@ packages: resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} engines: {node: '>= 14'} + aggregate-error@5.0.0: + resolution: {integrity: sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==} + engines: {node: '>=18'} + ahooks@3.8.0: resolution: {integrity: sha512-M01m+mxLRNNeJ/PCT3Fom26UyreTj6oMqJBetUrJnK4VNI5j6eMA543Xxo53OBXn6XibA2FXKcCCgrT6YCTtKQ==} engines: {node: '>=8.0.0'} @@ -1895,6 +2009,9 @@ packages: before-after-hook@2.2.3: resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} + before-after-hook@3.0.2: + resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==} + big-integer@1.6.52: resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} engines: {node: '>=0.6'} @@ -1906,6 +2023,9 @@ packages: boolean@3.2.0: resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} + bottleneck@2.19.5: + resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==} + boxen@1.3.0: resolution: {integrity: sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==} engines: {node: '>=4'} @@ -2014,6 +2134,10 @@ packages: classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + clean-stack@5.2.0: + resolution: {integrity: sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==} + engines: {node: '>=14.16'} + cli-boxes@1.0.0: resolution: {integrity: sha512-3Fo5wu8Ytle8q9iCzS4D2MWVL2X7JVWRiS1BnXbTFDhS9c/REkM9vd1AmabsoZoY5/dGi5TT9iKL8Kb6DeBRQg==} engines: {node: '>=0.10.0'} @@ -2459,6 +2583,10 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + eslint-compat-utils@0.5.0: resolution: {integrity: sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==} engines: {node: '>=12'} @@ -3011,6 +3139,10 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. @@ -3779,6 +3911,10 @@ packages: resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} engines: {node: '>= 0.4'} + octokit@4.0.2: + resolution: {integrity: sha512-wbqF4uc1YbcldtiBFfkSnquHtECEIpYD78YUXI6ri1Im5OO2NLo6ZVpRdbJpdnpZ05zMrVPssNiEo6JQtea+Qg==} + engines: {node: '>= 18'} + ofetch@1.3.4: resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==} @@ -4710,8 +4846,8 @@ packages: tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - tsx@4.15.4: - resolution: {integrity: sha512-d++FLCwJLrXaBFtRcqdPBzu6FiVOJ2j+UsvUZPtoTrnYtCGU5CEW7iHXtNZfA2fcRTvJFWPqA6SWBuB0GSva9w==} + tsx@4.15.5: + resolution: {integrity: sha512-iKi8jQ2VBmZ2kU/FkGkL2OSHBHsazsUzsdC/W/RwhKIEsIoZ1alCclZHP5jGfNHEaEWUJFM1GquzCf+4db3b0w==} engines: {node: '>=18.0.0'} hasBin: true @@ -4811,9 +4947,15 @@ packages: unist-util-visit@5.0.0: resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + universal-github-app-jwt@2.2.0: + resolution: {integrity: sha512-G5o6f95b5BggDGuUfKDApKaCgNYy2x7OdHY0zSMF081O0EJobw+1130VONhrA7ezGSV2FNOGyM+KQpQZAr9bIQ==} + universal-user-agent@6.0.1: resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} + universal-user-agent@7.0.2: + resolution: {integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==} + universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -5898,8 +6040,59 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 + '@octokit/app@15.1.0': + dependencies: + '@octokit/auth-app': 7.1.0 + '@octokit/auth-unauthenticated': 6.1.0 + '@octokit/core': 6.1.2 + '@octokit/oauth-app': 7.1.2 + '@octokit/plugin-paginate-rest': 11.3.0(@octokit/core@6.1.2) + '@octokit/types': 13.5.0 + '@octokit/webhooks': 13.2.7 + + '@octokit/auth-app@7.1.0': + dependencies: + '@octokit/auth-oauth-app': 8.1.1 + '@octokit/auth-oauth-user': 5.1.1 + '@octokit/request': 9.1.1 + '@octokit/request-error': 6.1.1 + '@octokit/types': 13.5.0 + lru-cache: 10.2.2 + universal-github-app-jwt: 2.2.0 + universal-user-agent: 7.0.2 + + '@octokit/auth-oauth-app@8.1.1': + dependencies: + '@octokit/auth-oauth-device': 7.1.1 + '@octokit/auth-oauth-user': 5.1.1 + '@octokit/request': 9.1.1 + '@octokit/types': 13.5.0 + universal-user-agent: 7.0.2 + + '@octokit/auth-oauth-device@7.1.1': + dependencies: + '@octokit/oauth-methods': 5.1.2 + '@octokit/request': 9.1.1 + '@octokit/types': 13.5.0 + universal-user-agent: 7.0.2 + + '@octokit/auth-oauth-user@5.1.1': + dependencies: + '@octokit/auth-oauth-device': 7.1.1 + '@octokit/oauth-methods': 5.1.2 + '@octokit/request': 9.1.1 + '@octokit/types': 13.5.0 + universal-user-agent: 7.0.2 + '@octokit/auth-token@4.0.0': {} + '@octokit/auth-token@5.1.1': {} + + '@octokit/auth-unauthenticated@6.1.0': + dependencies: + '@octokit/request-error': 6.1.1 + '@octokit/types': 13.5.0 + '@octokit/core@5.2.0': dependencies: '@octokit/auth-token': 4.0.0 @@ -5910,6 +6103,21 @@ snapshots: before-after-hook: 2.2.3 universal-user-agent: 6.0.1 + '@octokit/core@6.1.2': + dependencies: + '@octokit/auth-token': 5.1.1 + '@octokit/graphql': 8.1.1 + '@octokit/request': 9.1.1 + '@octokit/request-error': 6.1.1 + '@octokit/types': 13.5.0 + before-after-hook: 3.0.2 + universal-user-agent: 7.0.2 + + '@octokit/endpoint@10.1.1': + dependencies: + '@octokit/types': 13.5.0 + universal-user-agent: 7.0.2 + '@octokit/endpoint@9.0.5': dependencies: '@octokit/types': 13.5.0 @@ -5921,10 +6129,47 @@ snapshots: '@octokit/types': 13.5.0 universal-user-agent: 6.0.1 + '@octokit/graphql@8.1.1': + dependencies: + '@octokit/request': 9.1.1 + '@octokit/types': 13.5.0 + universal-user-agent: 7.0.2 + + '@octokit/oauth-app@7.1.2': + dependencies: + '@octokit/auth-oauth-app': 8.1.1 + '@octokit/auth-oauth-user': 5.1.1 + '@octokit/auth-unauthenticated': 6.1.0 + '@octokit/core': 6.1.2 + '@octokit/oauth-authorization-url': 7.1.1 + '@octokit/oauth-methods': 5.1.2 + '@types/aws-lambda': 8.10.138 + universal-user-agent: 7.0.2 + + '@octokit/oauth-authorization-url@7.1.1': {} + + '@octokit/oauth-methods@5.1.2': + dependencies: + '@octokit/oauth-authorization-url': 7.1.1 + '@octokit/request': 9.1.1 + '@octokit/request-error': 6.1.1 + '@octokit/types': 13.5.0 + '@octokit/openapi-types@20.0.0': {} '@octokit/openapi-types@22.2.0': {} + '@octokit/openapi-webhooks-types@8.2.1': {} + + '@octokit/plugin-paginate-graphql@5.2.2(@octokit/core@6.1.2)': + dependencies: + '@octokit/core': 6.1.2 + + '@octokit/plugin-paginate-rest@11.3.0(@octokit/core@6.1.2)': + dependencies: + '@octokit/core': 6.1.2 + '@octokit/types': 13.5.0 + '@octokit/plugin-paginate-rest@9.2.1(@octokit/core@5.2.0)': dependencies: '@octokit/core': 5.2.0 @@ -5935,12 +6180,34 @@ snapshots: '@octokit/core': 5.2.0 '@octokit/types': 12.6.0 + '@octokit/plugin-rest-endpoint-methods@13.2.1(@octokit/core@6.1.2)': + dependencies: + '@octokit/core': 6.1.2 + '@octokit/types': 13.5.0 + + '@octokit/plugin-retry@7.1.1(@octokit/core@6.1.2)': + dependencies: + '@octokit/core': 6.1.2 + '@octokit/request-error': 6.1.1 + '@octokit/types': 13.5.0 + bottleneck: 2.19.5 + + '@octokit/plugin-throttling@9.3.0(@octokit/core@6.1.2)': + dependencies: + '@octokit/core': 6.1.2 + '@octokit/types': 13.5.0 + bottleneck: 2.19.5 + '@octokit/request-error@5.1.0': dependencies: '@octokit/types': 13.5.0 deprecation: 2.3.1 once: 1.4.0 + '@octokit/request-error@6.1.1': + dependencies: + '@octokit/types': 13.5.0 + '@octokit/request@8.4.0': dependencies: '@octokit/endpoint': 9.0.5 @@ -5948,6 +6215,13 @@ snapshots: '@octokit/types': 13.5.0 universal-user-agent: 6.0.1 + '@octokit/request@9.1.1': + dependencies: + '@octokit/endpoint': 10.1.1 + '@octokit/request-error': 6.1.1 + '@octokit/types': 13.5.0 + universal-user-agent: 7.0.2 + '@octokit/types@12.6.0': dependencies: '@octokit/openapi-types': 20.0.0 @@ -5956,6 +6230,15 @@ snapshots: dependencies: '@octokit/openapi-types': 22.2.0 + '@octokit/webhooks-methods@5.1.0': {} + + '@octokit/webhooks@13.2.7': + dependencies: + '@octokit/openapi-webhooks-types': 8.2.1 + '@octokit/request-error': 6.1.1 + '@octokit/webhooks-methods': 5.1.0 + aggregate-error: 5.0.0 + '@pkgjs/parseargs@0.11.0': optional: true @@ -6154,6 +6437,8 @@ snapshots: dependencies: '@types/node': 20.12.10 + '@types/aws-lambda@8.10.138': {} + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.24.5 @@ -6385,6 +6670,11 @@ snapshots: transitivePeerDependencies: - supports-color + aggregate-error@5.0.0: + dependencies: + clean-stack: 5.2.0 + indent-string: 5.0.0 + ahooks@3.8.0(react@19.0.0-rc-9d4fba0788-20240530): dependencies: '@babel/runtime': 7.24.6 @@ -6578,6 +6868,8 @@ snapshots: before-after-hook@2.2.3: {} + before-after-hook@3.0.2: {} + big-integer@1.6.52: {} binary-extensions@2.3.0: {} @@ -6585,6 +6877,8 @@ snapshots: boolean@3.2.0: optional: true + bottleneck@2.19.5: {} + boxen@1.3.0: dependencies: ansi-align: 2.0.0 @@ -6703,6 +6997,10 @@ snapshots: classnames@2.5.1: {} + clean-stack@5.2.0: + dependencies: + escape-string-regexp: 5.0.0 + cli-boxes@1.0.0: {} cli-cursor@4.0.0: @@ -7233,6 +7531,8 @@ snapshots: escape-string-regexp@4.0.0: {} + escape-string-regexp@5.0.0: {} + eslint-compat-utils@0.5.0(eslint@8.57.0): dependencies: eslint: 8.57.0 @@ -7901,6 +8201,8 @@ snapshots: imurmurhash@0.1.4: {} + indent-string@5.0.0: {} + inflight@1.0.6: dependencies: once: 1.4.0 @@ -8726,6 +9028,19 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.0.0 + octokit@4.0.2: + dependencies: + '@octokit/app': 15.1.0 + '@octokit/core': 6.1.2 + '@octokit/oauth-app': 7.1.2 + '@octokit/plugin-paginate-graphql': 5.2.2(@octokit/core@6.1.2) + '@octokit/plugin-paginate-rest': 11.3.0(@octokit/core@6.1.2) + '@octokit/plugin-rest-endpoint-methods': 13.2.1(@octokit/core@6.1.2) + '@octokit/plugin-retry': 7.1.1(@octokit/core@6.1.2) + '@octokit/plugin-throttling': 9.3.0(@octokit/core@6.1.2) + '@octokit/request-error': 6.1.1 + '@octokit/types': 13.5.0 + ofetch@1.3.4: dependencies: destr: 2.0.3 @@ -9739,7 +10054,7 @@ snapshots: tslib@2.6.2: {} - tsx@4.15.4: + tsx@4.15.5: dependencies: esbuild: 0.21.4 get-tsconfig: 4.7.5 @@ -9887,8 +10202,12 @@ snapshots: unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 + universal-github-app-jwt@2.2.0: {} + universal-user-agent@6.0.1: {} + universal-user-agent@7.0.2: {} + universalify@0.1.2: {} universalify@2.0.1: {} diff --git a/clash-nyanpasu/scripts/check.ts b/clash-nyanpasu/scripts/check.ts index 3c111e4039..7047c8093f 100644 --- a/clash-nyanpasu/scripts/check.ts +++ b/clash-nyanpasu/scripts/check.ts @@ -4,6 +4,7 @@ import { colorize, consola } from "./utils/logger"; import { archCheck } from "./utils/arch-check"; import { Resolve } from "./utils/resolve"; import { printNyanpasu } from "./utils"; +import { generateLatestVersion } from "generate-latest-version"; // force download const FORCE = process.argv.includes("--force"); diff --git a/clash-nyanpasu/scripts/generate-latest-version.ts b/clash-nyanpasu/scripts/generate-latest-version.ts index b50c8d0cd8..f4b46ae40d 100644 --- a/clash-nyanpasu/scripts/generate-latest-version.ts +++ b/clash-nyanpasu/scripts/generate-latest-version.ts @@ -1,179 +1,38 @@ -import { getOctokit } from "@actions/github"; import fs from "fs-extra"; -import path from "node:path"; -import { MANIFEST_DIR } from "./utils/env"; +import { MANIFEST_DIR, MANIFEST_VERSION_PATH } from "./utils/env"; import { consola } from "./utils/logger"; - -const GITHUB_TOKEN = process.env.GITHUB_TOKEN || ""; - -const MANIFEST_VERSION_PATH = path.join(MANIFEST_DIR, "version.json"); - -export enum SupportedArch { - // blocked by clash-rs - // WindowsX86 = "windows-x86", - WindowsX86_64 = "windows-x86_64", - // blocked by clash-rs#212 - // WindowsArm64 = "windows-arm64", - LinuxAarch64 = "linux-aarch64", - LinuxAmd64 = "linux-amd64", - DarwinArm64 = "darwin-arm64", - DarwinX64 = "darwin-x64", -} - -export enum SupportedCore { - Mihomo = "mihomo", - MihomoAlpha = "mihomo_alpha", - ClashRs = "clash_rs", - ClashPremium = "clash_premium", -} - -export type ArchMapping = { [key in SupportedArch]: string }; - -export interface ManifestVersion { - manifest_version: number; - latest: { [K in SupportedCore]: string }; - arch_template: { [K in SupportedCore]: ArchMapping }; - updated_at: string; // ISO 8601 -} +import { ManifestVersion, SupportedCore } from "./types/index"; +import { + resolveMihomo, + resolveMihomoAlpha, + resolveClashRs, + resolveClashPremium, +} from "./utils/manifest"; const MANIFEST_VERSION = 1; -let previousManifest: ManifestVersion | null = null; -const getPreviousManifest = async (): Promise => { - const isExist = await fs.pathExists(MANIFEST_VERSION_PATH); - if (!isExist) { - previousManifest = null; - return; - } - previousManifest = (await fs.readJSON( - MANIFEST_VERSION_PATH, - )) as ManifestVersion; -}; - -// resolvers block -type LatestVersionResolver = () => Promise<{ - name: string; - version: string; - archMapping: ArchMapping; -}>; - -const resolveMihomo: LatestVersionResolver = async () => { - const octokit = getOctokit(GITHUB_TOKEN); - const latestRelease = await octokit.rest.repos.getLatestRelease({ - owner: "MetaCubeX", - repo: "mihomo", - }); - consola.debug(`mihomo latest release: ${latestRelease.data.tag_name}`); - - const archMapping: ArchMapping = { - // [SupportedArch.WindowsX86]: "mihomo-windows-386-{}.zip", - [SupportedArch.WindowsX86_64]: "mihomo-windows-amd64-compatible-{}.zip", - // [SupportedArch.WindowsAarch64]: "mihomo-windows-arm64-{}.zip", - [SupportedArch.LinuxAarch64]: "mihomo-linux-arm64-{}.gz", - [SupportedArch.LinuxAmd64]: "mihomo-linux-amd64-compatible-{}.gz", - [SupportedArch.DarwinArm64]: "mihomo-darwin-arm64-{}.gz", - [SupportedArch.DarwinX64]: "mihomo-darwin-amd64-compatible-{}.gz", - } satisfies ArchMapping; - return { - name: "mihomo", - version: latestRelease.data.tag_name, - archMapping, - }; -}; - -const resolveMihomoAlpha: LatestVersionResolver = async () => { - const resp = await fetch( - "https://github.com/MetaCubeX/mihomo/releases/download/Prerelease-Alpha/version.txt", - ); - const alphaReleaseHash = (await resp.text()).trim(); - consola.debug(`mihomo alpha release: ${alphaReleaseHash}`); - - const archMapping: ArchMapping = { - // [SupportedArch.WindowsX86]: "mihomo-windows-386-{}.zip", - [SupportedArch.WindowsX86_64]: "mihomo-windows-amd64-compatible-{}.zip", - // [SupportedArch.WindowsAarch64]: "mihomo-windows-arm64-{}.zip", - [SupportedArch.LinuxAarch64]: "mihomo-linux-arm64-{}.gz", - [SupportedArch.LinuxAmd64]: "mihomo-linux-amd64-compatible-{}.gz", - [SupportedArch.DarwinArm64]: "mihomo-darwin-arm64-{}.gz", - [SupportedArch.DarwinX64]: "mihomo-darwin-amd64-compatible-{}.gz", - } satisfies ArchMapping; - return { - name: "mihomo_alpha", - version: alphaReleaseHash, - archMapping, - }; -}; - -const resolveClashRs: LatestVersionResolver = async () => { - const octokit = getOctokit(GITHUB_TOKEN); - const latestRelease = await octokit.rest.repos.getLatestRelease({ - owner: "Watfaq", - repo: "clash-rs", - }); - consola.debug(`clash-rs latest release: ${latestRelease.data.tag_name}`); - - const archMapping: ArchMapping = { - // [SupportedArch.WindowsX86]: "mihomo-windows-386-alpha-{}.zip", - [SupportedArch.WindowsX86_64]: "clash-x86_64-pc-windows-msvc.exe", - // [SupportedArch.WindowsAarch64]: "mihomo-windows-arm64-alpha-{}.zip", - [SupportedArch.LinuxAarch64]: "clash-aarch64-unknown-linux-gnu-static-crt", - [SupportedArch.LinuxAmd64]: "clash-x86_64-unknown-linux-gnu-static-crt", - [SupportedArch.DarwinArm64]: "clash-aarch64-apple-darwin", - [SupportedArch.DarwinX64]: "clash-x86_64-apple-darwin", - } satisfies ArchMapping; - return { - name: "clash_rs", - version: latestRelease.data.tag_name, - archMapping, - }; -}; - -const resolveClashPremium: LatestVersionResolver = async () => { - const octokit = getOctokit(GITHUB_TOKEN); - const latestRelease = await octokit.rest.repos.getLatestRelease({ - owner: "zhongfly", - repo: "Clash-premium-backup", - }); - consola.debug(`clash-premium latest release: ${latestRelease.data.tag_name}`); - - const archMapping: ArchMapping = { - // [SupportedArch.WindowsX86]: "clash-windows-386-n{}.zip", - [SupportedArch.WindowsX86_64]: "clash-windows-amd64-n{}.zip", - // [SupportedArch.WindowsAarch64]: "clash-windows-arm64-n{}.zip", - [SupportedArch.LinuxAarch64]: "clash-linux-arm64-n{}.gz", - [SupportedArch.LinuxAmd64]: "clash-linux-amd64-n{}.gz", - [SupportedArch.DarwinArm64]: "clash-darwin-arm64-n{}.gz", - [SupportedArch.DarwinX64]: "clash-darwin-amd64-n{}.gz", - } satisfies ArchMapping; - return { - name: "clash_premium", - version: latestRelease.data.tag_name, - archMapping, - }; -}; - -async function main() { - if (!GITHUB_TOKEN) { - consola.fatal("GITHUB_TOKEN is not set"); - process.exit(1); - } - +export async function generateLatestVersion() { const resolvers = [ resolveMihomo, resolveMihomoAlpha, resolveClashRs, resolveClashPremium, ]; + consola.start("Resolving latest versions"); + const results = await Promise.all(resolvers.map((r) => r())); + consola.success("Resolved latest versions"); consola.start("Generating manifest"); + const manifest: ManifestVersion = { manifest_version: MANIFEST_VERSION, latest: {}, arch_template: {}, } as ManifestVersion; + for (const result of results) { manifest.latest[result.name as SupportedCore] = result.version; manifest.arch_template[result.name as SupportedCore] = result.archMapping; @@ -182,16 +41,21 @@ async function main() { await fs.ensureDir(MANIFEST_DIR); // If no changes, skip writing manifest const previousManifest = (await fs.readJSON(MANIFEST_VERSION_PATH)) || {}; + delete previousManifest.updated_at; + if (JSON.stringify(previousManifest) === JSON.stringify(manifest)) { consola.success("No changes, skip writing manifest"); return; } + manifest.updated_at = new Date().toISOString(); + consola.success("Generated manifest"); await fs.writeJSON(MANIFEST_VERSION_PATH, manifest, { spaces: 2 }); + consola.success("Manifest written"); } -main(); +generateLatestVersion(); diff --git a/clash-nyanpasu/scripts/package.json b/clash-nyanpasu/scripts/package.json index cdf222218b..410ad97a10 100644 --- a/clash-nyanpasu/scripts/package.json +++ b/clash-nyanpasu/scripts/package.json @@ -1,5 +1,6 @@ { "name": "@nyanpasu/scripts", + "type": "module", "version": "0.1.0", "dependencies": { "@actions/github": "6.0.0", @@ -7,6 +8,7 @@ "figlet": "1.7.0" }, "devDependencies": { + "@octokit/types": "13.5.0", "@types/adm-zip": "0.5.5", "adm-zip": "0.5.14", "colorize-template": "1.0.0", @@ -14,6 +16,7 @@ "fs-extra": "11.2.0", "https-proxy-agent": "7.0.4", "node-fetch": "3.3.2", + "octokit": "4.0.2", "picocolors": "1.0.1", "telegram": "2.22.2" } diff --git a/clash-nyanpasu/scripts/tsconfig.json b/clash-nyanpasu/scripts/tsconfig.json index 8162dc1f67..ca1c1ec94f 100644 --- a/clash-nyanpasu/scripts/tsconfig.json +++ b/clash-nyanpasu/scripts/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "baseUrl": ".", + "baseUrl": "./", "target": "ESNext", "useDefineForClassFields": true, "lib": ["ESNext"], diff --git a/clash-nyanpasu/scripts/types/index.d.ts b/clash-nyanpasu/scripts/types/index.d.ts deleted file mode 100644 index 44a95a9894..0000000000 --- a/clash-nyanpasu/scripts/types/index.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -export interface ClashManifest { - URL_PREFIX: string; - LATEST_DATE?: string; - STORAGE_PREFIX?: string; - BACKUP_URL_PREFIX?: string; - BACKUP_LATEST_DATE?: string; - VERSION?: string; - VERSION_URL?: string; - BIN_MAP: { [key: string]: string }; -} - -export interface BinInfo { - name: string; - targetFile: string; - exeFile: string; - tmpFile: string; - downloadURL: string; -} diff --git a/clash-nyanpasu/scripts/types/index.ts b/clash-nyanpasu/scripts/types/index.ts new file mode 100644 index 0000000000..b300a4d463 --- /dev/null +++ b/clash-nyanpasu/scripts/types/index.ts @@ -0,0 +1,44 @@ +export interface ClashManifest { + URL_PREFIX: string; + LATEST_DATE?: string; + STORAGE_PREFIX?: string; + BACKUP_URL_PREFIX?: string; + BACKUP_LATEST_DATE?: string; + VERSION?: string; + VERSION_URL?: string; + BIN_MAP: { [key: string]: string }; +} + +export interface BinInfo { + name: string; + targetFile: string; + exeFile: string; + tmpFile: string; + downloadURL: string; +} + +export enum SupportedArch { + // blocked by clash-rs + // WindowsX86 = "windows-x86", + WindowsX86_64 = "windows-x86_64", + // blocked by clash-rs#212 + // WindowsArm64 = "windows-arm64", + LinuxAarch64 = "linux-aarch64", + LinuxAmd64 = "linux-amd64", + DarwinArm64 = "darwin-arm64", + DarwinX64 = "darwin-x64", +} + +export enum SupportedCore { + Mihomo = "mihomo", + MihomoAlpha = "mihomo_alpha", + ClashRs = "clash_rs", + ClashPremium = "clash_premium", +} + +export interface ManifestVersion { + manifest_version: number; + latest: { [K in SupportedCore]: string }; + arch_template: { [K in SupportedCore]: ArchMapping }; + updated_at: string; // ISO 8601 +} diff --git a/clash-nyanpasu/scripts/utils/env.ts b/clash-nyanpasu/scripts/utils/env.ts index 219fe2c1d2..27f6161b95 100644 --- a/clash-nyanpasu/scripts/utils/env.ts +++ b/clash-nyanpasu/scripts/utils/env.ts @@ -6,3 +6,4 @@ export const MANIFEST_DIR = path.join(cwd, "manifest"); export const GITHUB_PROXY = "https://mirror.ghproxy.com/"; export const GITHUB_TOKEN = process.env.GITHUB_TOKEN; export const TEMP_DIR = path.join(cwd, "node_modules/.verge"); +export const MANIFEST_VERSION_PATH = path.join(MANIFEST_DIR, "version.json"); diff --git a/clash-nyanpasu/scripts/utils/manifest.ts b/clash-nyanpasu/scripts/utils/manifest.ts new file mode 100644 index 0000000000..85d501c4c7 --- /dev/null +++ b/clash-nyanpasu/scripts/utils/manifest.ts @@ -0,0 +1,113 @@ +import consola from "consola"; +import { SupportedArch } from "../types/index"; +import { octokit } from "./octokit"; + +export type ArchMapping = { [key in SupportedArch]: string }; + +// resolvers block +export type LatestVersionResolver = Promise<{ + name: string; + version: string; + archMapping: ArchMapping; +}>; + +export const resolveMihomo = async (): LatestVersionResolver => { + const latestRelease = await octokit.rest.repos.getLatestRelease({ + owner: "MetaCubeX", + repo: "mihomo", + }); + + consola.debug(`mihomo latest release: ${latestRelease.data.tag_name}`); + + const archMapping: ArchMapping = { + // [SupportedArch.WindowsX86]: "mihomo-windows-386-{}.zip", + [SupportedArch.WindowsX86_64]: "mihomo-windows-amd64-compatible-{}.zip", + // [SupportedArch.WindowsAarch64]: "mihomo-windows-arm64-{}.zip", + [SupportedArch.LinuxAarch64]: "mihomo-linux-arm64-{}.gz", + [SupportedArch.LinuxAmd64]: "mihomo-linux-amd64-compatible-{}.gz", + [SupportedArch.DarwinArm64]: "mihomo-darwin-arm64-{}.gz", + [SupportedArch.DarwinX64]: "mihomo-darwin-amd64-compatible-{}.gz", + } satisfies ArchMapping; + + return { + name: "mihomo", + version: latestRelease.data.tag_name, + archMapping, + }; +}; + +export const resolveMihomoAlpha = async (): LatestVersionResolver => { + const resp = await fetch( + "https://github.com/MetaCubeX/mihomo/releases/download/Prerelease-Alpha/version.txt", + ); + + const alphaReleaseHash = (await resp.text()).trim(); + + consola.debug(`mihomo alpha release: ${alphaReleaseHash}`); + + const archMapping: ArchMapping = { + // [SupportedArch.WindowsX86]: "mihomo-windows-386-{}.zip", + [SupportedArch.WindowsX86_64]: "mihomo-windows-amd64-compatible-{}.zip", + // [SupportedArch.WindowsAarch64]: "mihomo-windows-arm64-{}.zip", + [SupportedArch.LinuxAarch64]: "mihomo-linux-arm64-{}.gz", + [SupportedArch.LinuxAmd64]: "mihomo-linux-amd64-compatible-{}.gz", + [SupportedArch.DarwinArm64]: "mihomo-darwin-arm64-{}.gz", + [SupportedArch.DarwinX64]: "mihomo-darwin-amd64-compatible-{}.gz", + } satisfies ArchMapping; + + return { + name: "mihomo_alpha", + version: alphaReleaseHash, + archMapping, + }; +}; + +export const resolveClashRs = async (): LatestVersionResolver => { + const latestRelease = await octokit.rest.repos.getLatestRelease({ + owner: "Watfaq", + repo: "clash-rs", + }); + + consola.debug(`clash-rs latest release: ${latestRelease.data.tag_name}`); + + const archMapping: ArchMapping = { + // [SupportedArch.WindowsX86]: "mihomo-windows-386-alpha-{}.zip", + [SupportedArch.WindowsX86_64]: "clash-x86_64-pc-windows-msvc.exe", + // [SupportedArch.WindowsAarch64]: "mihomo-windows-arm64-alpha-{}.zip", + [SupportedArch.LinuxAarch64]: "clash-aarch64-unknown-linux-gnu-static-crt", + [SupportedArch.LinuxAmd64]: "clash-x86_64-unknown-linux-gnu-static-crt", + [SupportedArch.DarwinArm64]: "clash-aarch64-apple-darwin", + [SupportedArch.DarwinX64]: "clash-x86_64-apple-darwin", + } satisfies ArchMapping; + + return { + name: "clash_rs", + version: latestRelease.data.tag_name, + archMapping, + }; +}; + +export const resolveClashPremium = async (): LatestVersionResolver => { + const latestRelease = await octokit.rest.repos.getLatestRelease({ + owner: "zhongfly", + repo: "Clash-premium-backup", + }); + + consola.debug(`clash-premium latest release: ${latestRelease.data.tag_name}`); + + const archMapping: ArchMapping = { + // [SupportedArch.WindowsX86]: "clash-windows-386-n{}.zip", + [SupportedArch.WindowsX86_64]: "clash-windows-amd64-n{}.zip", + // [SupportedArch.WindowsAarch64]: "clash-windows-arm64-n{}.zip", + [SupportedArch.LinuxAarch64]: "clash-linux-arm64-n{}.gz", + [SupportedArch.LinuxAmd64]: "clash-linux-amd64-n{}.gz", + [SupportedArch.DarwinArm64]: "clash-darwin-arm64-n{}.gz", + [SupportedArch.DarwinX64]: "clash-darwin-amd64-n{}.gz", + } satisfies ArchMapping; + + return { + name: "clash_premium", + version: latestRelease.data.tag_name, + archMapping, + }; +}; diff --git a/clash-nyanpasu/scripts/utils/octokit.ts b/clash-nyanpasu/scripts/utils/octokit.ts new file mode 100644 index 0000000000..4f3a1159ca --- /dev/null +++ b/clash-nyanpasu/scripts/utils/octokit.ts @@ -0,0 +1,8 @@ +import { Octokit } from "octokit"; + +const BASE_OPTIONS = { + owner: "LibNyanpasu", + repo: "clash-nyanpasu", +}; + +export const octokit = new Octokit(BASE_OPTIONS); diff --git a/clash-verge-rev/.github/workflows/alpha.yml b/clash-verge-rev/.github/workflows/alpha.yml index 7b2cbe46ad..6579df0aa4 100644 --- a/clash-verge-rev/.github/workflows/alpha.yml +++ b/clash-verge-rev/.github/workflows/alpha.yml @@ -9,6 +9,10 @@ permissions: write-all env: CARGO_INCREMENTAL: 0 RUST_BACKTRACE: short +concurrency: + # only allow per workflow per commit (and not pr) to run at a time + group: "${{ github.workflow }} - ${{ github.head_ref || github.ref }}" + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} jobs: alpha: diff --git a/clash-verge-rev/src/components/profile/editor-viewer.tsx b/clash-verge-rev/src/components/profile/editor-viewer.tsx index d97e6ef796..1bfbb80629 100644 --- a/clash-verge-rev/src/components/profile/editor-viewer.tsx +++ b/clash-verge-rev/src/components/profile/editor-viewer.tsx @@ -171,12 +171,14 @@ export const EditorViewer = (props: Props) => { - - + {readOnly ? null : ( + + )} ); diff --git a/clash-verge-rev/src/pages/logs.tsx b/clash-verge-rev/src/pages/logs.tsx index f4166c059b..b9df1aba4f 100644 --- a/clash-verge-rev/src/pages/logs.tsx +++ b/clash-verge-rev/src/pages/logs.tsx @@ -24,11 +24,11 @@ const LogPage = () => { const [match, setMatch] = useState(() => (_: string) => true); const filterLogs = useMemo(() => { - return logData - .filter((data) => - logState === "all" ? true : data.type.includes(logState) - ) - .filter((data) => match(data.payload)); + return logData.filter( + (data) => + (logState === "all" ? true : data.type.includes(logState)) && + match(data.payload) + ); }, [logData, logState, match]); return ( diff --git a/clash-verge-rev/src/services/api.ts b/clash-verge-rev/src/services/api.ts index bded6e32e1..a82edda145 100644 --- a/clash-verge-rev/src/services/api.ts +++ b/clash-verge-rev/src/services/api.ts @@ -134,25 +134,37 @@ export const getProxies = async () => { const { GLOBAL: global, DIRECT: direct, REJECT: reject } = proxyRecord; - let groups = Object.values(proxyRecord) - .filter((each) => each.name !== "GLOBAL" && each.all) - .map((each) => ({ - ...each, - all: each.all!.map((item) => generateItem(item)), - })); - - if (global?.all) { - let globalGroups = global.all - .filter((name) => proxyRecord[name]?.all) - .map((name) => proxyRecord[name]) - .map((each) => ({ + let groups: IProxyGroupItem[] = Object.values(proxyRecord).reduce< + IProxyGroupItem[] + >((acc, each) => { + if (each.name !== "GLOBAL" && each.all) { + acc.push({ ...each, all: each.all!.map((item) => generateItem(item)), - })); - let globalNames = globalGroups.map((each) => each.name); + }); + } + + return acc; + }, []); + + if (global?.all) { + let globalGroups: IProxyGroupItem[] = global.all.reduce( + (acc, name) => { + if (proxyRecord[name]?.all) { + acc.push({ + ...proxyRecord[name], + all: proxyRecord[name].all!.map((item) => generateItem(item)), + }); + } + return acc; + }, + [] + ); + + let globalNames = new Set(globalGroups.map((each) => each.name)); groups = groups .filter((group) => { - return !globalNames.includes(group.name); + return !globalNames.has(group.name); }) .concat(globalGroups); } diff --git a/clash-verge-rev/src/services/cmds.ts b/clash-verge-rev/src/services/cmds.ts index 377f374616..f15c95c243 100644 --- a/clash-verge-rev/src/services/cmds.ts +++ b/clash-verge-rev/src/services/cmds.ts @@ -7,23 +7,22 @@ export async function getClashLogs() { const newRegex = /(.+?)\s+(.+?)\s+(.+)/; const logs = await invoke("get_clash_logs"); - return logs - .map((log) => { - const result = log.match(regex); - if (result) { - const [_, _time, type, payload] = result; - const time = dayjs(_time).format("MM-DD HH:mm:ss"); - return { time, type, payload }; - } + return logs.reduce((acc, log) => { + const result = log.match(regex); + if (result) { + const [_, _time, type, payload] = result; + const time = dayjs(_time).format("MM-DD HH:mm:ss"); + acc.push({ time, type, payload }); + return acc; + } - const result2 = log.match(newRegex); - if (result2) { - const [_, time, type, payload] = result2; - return { time, type, payload }; - } - return null; - }) - .filter(Boolean) as ILogItem[]; + const result2 = log.match(newRegex); + if (result2) { + const [_, time, type, payload] = result2; + acc.push({ time, type, payload }); + } + return acc; + }, []); } export async function getProfiles() { diff --git a/echo/examples/web.json b/echo/examples/web.json index a0f402e8b7..2a52dfb47b 100644 --- a/echo/examples/web.json +++ b/echo/examples/web.json @@ -9,7 +9,7 @@ "listen": "127.0.0.1:1234", "listen_type": "raw", "transport_type": "raw", - "label": "relay1", + "label": "iperf3", "tcp_remotes": ["0.0.0.0:5201"] } ] diff --git a/echo/internal/cli/config.go b/echo/internal/cli/config.go index 231e4fec46..f23fba816c 100644 --- a/echo/internal/cli/config.go +++ b/echo/internal/cli/config.go @@ -116,7 +116,7 @@ func MustStartComponents(mainCtx context.Context, cfg *config.Config) { }() if cfg.NeedStartWebServer() { - webS, err := web.NewServer(cfg, rs, rs.Cmgr) + webS, err := web.NewServer(cfg, rs, rs, rs.Cmgr) if err != nil { cliLogger.Fatalf("NewWebServer meet err=%s", err.Error()) } diff --git a/echo/internal/glue/interface.go b/echo/internal/glue/interface.go new file mode 100644 index 0000000000..0b2a193f22 --- /dev/null +++ b/echo/internal/glue/interface.go @@ -0,0 +1,14 @@ +package glue + +import ( + "context" +) + +type Reloader interface { + Reload(force bool) error +} + +type HealthChecker interface { + // get relay by ID and check the connection health + HealthCheck(ctx context.Context, RelayID string) error +} diff --git a/echo/internal/relay/health_check.go b/echo/internal/relay/health_check.go new file mode 100644 index 0000000000..c410ed9467 --- /dev/null +++ b/echo/internal/relay/health_check.go @@ -0,0 +1,19 @@ +package relay + +import ( + "context" + "fmt" + + "github.com/Ehco1996/ehco/internal/glue" +) + +var _ glue.HealthChecker = (*Server)(nil) + +func (r *Server) HealthCheck(ctx context.Context, relayID string) error { + rs, ok := r.relayM.Load(relayID) + if !ok { + return fmt.Errorf("label for relay: %s not found,can not health check", relayID) + } + inner, _ := rs.(*Relay) + return inner.relayServer.HealthCheck(ctx) +} diff --git a/echo/internal/relay/server_reloader.go b/echo/internal/relay/server_reloader.go index f3f8841a03..7a88b86378 100644 --- a/echo/internal/relay/server_reloader.go +++ b/echo/internal/relay/server_reloader.go @@ -1,13 +1,13 @@ package relay import ( + "github.com/Ehco1996/ehco/internal/glue" "github.com/Ehco1996/ehco/internal/relay/conf" - "github.com/Ehco1996/ehco/internal/reloader" "go.uber.org/zap" ) // make sure Server implements the reloader.Reloader interface -var _ reloader.Reloader = (*Server)(nil) +var _ glue.Reloader = (*Server)(nil) func (s *Server) Reload(force bool) error { // k:name v: *Config diff --git a/echo/internal/reloader/reloader.go b/echo/internal/reloader/reloader.go deleted file mode 100644 index 4d81654620..0000000000 --- a/echo/internal/reloader/reloader.go +++ /dev/null @@ -1,5 +0,0 @@ -package reloader - -type Reloader interface { - Reload(force bool) error -} diff --git a/echo/internal/transporter/base.go b/echo/internal/transporter/base.go index 6f38630b81..5428333827 100644 --- a/echo/internal/transporter/base.go +++ b/echo/internal/transporter/base.go @@ -24,15 +24,21 @@ type baseTransporter struct { cmgr cmgr.Cmgr tCPRemotes lb.RoundRobin + relayer RelayClient } -func NewBaseTransporter(cfg *conf.Config, cmgr cmgr.Cmgr) *baseTransporter { +func NewBaseTransporter(cfg *conf.Config, cmgr cmgr.Cmgr) (*baseTransporter, error) { + relayer, err := newRelayClient(cfg) + if err != nil { + return nil, err + } return &baseTransporter{ cfg: cfg, cmgr: cmgr, tCPRemotes: cfg.ToTCPRemotes(), l: zap.S().Named(cfg.GetLoggerName()), - } + relayer: relayer, + }, nil } func (b *baseTransporter) GetTCPListenAddr() (*net.TCPAddr, error) { @@ -94,3 +100,7 @@ func (b *baseTransporter) RelayTCPConn(c net.Conn, handshakeF TCPHandShakeF) err defer b.cmgr.RemoveConnection(relayConn) return relayConn.Transport(remote.Label) } + +func (b *baseTransporter) HealthCheck(ctx context.Context) error { + return b.relayer.HealthCheck(ctx, b.GetRemote().Clone()) +} diff --git a/echo/internal/transporter/interface.go b/echo/internal/transporter/interface.go index f36c48e259..6292e535ae 100644 --- a/echo/internal/transporter/interface.go +++ b/echo/internal/transporter/interface.go @@ -1,6 +1,8 @@ package transporter import ( + "context" + "fmt" "net" "github.com/Ehco1996/ehco/internal/cmgr" @@ -12,39 +14,45 @@ import ( type TCPHandShakeF func(remote *lb.Node) (net.Conn, error) type RelayClient interface { + HealthCheck(ctx context.Context, remote *lb.Node) error TCPHandShake(remote *lb.Node) (net.Conn, error) - RelayTCPConn(c net.Conn, handshakeF TCPHandShakeF) error } -func newRelayClient(base *baseTransporter) (RelayClient, error) { - switch base.cfg.TransportType { +func newRelayClient(cfg *conf.Config) (RelayClient, error) { + switch cfg.TransportType { case constant.RelayTypeRaw: - return newRawClient(base) - case constant.RelayTypeWS: - return newWsClient(base) - case constant.RelayTypeMWS: - return newMwsClient(base) - case constant.RelayTypeWSS: - return newWssClient(base) - case constant.RelayTypeMWSS: - return newMwssClient(base) + return newRawClient(cfg) case constant.RelayTypeMTCP: - return newMtcpClient(base) + return newMtcpClient(cfg) + case constant.RelayTypeWS: + return newWsClient(cfg) + case constant.RelayTypeMWS: + return newMwsClient(cfg) + case constant.RelayTypeWSS: + return newWssClient(cfg) + case constant.RelayTypeMWSS: + return newMwssClient(cfg) default: - panic("unsupported transport type" + base.cfg.TransportType) + return nil, fmt.Errorf("unsupported transport type" + cfg.TransportType) } } type RelayServer interface { ListenAndServe() error Close() error + HealthCheck(ctx context.Context) error } func NewRelayServer(cfg *conf.Config, cmgr cmgr.Cmgr) (RelayServer, error) { - base := NewBaseTransporter(cfg, cmgr) + base, err := NewBaseTransporter(cfg, cmgr) + if err != nil { + return nil, err + } switch cfg.ListenType { case constant.RelayTypeRaw: return newRawServer(base) + case constant.RelayTypeMTCP: + return newMtcpServer(base) case constant.RelayTypeWS: return newWsServer(base) case constant.RelayTypeMWS: @@ -53,8 +61,6 @@ func NewRelayServer(cfg *conf.Config, cmgr cmgr.Cmgr) (RelayServer, error) { return newWssServer(base) case constant.RelayTypeMWSS: return newMwssServer(base) - case constant.RelayTypeMTCP: - return newMtcpServer(base) default: panic("unsupported transport type" + cfg.ListenType) } diff --git a/echo/internal/transporter/raw.go b/echo/internal/transporter/raw.go index 7f1b5940ad..1bfcfcf289 100644 --- a/echo/internal/transporter/raw.go +++ b/echo/internal/transporter/raw.go @@ -2,12 +2,15 @@ package transporter import ( + "context" "net" "time" "github.com/Ehco1996/ehco/internal/constant" "github.com/Ehco1996/ehco/internal/metrics" + "github.com/Ehco1996/ehco/internal/relay/conf" "github.com/Ehco1996/ehco/pkg/lb" + "go.uber.org/zap" ) var ( @@ -16,15 +19,16 @@ var ( ) type RawClient struct { - *baseTransporter - dialer *net.Dialer + cfg *conf.Config + l *zap.SugaredLogger } -func newRawClient(base *baseTransporter) (*RawClient, error) { +func newRawClient(cfg *conf.Config) (*RawClient, error) { r := &RawClient{ - baseTransporter: base, - dialer: &net.Dialer{Timeout: constant.DialTimeOut}, + l: zap.S().Named("raw"), + cfg: cfg, + dialer: &net.Dialer{Timeout: constant.DialTimeOut}, } return r, nil } @@ -41,11 +45,22 @@ func (raw *RawClient) TCPHandShake(remote *lb.Node) (net.Conn, error) { return rc, nil } +func (raw *RawClient) HealthCheck(ctx context.Context, remote *lb.Node) error { + l := zap.S().Named("health-check") + l.Infof("start send req to %s", remote.Address) + c, err := raw.TCPHandShake(remote) + if err != nil { + l.Errorf("send req to %s meet error:%s", remote.Address, err) + return err + } + c.Close() + return nil +} + type RawServer struct { *baseTransporter localTCPAddr *net.TCPAddr lis *net.TCPListener - relayer RelayClient } func newRawServer(base *baseTransporter) (*RawServer, error) { @@ -57,15 +72,10 @@ func newRawServer(base *baseTransporter) (*RawServer, error) { if err != nil { return nil, err } - relayer, err := newRelayClient(base) - if err != nil { - return nil, err - } return &RawServer{ lis: lis, baseTransporter: base, localTCPAddr: addr, - relayer: relayer, }, nil } diff --git a/echo/internal/transporter/raw_mux.go b/echo/internal/transporter/raw_mux.go index 7e52861cb8..b13d83806c 100644 --- a/echo/internal/transporter/raw_mux.go +++ b/echo/internal/transporter/raw_mux.go @@ -6,8 +6,10 @@ import ( "time" "github.com/xtaci/smux" + "go.uber.org/zap" "github.com/Ehco1996/ehco/internal/metrics" + "github.com/Ehco1996/ehco/internal/relay/conf" "github.com/Ehco1996/ehco/pkg/lb" ) @@ -21,13 +23,13 @@ type MtcpClient struct { muxTP *smuxTransporter } -func newMtcpClient(base *baseTransporter) (*MtcpClient, error) { - raw, err := newRawClient(base) +func newMtcpClient(cfg *conf.Config) (*MtcpClient, error) { + raw, err := newRawClient(cfg) if err != nil { return nil, err } c := &MtcpClient{RawClient: raw} - c.muxTP = NewSmuxTransporter(raw.l.Named("mtcp"), c.initNewSession) + c.muxTP = NewSmuxTransporter(zap.S().Named("mtcp"), c.initNewSession) return c, nil } diff --git a/echo/internal/transporter/ws.go b/echo/internal/transporter/ws.go index a41eb45a6c..6499a50222 100644 --- a/echo/internal/transporter/ws.go +++ b/echo/internal/transporter/ws.go @@ -13,6 +13,7 @@ import ( "github.com/Ehco1996/ehco/internal/conn" "github.com/Ehco1996/ehco/internal/constant" "github.com/Ehco1996/ehco/internal/metrics" + "github.com/Ehco1996/ehco/internal/relay/conf" "github.com/Ehco1996/ehco/internal/web" "github.com/Ehco1996/ehco/pkg/lb" ) @@ -23,15 +24,16 @@ var ( ) type WsClient struct { - *baseTransporter - dialer *ws.Dialer + cfg *conf.Config + l *zap.SugaredLogger } -func newWsClient(base *baseTransporter) (*WsClient, error) { +func newWsClient(cfg *conf.Config) (*WsClient, error) { s := &WsClient{ - baseTransporter: base, - dialer: &ws.Dialer{Timeout: constant.DialTimeOut}, + cfg: cfg, + l: zap.S().Named(cfg.TransportType), + dialer: &ws.Dialer{Timeout: constant.DialTimeOut}, } return s, nil } @@ -53,12 +55,23 @@ func (s *WsClient) TCPHandShake(remote *lb.Node) (net.Conn, error) { return c, nil } +func (s *WsClient) HealthCheck(ctx context.Context, remote *lb.Node) error { + l := zap.S().Named("health-check") + l.Infof("start send req to %s", remote.Address) + c, err := s.TCPHandShake(remote) + if err != nil { + l.Errorf("send req to %s meet error:%s", remote.Address, err) + return err + } + c.Close() + return nil +} + type WsServer struct { *baseTransporter e *echo.Echo httpServer *http.Server - relayer RelayClient } func newWsServer(base *baseTransporter) (*WsServer, error) { @@ -79,11 +92,6 @@ func newWsServer(base *baseTransporter) (*WsServer, error) { e.GET(base.cfg.GetWSHandShakePath(), echo.WrapHandler(http.HandlerFunc(s.HandleRequest))) s.e = e - relayer, err := newRelayClient(base) - if err != nil { - return nil, err - } - s.relayer = relayer return s, nil } diff --git a/echo/internal/transporter/ws_mux.go b/echo/internal/transporter/ws_mux.go index 46a204455e..d9b6cd46aa 100644 --- a/echo/internal/transporter/ws_mux.go +++ b/echo/internal/transporter/ws_mux.go @@ -14,6 +14,7 @@ import ( "github.com/xtaci/smux" "github.com/Ehco1996/ehco/internal/metrics" + "github.com/Ehco1996/ehco/internal/relay/conf" "github.com/Ehco1996/ehco/pkg/lb" ) @@ -29,8 +30,8 @@ type MwsClient struct { muxTP *smuxTransporter } -func newMwsClient(base *baseTransporter) (*MwsClient, error) { - wc, err := newWssClient(base) +func newMwsClient(cfg *conf.Config) (*MwsClient, error) { + wc, err := newWssClient(cfg) if err != nil { return nil, err } diff --git a/echo/internal/transporter/wss.go b/echo/internal/transporter/wss.go index 19c5eb9610..74391f078e 100644 --- a/echo/internal/transporter/wss.go +++ b/echo/internal/transporter/wss.go @@ -1,6 +1,7 @@ package transporter import ( + "github.com/Ehco1996/ehco/internal/relay/conf" mytls "github.com/Ehco1996/ehco/internal/tls" ) @@ -13,8 +14,8 @@ type WssClient struct { *WsClient } -func newWssClient(base *baseTransporter) (*WssClient, error) { - wc, err := newWsClient(base) +func newWssClient(cfg *conf.Config) (*WssClient, error) { + wc, err := newWsClient(cfg) if err != nil { return nil, err } diff --git a/echo/internal/transporter/wss_mux.go b/echo/internal/transporter/wss_mux.go index 95b10986d6..1b7f60506b 100644 --- a/echo/internal/transporter/wss_mux.go +++ b/echo/internal/transporter/wss_mux.go @@ -14,6 +14,7 @@ import ( "github.com/xtaci/smux" "github.com/Ehco1996/ehco/internal/metrics" + "github.com/Ehco1996/ehco/internal/relay/conf" "github.com/Ehco1996/ehco/pkg/lb" ) @@ -29,8 +30,8 @@ type MwssClient struct { muxTP *smuxTransporter } -func newMwssClient(base *baseTransporter) (*MwssClient, error) { - wc, err := newWssClient(base) +func newMwssClient(cfg *conf.Config) (*MwssClient, error) { + wc, err := newWssClient(cfg) if err != nil { return nil, err } diff --git a/echo/internal/web/handlers.go b/echo/internal/web/handlers.go index 0e432a7dbe..450206f309 100644 --- a/echo/internal/web/handlers.go +++ b/echo/internal/web/handlers.go @@ -12,7 +12,7 @@ import ( "go.uber.org/zap" ) -const defaultPageSize = 10 +const defaultPageSize = 20 func MakeIndexF() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { @@ -51,13 +51,15 @@ func (s *Server) HandleClashProxyProvider(c echo.Context) error { } func (s *Server) handleClashProxyProvider(c echo.Context, subName string, grouped bool) error { - if s.relayServerReloader != nil { - if err := s.relayServerReloader.Reload(true); err != nil { + if s.Reloader != nil { + if err := s.Reloader.Reload(true); err != nil { return echo.NewHTTPError(http.StatusBadRequest, err.Error()) } } else { - s.l.Debugf("relayServerReloader is nil this should not happen") + s.l.Debugf("Reloader is nil this should not happen") + return echo.NewHTTPError(http.StatusBadRequest, "should not happen error happen :)") } + clashSubList, err := s.cfg.GetClashSubList() if err != nil { return echo.NewHTTPError(http.StatusBadRequest, err.Error()) @@ -81,11 +83,10 @@ func (s *Server) handleClashProxyProvider(c echo.Context, subName string, groupe } func (s *Server) HandleReload(c echo.Context) error { - if s.relayServerReloader == nil { + if s.Reloader == nil { return echo.NewHTTPError(http.StatusBadRequest, "reload not support") } - - err := s.relayServerReloader.Reload(true) + err := s.Reloader.Reload(true) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, err.Error()) } @@ -97,6 +98,18 @@ func (s *Server) HandleReload(c echo.Context) error { return nil } +func (s *Server) HandleHealthCheck(c echo.Context) error { + relayLabel := c.QueryParam("relay_label") + if relayLabel == "" { + return echo.NewHTTPError(http.StatusBadRequest, "relay_label is required") + } + if err := s.HealthCheck(c.Request().Context(), relayLabel); err != nil { + res := CommonResp{Message: err.Error()} + return c.JSON(http.StatusBadRequest, res) + } + return c.JSON(http.StatusOK, CommonResp{Message: "connect success"}) +} + func (s *Server) CurrentConfig(c echo.Context) error { ret, err := json.Marshal(s.cfg) if err != nil { diff --git a/echo/internal/web/server.go b/echo/internal/web/server.go index 60391e1dc2..575bf90250 100644 --- a/echo/internal/web/server.go +++ b/echo/internal/web/server.go @@ -17,21 +17,23 @@ import ( "github.com/Ehco1996/ehco/internal/cmgr" "github.com/Ehco1996/ehco/internal/config" + "github.com/Ehco1996/ehco/internal/glue" "github.com/Ehco1996/ehco/internal/metrics" - "github.com/Ehco1996/ehco/internal/reloader" ) //go:embed templates/*.html var templatesFS embed.FS type Server struct { + glue.Reloader + glue.HealthChecker + e *echo.Echo addr string l *zap.SugaredLogger cfg *config.Config - relayServerReloader reloader.Reloader - connMgr cmgr.Cmgr + connMgr cmgr.Cmgr } type echoTemplate struct { @@ -42,7 +44,11 @@ func (t *echoTemplate) Render(w io.Writer, name string, data interface{}, c echo return t.templates.ExecuteTemplate(w, name, data) } -func NewServer(cfg *config.Config, relayReloader reloader.Reloader, connMgr cmgr.Cmgr) (*Server, error) { +func NewServer( + cfg *config.Config, + relayReloader glue.Reloader, + healthChecker glue.HealthChecker, + connMgr cmgr.Cmgr) (*Server, error) { l := zap.S().Named("web") templates := template.Must(template.ParseFS(templatesFS, "templates/*.html")) @@ -79,12 +85,14 @@ func NewServer(cfg *config.Config, relayReloader reloader.Reloader, connMgr cmgr return nil, err } s := &Server{ - e: e, - l: l, - cfg: cfg, - connMgr: connMgr, - relayServerReloader: relayReloader, - addr: net.JoinHostPort(cfg.WebHost, fmt.Sprintf("%d", cfg.WebPort)), + Reloader: relayReloader, + HealthChecker: healthChecker, + + e: e, + l: l, + cfg: cfg, + connMgr: connMgr, + addr: net.JoinHostPort(cfg.WebHost, fmt.Sprintf("%d", cfg.WebPort)), } // register handler @@ -99,7 +107,7 @@ func NewServer(cfg *config.Config, relayReloader reloader.Reloader, connMgr cmgr api := e.Group("/api/v1") api.GET("/config/", s.CurrentConfig) api.POST("/config/reload/", s.HandleReload) - + api.GET("/health_check/", s.HandleHealthCheck) return s, nil } diff --git a/echo/internal/web/templates/connection.html b/echo/internal/web/templates/connection.html index 47d6cb07c0..c32f8109ad 100644 --- a/echo/internal/web/templates/connection.html +++ b/echo/internal/web/templates/connection.html @@ -3,7 +3,9 @@ - + + + Connections @@ -57,9 +59,9 @@ {{if gt .CurrentPage 1}}
  • 1
  • {{end}} -
  • +
  • {{.CurrentPage}}
  • -
  • +
  • {{if lt .CurrentPage .TotalPage}}
  • {{.TotalPage}}
  • {{end}} diff --git a/echo/internal/web/templates/index.html b/echo/internal/web/templates/index.html index 1a3f31e992..ac294b7310 100644 --- a/echo/internal/web/templates/index.html +++ b/echo/internal/web/templates/index.html @@ -1,7 +1,9 @@ - + + + ehco is a network relay tool and a typo :) -
    @@ -38,7 +39,6 @@
    -
    @@ -82,7 +82,7 @@
    - {{if .SubConfigs}} + {{ if .SubConfigs }}

    @@ -92,7 +92,7 @@

      - {{range .SubConfigs}} + {{ range .SubConfigs }}
    - {{end}} + {{ end }}
    - {{end}} - + {{ end }}
    -
    @@ -137,7 +135,6 @@
    -