gitgrip 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +3 -10
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/pr/create.d.ts.map +1 -1
- package/dist/commands/pr/create.js +29 -8
- package/dist/commands/pr/create.js.map +1 -1
- package/dist/commands/pr/merge.d.ts.map +1 -1
- package/dist/commands/pr/merge.js +40 -33
- package/dist/commands/pr/merge.js.map +1 -1
- package/dist/commands/pr/status.d.ts.map +1 -1
- package/dist/commands/pr/status.js +15 -11
- package/dist/commands/pr/status.js.map +1 -1
- package/dist/index.js +1 -17
- package/dist/index.js.map +1 -1
- package/dist/lib/github.d.ts +28 -4
- package/dist/lib/github.d.ts.map +1 -1
- package/dist/lib/github.js +65 -126
- package/dist/lib/github.js.map +1 -1
- package/dist/lib/linker.d.ts +19 -4
- package/dist/lib/linker.d.ts.map +1 -1
- package/dist/lib/linker.js +107 -16
- package/dist/lib/linker.js.map +1 -1
- package/dist/lib/manifest.d.ts +14 -16
- package/dist/lib/manifest.d.ts.map +1 -1
- package/dist/lib/manifest.js +49 -57
- package/dist/lib/manifest.js.map +1 -1
- package/dist/lib/platform/azure-devops.d.ts +83 -0
- package/dist/lib/platform/azure-devops.d.ts.map +1 -0
- package/dist/lib/platform/azure-devops.js +378 -0
- package/dist/lib/platform/azure-devops.js.map +1 -0
- package/dist/lib/platform/github.d.ts +82 -0
- package/dist/lib/platform/github.d.ts.map +1 -0
- package/dist/lib/platform/github.js +285 -0
- package/dist/lib/platform/github.js.map +1 -0
- package/dist/lib/platform/gitlab.d.ts +82 -0
- package/dist/lib/platform/gitlab.d.ts.map +1 -0
- package/dist/lib/platform/gitlab.js +331 -0
- package/dist/lib/platform/gitlab.js.map +1 -0
- package/dist/lib/platform/index.d.ts +60 -0
- package/dist/lib/platform/index.d.ts.map +1 -0
- package/dist/lib/platform/index.js +132 -0
- package/dist/lib/platform/index.js.map +1 -0
- package/dist/lib/platform/types.d.ts +162 -0
- package/dist/lib/platform/types.d.ts.map +1 -0
- package/dist/lib/platform/types.js +5 -0
- package/dist/lib/platform/types.js.map +1 -0
- package/dist/types.d.ts +39 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -1
- package/dist/commands/migrate.d.ts +0 -17
- package/dist/commands/migrate.d.ts.map +0 -1
- package/dist/commands/migrate.js +0 -180
- package/dist/commands/migrate.js.map +0 -1
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitLab hosting platform adapter
|
|
3
|
+
*/
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
/**
|
|
6
|
+
* GitLab platform adapter implementing the HostingPlatform interface
|
|
7
|
+
*/
|
|
8
|
+
export class GitLabPlatform {
|
|
9
|
+
type = 'gitlab';
|
|
10
|
+
token = null;
|
|
11
|
+
config;
|
|
12
|
+
baseUrl;
|
|
13
|
+
constructor(config) {
|
|
14
|
+
this.config = config ?? { type: 'gitlab' };
|
|
15
|
+
this.baseUrl = this.config.baseUrl ?? 'https://gitlab.com';
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get GitLab token from environment or glab CLI
|
|
19
|
+
*/
|
|
20
|
+
async getToken() {
|
|
21
|
+
if (this.token) {
|
|
22
|
+
return this.token;
|
|
23
|
+
}
|
|
24
|
+
// Try environment variable first
|
|
25
|
+
if (process.env.GITLAB_TOKEN) {
|
|
26
|
+
this.token = process.env.GITLAB_TOKEN;
|
|
27
|
+
return this.token;
|
|
28
|
+
}
|
|
29
|
+
// Try glab CLI
|
|
30
|
+
try {
|
|
31
|
+
const output = execSync('glab auth status -t 2>&1', { encoding: 'utf-8' });
|
|
32
|
+
// Parse token from glab output: "Token: glpat-..."
|
|
33
|
+
const tokenMatch = output.match(/Token:\s+(\S+)/);
|
|
34
|
+
if (tokenMatch) {
|
|
35
|
+
this.token = tokenMatch[1];
|
|
36
|
+
return this.token;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// glab CLI not available or not authenticated
|
|
41
|
+
}
|
|
42
|
+
throw new Error('GitLab token not found. Set GITLAB_TOKEN environment variable or run "glab auth login"');
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Make authenticated API request to GitLab
|
|
46
|
+
*/
|
|
47
|
+
async apiRequest(method, endpoint, body) {
|
|
48
|
+
const token = await this.getToken();
|
|
49
|
+
const url = `${this.baseUrl}/api/v4${endpoint}`;
|
|
50
|
+
const options = {
|
|
51
|
+
method,
|
|
52
|
+
headers: {
|
|
53
|
+
'PRIVATE-TOKEN': token,
|
|
54
|
+
'Content-Type': 'application/json',
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
if (body) {
|
|
58
|
+
options.body = JSON.stringify(body);
|
|
59
|
+
}
|
|
60
|
+
const response = await fetch(url, options);
|
|
61
|
+
if (!response.ok) {
|
|
62
|
+
const errorText = await response.text();
|
|
63
|
+
throw new Error(`GitLab API error (${response.status}): ${errorText}`);
|
|
64
|
+
}
|
|
65
|
+
return response.json();
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Encode project path for GitLab API (owner/repo -> owner%2Frepo)
|
|
69
|
+
*/
|
|
70
|
+
encodeProject(owner, repo) {
|
|
71
|
+
return encodeURIComponent(`${owner}/${repo}`);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Create a merge request
|
|
75
|
+
*/
|
|
76
|
+
async createPullRequest(owner, repo, head, base, title, body = '', draft = false) {
|
|
77
|
+
const projectId = this.encodeProject(owner, repo);
|
|
78
|
+
const mrTitle = draft ? `Draft: ${title}` : title;
|
|
79
|
+
const mr = await this.apiRequest('POST', `/projects/${projectId}/merge_requests`, {
|
|
80
|
+
source_branch: head,
|
|
81
|
+
target_branch: base,
|
|
82
|
+
title: mrTitle,
|
|
83
|
+
description: body,
|
|
84
|
+
});
|
|
85
|
+
return {
|
|
86
|
+
number: mr.iid,
|
|
87
|
+
url: mr.web_url,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get merge request details
|
|
92
|
+
*/
|
|
93
|
+
async getPullRequest(owner, repo, pullNumber) {
|
|
94
|
+
const projectId = this.encodeProject(owner, repo);
|
|
95
|
+
const mr = await this.apiRequest('GET', `/projects/${projectId}/merge_requests/${pullNumber}`);
|
|
96
|
+
// Map GitLab state to our unified state
|
|
97
|
+
let state = 'open';
|
|
98
|
+
let merged = false;
|
|
99
|
+
if (mr.state === 'merged') {
|
|
100
|
+
state = 'closed';
|
|
101
|
+
merged = true;
|
|
102
|
+
}
|
|
103
|
+
else if (mr.state === 'closed') {
|
|
104
|
+
state = 'closed';
|
|
105
|
+
}
|
|
106
|
+
// GitLab uses detailed_merge_status for mergeability
|
|
107
|
+
const mergeable = mr.detailed_merge_status === 'mergeable' ||
|
|
108
|
+
mr.merge_status === 'can_be_merged';
|
|
109
|
+
return {
|
|
110
|
+
number: mr.iid,
|
|
111
|
+
url: mr.web_url,
|
|
112
|
+
title: mr.title,
|
|
113
|
+
body: mr.description ?? '',
|
|
114
|
+
state,
|
|
115
|
+
merged,
|
|
116
|
+
mergeable,
|
|
117
|
+
head: {
|
|
118
|
+
ref: mr.source_branch,
|
|
119
|
+
sha: mr.sha,
|
|
120
|
+
},
|
|
121
|
+
base: {
|
|
122
|
+
ref: mr.target_branch,
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Update merge request description
|
|
128
|
+
*/
|
|
129
|
+
async updatePullRequestBody(owner, repo, pullNumber, body) {
|
|
130
|
+
const projectId = this.encodeProject(owner, repo);
|
|
131
|
+
await this.apiRequest('PUT', `/projects/${projectId}/merge_requests/${pullNumber}`, { description: body });
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Merge a merge request
|
|
135
|
+
*/
|
|
136
|
+
async mergePullRequest(owner, repo, pullNumber, options = {}) {
|
|
137
|
+
const projectId = this.encodeProject(owner, repo);
|
|
138
|
+
try {
|
|
139
|
+
// GitLab merge options
|
|
140
|
+
const mergeParams = {};
|
|
141
|
+
if (options.method === 'squash') {
|
|
142
|
+
mergeParams.squash = true;
|
|
143
|
+
}
|
|
144
|
+
if (options.deleteBranch) {
|
|
145
|
+
mergeParams.should_remove_source_branch = true;
|
|
146
|
+
}
|
|
147
|
+
await this.apiRequest('PUT', `/projects/${projectId}/merge_requests/${pullNumber}/merge`, mergeParams);
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Find MR by branch name
|
|
156
|
+
*/
|
|
157
|
+
async findPRByBranch(owner, repo, branch) {
|
|
158
|
+
const projectId = this.encodeProject(owner, repo);
|
|
159
|
+
const mrs = await this.apiRequest('GET', `/projects/${projectId}/merge_requests?source_branch=${encodeURIComponent(branch)}&state=opened`);
|
|
160
|
+
if (mrs.length > 0) {
|
|
161
|
+
return {
|
|
162
|
+
number: mrs[0].iid,
|
|
163
|
+
url: mrs[0].web_url,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Check if MR is approved
|
|
170
|
+
*/
|
|
171
|
+
async isPullRequestApproved(owner, repo, pullNumber) {
|
|
172
|
+
const projectId = this.encodeProject(owner, repo);
|
|
173
|
+
try {
|
|
174
|
+
const approval = await this.apiRequest('GET', `/projects/${projectId}/merge_requests/${pullNumber}/approvals`);
|
|
175
|
+
return approval.approved;
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// Approvals API might not be available (requires license)
|
|
179
|
+
// Fall back to checking if MR has any approvals
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Get MR reviews/approvals
|
|
185
|
+
*/
|
|
186
|
+
async getPullRequestReviews(owner, repo, pullNumber) {
|
|
187
|
+
const projectId = this.encodeProject(owner, repo);
|
|
188
|
+
try {
|
|
189
|
+
const approval = await this.apiRequest('GET', `/projects/${projectId}/merge_requests/${pullNumber}/approvals`);
|
|
190
|
+
return approval.approved_by.map((a) => ({
|
|
191
|
+
state: 'APPROVED',
|
|
192
|
+
user: a.user.username,
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Get pipeline status for MR
|
|
201
|
+
*/
|
|
202
|
+
async getStatusChecks(owner, repo, ref) {
|
|
203
|
+
const projectId = this.encodeProject(owner, repo);
|
|
204
|
+
try {
|
|
205
|
+
// Get pipelines for this ref
|
|
206
|
+
const pipelines = await this.apiRequest('GET', `/projects/${projectId}/pipelines?sha=${ref}&per_page=1`);
|
|
207
|
+
if (pipelines.length === 0) {
|
|
208
|
+
return { state: 'success', statuses: [] };
|
|
209
|
+
}
|
|
210
|
+
const pipeline = pipelines[0];
|
|
211
|
+
// Map GitLab pipeline status to our unified status
|
|
212
|
+
let state;
|
|
213
|
+
switch (pipeline.status) {
|
|
214
|
+
case 'success':
|
|
215
|
+
state = 'success';
|
|
216
|
+
break;
|
|
217
|
+
case 'failed':
|
|
218
|
+
case 'canceled':
|
|
219
|
+
state = 'failure';
|
|
220
|
+
break;
|
|
221
|
+
default:
|
|
222
|
+
state = 'pending';
|
|
223
|
+
}
|
|
224
|
+
return {
|
|
225
|
+
state,
|
|
226
|
+
statuses: [{ context: 'gitlab-pipeline', state: pipeline.status }],
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
// No pipeline or API error
|
|
231
|
+
return { state: 'success', statuses: [] };
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Parse GitLab URL to extract owner/repo (group/project)
|
|
236
|
+
*/
|
|
237
|
+
parseRepoUrl(url) {
|
|
238
|
+
// Extract hostname from baseUrl for matching
|
|
239
|
+
const baseHost = new URL(this.baseUrl).host;
|
|
240
|
+
const escapedHost = baseHost.replace(/\./g, '\\.');
|
|
241
|
+
// SSH format: git@gitlab.com:owner/repo.git or git@gitlab.com:group/subgroup/repo.git
|
|
242
|
+
const sshRegex = new RegExp(`git@${escapedHost}:(.+?)(?:\\.git)?$`);
|
|
243
|
+
const sshMatch = url.match(sshRegex);
|
|
244
|
+
if (sshMatch) {
|
|
245
|
+
const path = sshMatch[1];
|
|
246
|
+
const parts = path.split('/');
|
|
247
|
+
// Last part is repo, everything else is the namespace (owner)
|
|
248
|
+
const repo = parts.pop();
|
|
249
|
+
const owner = parts.join('/');
|
|
250
|
+
return { owner, repo };
|
|
251
|
+
}
|
|
252
|
+
// HTTPS format: https://gitlab.com/owner/repo.git
|
|
253
|
+
const httpsRegex = new RegExp(`https?://${escapedHost}/(.+?)(?:\\.git)?$`);
|
|
254
|
+
const httpsMatch = url.match(httpsRegex);
|
|
255
|
+
if (httpsMatch) {
|
|
256
|
+
const path = httpsMatch[1];
|
|
257
|
+
const parts = path.split('/');
|
|
258
|
+
const repo = parts.pop();
|
|
259
|
+
const owner = parts.join('/');
|
|
260
|
+
return { owner, repo };
|
|
261
|
+
}
|
|
262
|
+
// Also check for generic gitlab patterns if no baseUrl match
|
|
263
|
+
if (this.baseUrl === 'https://gitlab.com') {
|
|
264
|
+
const genericSshMatch = url.match(/git@gitlab\.com:(.+?)(?:\.git)?$/);
|
|
265
|
+
if (genericSshMatch) {
|
|
266
|
+
const path = genericSshMatch[1];
|
|
267
|
+
const parts = path.split('/');
|
|
268
|
+
const repo = parts.pop();
|
|
269
|
+
const owner = parts.join('/');
|
|
270
|
+
return { owner, repo };
|
|
271
|
+
}
|
|
272
|
+
const genericHttpsMatch = url.match(/https?:\/\/gitlab\.com\/(.+?)(?:\.git)?$/);
|
|
273
|
+
if (genericHttpsMatch) {
|
|
274
|
+
const path = genericHttpsMatch[1];
|
|
275
|
+
const parts = path.split('/');
|
|
276
|
+
const repo = parts.pop();
|
|
277
|
+
const owner = parts.join('/');
|
|
278
|
+
return { owner, repo };
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Check if URL matches GitLab
|
|
285
|
+
*/
|
|
286
|
+
matchesUrl(url) {
|
|
287
|
+
// Check for gitlab.com (specific match)
|
|
288
|
+
if (url.includes('gitlab.com'))
|
|
289
|
+
return true;
|
|
290
|
+
// Check against configured base URL
|
|
291
|
+
if (this.config.baseUrl) {
|
|
292
|
+
const host = new URL(this.config.baseUrl).host;
|
|
293
|
+
if (url.includes(host))
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
// Check if URL appears to be GitLab (contains gitlab in the hostname, not path)
|
|
297
|
+
// Match patterns like git@gitlab.company.com or https://gitlab.company.com
|
|
298
|
+
if (/(?:@|:\/\/)gitlab\./i.test(url))
|
|
299
|
+
return true;
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Generate HTML comment for linked MR tracking
|
|
304
|
+
*/
|
|
305
|
+
generateLinkedPRComment(links) {
|
|
306
|
+
const prLinks = links.map((pr) => `${pr.repoName}!${pr.number}`).join(',');
|
|
307
|
+
return `<!-- codi-repo:links:${prLinks} -->`;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Parse linked MRs from MR description
|
|
311
|
+
*/
|
|
312
|
+
parseLinkedPRComment(body) {
|
|
313
|
+
const match = body.match(/<!-- codi-repo:links:(.+?) -->/);
|
|
314
|
+
if (!match) {
|
|
315
|
+
return [];
|
|
316
|
+
}
|
|
317
|
+
const links = match[1].split(',');
|
|
318
|
+
return links.map((link) => {
|
|
319
|
+
// GitLab uses ! for MR references
|
|
320
|
+
const [repoName, numStr] = link.split(/[#!]/);
|
|
321
|
+
return { repoName, number: parseInt(numStr, 10) };
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Create a new GitLab platform instance
|
|
327
|
+
*/
|
|
328
|
+
export function createGitLabPlatform(config) {
|
|
329
|
+
return new GitLabPlatform(config);
|
|
330
|
+
}
|
|
331
|
+
//# sourceMappingURL=gitlab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitlab.js","sourceRoot":"","sources":["../../../src/lib/platform/gitlab.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform abstraction for multi-platform hosting support
|
|
3
|
+
*
|
|
4
|
+
* This module provides a unified interface for working with different
|
|
5
|
+
* git hosting platforms (GitHub, GitLab, Azure DevOps).
|
|
6
|
+
*/
|
|
7
|
+
export * from './types.js';
|
|
8
|
+
export { GitHubPlatform, getGitHubPlatform, createGitHubPlatform } from './github.js';
|
|
9
|
+
export { GitLabPlatform, createGitLabPlatform } from './gitlab.js';
|
|
10
|
+
export { AzureDevOpsPlatform, createAzureDevOpsPlatform } from './azure-devops.js';
|
|
11
|
+
import type { HostingPlatform, PlatformType, PlatformConfig, ParsedRepoInfo } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Detect the platform type from a git URL
|
|
14
|
+
*
|
|
15
|
+
* @param url - Git URL (SSH or HTTPS format)
|
|
16
|
+
* @returns The detected platform type, or null if unknown
|
|
17
|
+
*/
|
|
18
|
+
export declare function detectPlatform(url: string): PlatformType | null;
|
|
19
|
+
/**
|
|
20
|
+
* Get a platform adapter for the specified type
|
|
21
|
+
*
|
|
22
|
+
* Uses caching to return the same instance for identical configurations.
|
|
23
|
+
*
|
|
24
|
+
* @param type - Platform type
|
|
25
|
+
* @param config - Optional platform configuration (for self-hosted instances)
|
|
26
|
+
* @returns Platform adapter instance
|
|
27
|
+
*/
|
|
28
|
+
export declare function getPlatformAdapter(type: PlatformType, config?: PlatformConfig): HostingPlatform;
|
|
29
|
+
/**
|
|
30
|
+
* Get a platform adapter for a specific git URL
|
|
31
|
+
*
|
|
32
|
+
* Auto-detects the platform from the URL.
|
|
33
|
+
*
|
|
34
|
+
* @param url - Git URL (SSH or HTTPS format)
|
|
35
|
+
* @param config - Optional platform configuration (for self-hosted instances)
|
|
36
|
+
* @returns Platform adapter instance
|
|
37
|
+
* @throws Error if platform cannot be detected
|
|
38
|
+
*/
|
|
39
|
+
export declare function getPlatformForUrl(url: string, config?: PlatformConfig): HostingPlatform;
|
|
40
|
+
/**
|
|
41
|
+
* Parse a git URL using the appropriate platform adapter
|
|
42
|
+
*
|
|
43
|
+
* @param url - Git URL (SSH or HTTPS format)
|
|
44
|
+
* @returns Parsed repository info, or null if URL format is not recognized
|
|
45
|
+
*/
|
|
46
|
+
export declare function parseRepoUrl(url: string): (ParsedRepoInfo & {
|
|
47
|
+
platform: PlatformType;
|
|
48
|
+
}) | null;
|
|
49
|
+
/**
|
|
50
|
+
* Check if a URL belongs to a supported hosting platform
|
|
51
|
+
*
|
|
52
|
+
* @param url - Git URL to check
|
|
53
|
+
* @returns true if the URL is from a supported platform
|
|
54
|
+
*/
|
|
55
|
+
export declare function isSupportedUrl(url: string): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Clear the platform cache (useful for testing)
|
|
58
|
+
*/
|
|
59
|
+
export declare function clearPlatformCache(): void;
|
|
60
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/platform/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAEnF,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAQhG;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CA2B/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,YAAY,EAClB,MAAM,CAAC,EAAE,cAAc,GACtB,eAAe,CA8BjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,cAAc,GACtB,eAAe,CAUjB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,cAAc,GAAG;IAAE,QAAQ,EAAE,YAAY,CAAA;CAAE,CAAC,GAAG,IAAI,CAc9F;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform abstraction for multi-platform hosting support
|
|
3
|
+
*
|
|
4
|
+
* This module provides a unified interface for working with different
|
|
5
|
+
* git hosting platforms (GitHub, GitLab, Azure DevOps).
|
|
6
|
+
*/
|
|
7
|
+
export * from './types.js';
|
|
8
|
+
export { GitHubPlatform, getGitHubPlatform, createGitHubPlatform } from './github.js';
|
|
9
|
+
export { GitLabPlatform, createGitLabPlatform } from './gitlab.js';
|
|
10
|
+
export { AzureDevOpsPlatform, createAzureDevOpsPlatform } from './azure-devops.js';
|
|
11
|
+
import { GitHubPlatform } from './github.js';
|
|
12
|
+
import { GitLabPlatform } from './gitlab.js';
|
|
13
|
+
import { AzureDevOpsPlatform } from './azure-devops.js';
|
|
14
|
+
// Cache of platform instances by type and baseUrl
|
|
15
|
+
const platformCache = new Map();
|
|
16
|
+
/**
|
|
17
|
+
* Detect the platform type from a git URL
|
|
18
|
+
*
|
|
19
|
+
* @param url - Git URL (SSH or HTTPS format)
|
|
20
|
+
* @returns The detected platform type, or null if unknown
|
|
21
|
+
*/
|
|
22
|
+
export function detectPlatform(url) {
|
|
23
|
+
// GitHub detection (most common, check first)
|
|
24
|
+
if (url.includes('github.com')) {
|
|
25
|
+
return 'github';
|
|
26
|
+
}
|
|
27
|
+
// Azure DevOps detection (check before GitLab to avoid false positives)
|
|
28
|
+
if (url.includes('dev.azure.com') ||
|
|
29
|
+
url.includes('visualstudio.com') ||
|
|
30
|
+
url.includes('ssh.dev.azure.com')) {
|
|
31
|
+
return 'azure-devops';
|
|
32
|
+
}
|
|
33
|
+
// GitLab detection - check for gitlab.com or gitlab in hostname (not in path)
|
|
34
|
+
// This avoids false positives like "git@myserver.com:my-gitlab-clone/repo.git"
|
|
35
|
+
if (url.includes('gitlab.com')) {
|
|
36
|
+
return 'gitlab';
|
|
37
|
+
}
|
|
38
|
+
// Match URLs where "gitlab" appears in the hostname portion
|
|
39
|
+
// e.g., git@gitlab.company.com: or https://gitlab.company.com/
|
|
40
|
+
if (/(?:@|:\/\/)gitlab\./i.test(url)) {
|
|
41
|
+
return 'gitlab';
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get a platform adapter for the specified type
|
|
47
|
+
*
|
|
48
|
+
* Uses caching to return the same instance for identical configurations.
|
|
49
|
+
*
|
|
50
|
+
* @param type - Platform type
|
|
51
|
+
* @param config - Optional platform configuration (for self-hosted instances)
|
|
52
|
+
* @returns Platform adapter instance
|
|
53
|
+
*/
|
|
54
|
+
export function getPlatformAdapter(type, config) {
|
|
55
|
+
// Create cache key based on type and baseUrl
|
|
56
|
+
const cacheKey = `${type}:${config?.baseUrl ?? 'default'}`;
|
|
57
|
+
// Check cache first
|
|
58
|
+
let platform = platformCache.get(cacheKey);
|
|
59
|
+
if (platform) {
|
|
60
|
+
return platform;
|
|
61
|
+
}
|
|
62
|
+
// Create new instance
|
|
63
|
+
const platformConfig = { type, ...config };
|
|
64
|
+
switch (type) {
|
|
65
|
+
case 'github':
|
|
66
|
+
platform = new GitHubPlatform(platformConfig);
|
|
67
|
+
break;
|
|
68
|
+
case 'gitlab':
|
|
69
|
+
platform = new GitLabPlatform(platformConfig);
|
|
70
|
+
break;
|
|
71
|
+
case 'azure-devops':
|
|
72
|
+
platform = new AzureDevOpsPlatform(platformConfig);
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
throw new Error(`Unknown platform type: ${type}`);
|
|
76
|
+
}
|
|
77
|
+
// Cache and return
|
|
78
|
+
platformCache.set(cacheKey, platform);
|
|
79
|
+
return platform;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get a platform adapter for a specific git URL
|
|
83
|
+
*
|
|
84
|
+
* Auto-detects the platform from the URL.
|
|
85
|
+
*
|
|
86
|
+
* @param url - Git URL (SSH or HTTPS format)
|
|
87
|
+
* @param config - Optional platform configuration (for self-hosted instances)
|
|
88
|
+
* @returns Platform adapter instance
|
|
89
|
+
* @throws Error if platform cannot be detected
|
|
90
|
+
*/
|
|
91
|
+
export function getPlatformForUrl(url, config) {
|
|
92
|
+
const type = detectPlatform(url);
|
|
93
|
+
if (!type) {
|
|
94
|
+
throw new Error(`Unable to detect hosting platform from URL: ${url}. ` +
|
|
95
|
+
`Supported platforms: GitHub, GitLab, Azure DevOps`);
|
|
96
|
+
}
|
|
97
|
+
return getPlatformAdapter(type, config);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Parse a git URL using the appropriate platform adapter
|
|
101
|
+
*
|
|
102
|
+
* @param url - Git URL (SSH or HTTPS format)
|
|
103
|
+
* @returns Parsed repository info, or null if URL format is not recognized
|
|
104
|
+
*/
|
|
105
|
+
export function parseRepoUrl(url) {
|
|
106
|
+
const type = detectPlatform(url);
|
|
107
|
+
if (!type) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const platform = getPlatformAdapter(type);
|
|
111
|
+
const parsed = platform.parseRepoUrl(url);
|
|
112
|
+
if (!parsed) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
return { ...parsed, platform: type };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Check if a URL belongs to a supported hosting platform
|
|
119
|
+
*
|
|
120
|
+
* @param url - Git URL to check
|
|
121
|
+
* @returns true if the URL is from a supported platform
|
|
122
|
+
*/
|
|
123
|
+
export function isSupportedUrl(url) {
|
|
124
|
+
return detectPlatform(url) !== null;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Clear the platform cache (useful for testing)
|
|
128
|
+
*/
|
|
129
|
+
export function clearPlatformCache() {
|
|
130
|
+
platformCache.clear();
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/platform/index.ts"],"names":[],"mappings":"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"}
|