๐Ÿ“ฆ Kong / insomnia

๐Ÿ“„ registry.ts ยท 100 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100import type { GitProviderOption, GitRemoteProvider, GitRemoteProviderType, ValidationResult } from './types';

// Re-export types from git-credentials model for convenience
export type {
  GitCredentials as GitCredentialData,
  GitRemoteProviderType,
  ProviderEmail,
} from '~/models/git-credentials';

export class GitRemoteProviderRegistry {
  private providers = new Map<GitRemoteProviderType, GitRemoteProvider>();

  /**
   * Register a provider
   */
  register(provider: GitRemoteProvider): void {
    const type = provider.config.type;
    if (this.providers.has(type)) {
      console.warn(`[GitRemoteProviderRegistry] Provider '${type}' is already registered, overwriting`);
    }
    this.providers.set(type, provider);
  }

  /**
   * Get provider by type
   */
  get(type: GitRemoteProviderType): GitRemoteProvider | undefined {
    return this.providers.get(type);
  }

  /**
   * Get provider by type (throws if not found)
   */
  getOrThrow(type: GitRemoteProviderType): GitRemoteProvider {
    const provider = this.get(type);
    if (!provider) {
      throw new Error(`Provider '${type}' is not registered`);
    }
    return provider;
  }

  /**
   * Check if provider exists
   */
  has(type: GitRemoteProviderType): boolean {
    return this.providers.has(type);
  }

  /**
   * Get all registered providers
   */
  getAll(): GitRemoteProvider[] {
    return Array.from(this.providers.values());
  }

  /**
   * List provider options for UI
   */
  listProviderOptions(): GitProviderOption[] {
    return this.getAll().map(provider => ({
      id: provider.config.type,
      type: provider.config.type,
      displayName: provider.config.displayName,
      description: provider.config.description,
      iconName: provider.config.iconName,
      supportsOAuth: provider.supportsOAuth,
      supportsFetchRepos: provider.supportsFetchRepos,
      supportsAutoRenew: provider.supportsAutoRenew,
    }));
  }

  /**
   * Validate URL against a specific provider
   */
  async validateUrl(type: GitRemoteProviderType, url: string): Promise<ValidationResult> {
    const provider = this.get(type);
    if (!provider) {
      return {
        valid: false,
        error: `Provider '${type}' is not registered`,
      };
    }
    return provider.validateUrl(url);
  }

  /**
   * Find the best provider for a given URL
   * Returns undefined if no provider can handle the URL
   */
  async detectProviderForUrl(url: string): Promise<GitRemoteProviderType | undefined> {
    for (const provider of this.getAll()) {
      const result = await provider.validateUrl(url);
      if (result.valid) {
        return provider.config.type;
      }
    }
    return undefined;
  }
}