refactor: simplify auth and subscription links

This commit is contained in:
2026-07-28 10:32:21 +08:00
parent b7a7cd9c71
commit fc8c23beee
41 changed files with 739 additions and 1468 deletions
+28 -15
View File
@@ -35,14 +35,15 @@ type BuildOptions struct {
// BuildResult holds the output of a subscription build.
type BuildResult struct {
Body string
Metadata model.SubscriptionResponseMetadata
Nodes int
Body string
Metadata model.SubscriptionResponseMetadata
Nodes int
OriginalNodes int
}
// BuildSubscriptionResult runs the full subscription pipeline.
func BuildSubscriptionResult(ctx context.Context, opts BuildOptions) (*BuildResult, error) {
proxies, metadata, err := loadProxyNodes(ctx, opts)
proxies, originalNodes, metadata, err := loadProxyNodes(ctx, opts)
if err != nil {
return nil, err
}
@@ -56,13 +57,14 @@ func BuildSubscriptionResult(ctx context.Context, opts BuildOptions) (*BuildResu
}
return &BuildResult{
Body: body,
Metadata: metadata,
Nodes: len(proxies),
Body: body,
Metadata: metadata,
Nodes: len(proxies),
OriginalNodes: originalNodes,
}, nil
}
func loadProxyNodes(ctx context.Context, opts BuildOptions) ([]model.ProxyNode, model.SubscriptionResponseMetadata, error) {
func loadProxyNodes(ctx context.Context, opts BuildOptions) ([]model.ProxyNode, int, model.SubscriptionResponseMetadata, error) {
sources := getSources(opts)
enabledSources := make([]model.SourceRecord, 0, len(sources))
for _, s := range sources {
@@ -71,20 +73,21 @@ func loadProxyNodes(ctx context.Context, opts BuildOptions) ([]model.ProxyNode,
}
}
if len(enabledSources) == 0 {
return nil, model.SubscriptionResponseMetadata{}, nil
return nil, 0, model.SubscriptionResponseMetadata{}, nil
}
metadataMap := make(map[string]model.SubscriptionResponseMetadata)
metadataByIndex := make([]model.SubscriptionResponseMetadata, len(enabledSources))
originalCounts := make([]int, len(enabledSources))
tasks := make([]func() ([]model.ProxyNode, error), len(enabledSources))
for i, sub := range enabledSources {
i := i
sub := sub
tasks[i] = func() ([]model.ProxyNode, error) {
raw, meta := loadSubscriptionRaw(ctx, sub, opts)
if sub.ID != "" {
metadataMap[sub.ID] = meta
}
metadataByIndex[i] = meta
nodes := proxy.ParseProxies(raw)
originalCounts[i] = len(nodes)
filters := sub.Filters
if filters == nil {
filters = []model.FilterRule{}
@@ -113,13 +116,17 @@ func loadProxyNodes(ctx context.Context, opts BuildOptions) ([]model.ProxyNode,
proxyLists = results
}
if taskErr != nil {
return nil, model.SubscriptionResponseMetadata{}, taskErr
return nil, 0, model.SubscriptionResponseMetadata{}, taskErr
}
var allProxies []model.ProxyNode
originalNodes := 0
for _, list := range proxyLists {
allProxies = append(allProxies, list...)
}
for _, count := range originalCounts {
originalNodes += count
}
// Apply collection-level filters
if opts.Collection != nil {
@@ -137,8 +144,14 @@ func loadProxyNodes(ctx context.Context, opts BuildOptions) ([]model.ProxyNode,
allProxies = proxy.EnsureUniqueProxyNames(allProxies)
// Select response metadata
metadataMap := make(map[string]model.SubscriptionResponseMetadata, len(enabledSources))
for i, s := range enabledSources {
if s.ID != "" {
metadataMap[s.ID] = metadataByIndex[i]
}
}
metadata := selectResponseMetadata(enabledSources, metadataMap)
return allProxies, metadata, nil
return allProxies, originalNodes, metadata, nil
}
func getSources(opts BuildOptions) []model.SourceRecord {
+11 -8
View File
@@ -90,13 +90,13 @@ func TestBuildSubscriptionResult_Collection(t *testing.T) {
Filters: []model.FilterRule{}, Meta: map[string]any{},
}
collection := &model.CollectionRecord{
ID: "col1",
Name: "Collection",
SourceIds: []string{"src1", "src2"},
Filters: []model.FilterRule{},
ID: "col1",
Name: "Collection",
SourceIds: []string{"src1", "src2"},
Filters: []model.FilterRule{},
TemplateId: "acl4ssr-mihomo",
Enabled: true,
Meta: map[string]any{},
Enabled: true,
Meta: map[string]any{},
}
result, err := BuildSubscriptionResult(context.Background(), BuildOptions{
Collection: collection,
@@ -169,6 +169,9 @@ func TestBuildSubscriptionResult_WithFilters(t *testing.T) {
if result.Nodes != 1 {
t.Errorf("expected 1 node after filter, got %d", result.Nodes)
}
if result.OriginalNodes != 2 {
t.Errorf("expected 2 original nodes, got %d", result.OriginalNodes)
}
}
func TestBuildSubscriptionResult_MihomoTarget(t *testing.T) {
@@ -421,8 +424,8 @@ func TestSplitSourceUrls_Empty(t *testing.T) {
func TestMetadataFromSource(t *testing.T) {
meta := metadataFromSource(model.SourceRecord{
Meta: map[string]any{
"subUserinfo": "upload=1;download=2;total=3",
"profileWebPageUrl": "https://example.com",
"subUserinfo": "upload=1;download=2;total=3",
"profileWebPageUrl": "https://example.com",
"profileUpdateInterval": "24",
},
})