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;
}
}