@forge-glance/sdk 0.1.0 → 0.2.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/dist/GitHubProvider.d.ts +19 -3
- package/dist/GitHubProvider.js +217 -1
- package/dist/GitLabProvider.d.ts +25 -3
- package/dist/GitLabProvider.js +285 -1
- package/dist/GitProvider.d.ts +89 -1
- package/dist/index.d.ts +14 -14
- package/dist/index.js +502 -2
- package/dist/providers.js +502 -2
- package/dist/types.d.ts +103 -0
- package/package.json +1 -1
- package/src/GitHubProvider.ts +534 -115
- package/src/GitLabProvider.ts +519 -56
- package/src/GitProvider.ts +155 -13
- package/src/index.ts +25 -15
- package/src/types.ts +111 -0
package/src/GitProvider.ts
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
BranchProtectionRule,
|
|
3
|
+
CreatePullRequestInput,
|
|
4
|
+
Discussion,
|
|
5
|
+
MergePullRequestInput,
|
|
6
|
+
MRDetail,
|
|
7
|
+
ProviderCapabilities,
|
|
8
|
+
PullRequest,
|
|
9
|
+
UpdatePullRequestInput,
|
|
10
|
+
UserRef
|
|
11
|
+
} from './types.ts';
|
|
2
12
|
|
|
3
13
|
/**
|
|
4
14
|
* Provider-agnostic interface for a Git hosting service.
|
|
@@ -31,17 +41,153 @@ export interface GitProvider {
|
|
|
31
41
|
fetchSingleMR(
|
|
32
42
|
projectPath: string,
|
|
33
43
|
mrIid: number,
|
|
34
|
-
currentUserNumericId: number | null
|
|
44
|
+
currentUserNumericId: number | null
|
|
35
45
|
): Promise<PullRequest | null>;
|
|
36
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Fetch a single MR/PR by its source branch within a project.
|
|
49
|
+
* Returns null if no open MR/PR exists for that branch.
|
|
50
|
+
*/
|
|
51
|
+
fetchPullRequestByBranch(
|
|
52
|
+
projectPath: string,
|
|
53
|
+
sourceBranch: string
|
|
54
|
+
): Promise<PullRequest | null>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Create a new merge request / pull request.
|
|
58
|
+
* Returns the created PullRequest.
|
|
59
|
+
*/
|
|
60
|
+
createPullRequest(input: CreatePullRequestInput): Promise<PullRequest>;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Update an existing merge request / pull request.
|
|
64
|
+
* Returns the updated PullRequest.
|
|
65
|
+
*/
|
|
66
|
+
updatePullRequest(
|
|
67
|
+
projectPath: string,
|
|
68
|
+
mrIid: number,
|
|
69
|
+
input: UpdatePullRequestInput
|
|
70
|
+
): Promise<PullRequest>;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Fetch branch protection rules for a repository.
|
|
74
|
+
* Returns an array of rules (one per protected branch/pattern).
|
|
75
|
+
*/
|
|
76
|
+
fetchBranchProtectionRules(
|
|
77
|
+
projectPath: string
|
|
78
|
+
): Promise<BranchProtectionRule[]>;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Delete a branch from the repository.
|
|
82
|
+
* @throws if the branch doesn't exist or is protected.
|
|
83
|
+
*/
|
|
84
|
+
deleteBranch(projectPath: string, branch: string): Promise<void>;
|
|
85
|
+
|
|
37
86
|
/**
|
|
38
87
|
* Fetch discussions (comments, threads) for a specific MR/PR.
|
|
39
88
|
* Returns the MRDetail with discussions populated.
|
|
40
89
|
*/
|
|
41
|
-
fetchMRDiscussions(
|
|
42
|
-
|
|
90
|
+
fetchMRDiscussions(repositoryId: string, mrIid: number): Promise<MRDetail>;
|
|
91
|
+
|
|
92
|
+
// ── Mutation capabilities ───────────────────────────────────────────────
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Reports which mutation operations this provider supports.
|
|
96
|
+
* Callers should check these flags to conditionally show/hide UI
|
|
97
|
+
* affordances without knowing which provider they're talking to.
|
|
98
|
+
*/
|
|
99
|
+
readonly capabilities: ProviderCapabilities;
|
|
100
|
+
|
|
101
|
+
// ── MR lifecycle mutations ──────────────────────────────────────────────
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Merge (accept) a pull request / merge request.
|
|
105
|
+
* All input fields are optional — omitting them defers to the project's
|
|
106
|
+
* configured defaults (merge method, squash policy, delete-source-branch).
|
|
107
|
+
*/
|
|
108
|
+
mergePullRequest(
|
|
109
|
+
projectPath: string,
|
|
110
|
+
mrIid: number,
|
|
111
|
+
input?: MergePullRequestInput
|
|
112
|
+
): Promise<PullRequest>;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Approve a pull request / merge request.
|
|
116
|
+
* On GitLab: POST /merge_requests/:iid/approve
|
|
117
|
+
* On GitHub: POST /pulls/:number/reviews with event "APPROVE"
|
|
118
|
+
*/
|
|
119
|
+
approvePullRequest(projectPath: string, mrIid: number): Promise<void>;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Revoke an existing approval.
|
|
123
|
+
* GitLab-only — GitHub does not support unapproving via API.
|
|
124
|
+
* Check `capabilities.canUnapprove` before calling.
|
|
125
|
+
*/
|
|
126
|
+
unapprovePullRequest(projectPath: string, mrIid: number): Promise<void>;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Rebase the MR source branch onto the target branch.
|
|
130
|
+
* GitLab-only — GitHub does not have a native rebase API.
|
|
131
|
+
* Check `capabilities.canRebase` before calling.
|
|
132
|
+
*/
|
|
133
|
+
rebasePullRequest(projectPath: string, mrIid: number): Promise<void>;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Enable auto-merge: the MR will be merged automatically when the
|
|
137
|
+
* pipeline succeeds and all approval rules are met.
|
|
138
|
+
* GitLab-only — check `capabilities.canAutoMerge` before calling.
|
|
139
|
+
*/
|
|
140
|
+
setAutoMerge(projectPath: string, mrIid: number): Promise<void>;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Cancel a previously enabled auto-merge.
|
|
144
|
+
* GitLab-only — check `capabilities.canAutoMerge` before calling.
|
|
145
|
+
*/
|
|
146
|
+
cancelAutoMerge(projectPath: string, mrIid: number): Promise<void>;
|
|
147
|
+
|
|
148
|
+
// ── Discussion mutations ────────────────────────────────────────────────
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Resolve a discussion thread on an MR.
|
|
152
|
+
* GitLab-only — check `capabilities.canResolveDiscussions` before calling.
|
|
153
|
+
*/
|
|
154
|
+
resolveDiscussion(
|
|
155
|
+
projectPath: string,
|
|
156
|
+
mrIid: number,
|
|
157
|
+
discussionId: string
|
|
158
|
+
): Promise<void>;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Unresolve a previously resolved discussion thread.
|
|
162
|
+
* GitLab-only — check `capabilities.canResolveDiscussions` before calling.
|
|
163
|
+
*/
|
|
164
|
+
unresolveDiscussion(
|
|
165
|
+
projectPath: string,
|
|
166
|
+
mrIid: number,
|
|
167
|
+
discussionId: string
|
|
168
|
+
): Promise<void>;
|
|
169
|
+
|
|
170
|
+
// ── Pipeline mutations ──────────────────────────────────────────────────
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Retry a failed or canceled pipeline.
|
|
174
|
+
* On GitLab: POST /pipelines/:id/retry
|
|
175
|
+
* On GitHub: POST re-run for the workflow run.
|
|
176
|
+
*/
|
|
177
|
+
retryPipeline(projectPath: string, pipelineId: number): Promise<void>;
|
|
178
|
+
|
|
179
|
+
// ── Review mutations ────────────────────────────────────────────────────
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Re-request review attention on an MR from its reviewers.
|
|
183
|
+
* If `reviewerUsernames` is provided, only those reviewers are pinged;
|
|
184
|
+
* otherwise all current reviewers are re-requested.
|
|
185
|
+
*/
|
|
186
|
+
requestReReview(
|
|
187
|
+
projectPath: string,
|
|
43
188
|
mrIid: number,
|
|
44
|
-
|
|
189
|
+
reviewerUsernames?: string[]
|
|
190
|
+
): Promise<void>;
|
|
45
191
|
|
|
46
192
|
// ── REST pass-through (used by note mutations, job traces, etc.) ────────
|
|
47
193
|
|
|
@@ -52,11 +198,7 @@ export interface GitProvider {
|
|
|
52
198
|
*
|
|
53
199
|
* Implementations translate the path to the provider's API URL format.
|
|
54
200
|
*/
|
|
55
|
-
restRequest(
|
|
56
|
-
method: string,
|
|
57
|
-
path: string,
|
|
58
|
-
body?: unknown,
|
|
59
|
-
): Promise<Response>;
|
|
201
|
+
restRequest(method: string, path: string, body?: unknown): Promise<Response>;
|
|
60
202
|
}
|
|
61
203
|
|
|
62
204
|
/**
|
|
@@ -64,8 +206,8 @@ export interface GitProvider {
|
|
|
64
206
|
* e.g. "gitlab:42" → 42, "github:12345" → 12345
|
|
65
207
|
*/
|
|
66
208
|
export function parseRepoId(repositoryId: string): number {
|
|
67
|
-
const parts = repositoryId.split(
|
|
68
|
-
return parseInt(parts.at(-1) ??
|
|
209
|
+
const parts = repositoryId.split(':');
|
|
210
|
+
return parseInt(parts.at(-1) ?? '0', 10);
|
|
69
211
|
}
|
|
70
212
|
|
|
71
213
|
/**
|
|
@@ -73,5 +215,5 @@ export function parseRepoId(repositoryId: string): number {
|
|
|
73
215
|
* e.g. "gitlab:42" → "gitlab", "github:12345" → "github"
|
|
74
216
|
*/
|
|
75
217
|
export function repoIdProvider(repositoryId: string): string {
|
|
76
|
-
return repositoryId.split(
|
|
218
|
+
return repositoryId.split(':')[0] ?? 'unknown';
|
|
77
219
|
}
|
package/src/index.ts
CHANGED
|
@@ -16,6 +16,12 @@
|
|
|
16
16
|
export type {
|
|
17
17
|
PullRequest,
|
|
18
18
|
PullRequestsSnapshot,
|
|
19
|
+
CreatePullRequestInput,
|
|
20
|
+
UpdatePullRequestInput,
|
|
21
|
+
MergePullRequestInput,
|
|
22
|
+
MergeMethod,
|
|
23
|
+
ProviderCapabilities,
|
|
24
|
+
BranchProtectionRule,
|
|
19
25
|
Pipeline,
|
|
20
26
|
PipelineJob,
|
|
21
27
|
UserRef,
|
|
@@ -27,28 +33,32 @@ export type {
|
|
|
27
33
|
MRDetail,
|
|
28
34
|
FeedEvent,
|
|
29
35
|
FeedSnapshot,
|
|
30
|
-
ServerNotification
|
|
31
|
-
} from
|
|
36
|
+
ServerNotification
|
|
37
|
+
} from './types.ts';
|
|
32
38
|
|
|
33
39
|
// ── Provider interface ────────────────────────────────────────────────────────
|
|
34
|
-
export type { GitProvider } from
|
|
35
|
-
export { parseRepoId, repoIdProvider } from
|
|
40
|
+
export type { GitProvider } from './GitProvider.ts';
|
|
41
|
+
export { parseRepoId, repoIdProvider } from './GitProvider.ts';
|
|
36
42
|
|
|
37
43
|
// ── Logger ────────────────────────────────────────────────────────────────────
|
|
38
|
-
export type { ForgeLogger } from
|
|
39
|
-
export { noopLogger } from
|
|
44
|
+
export type { ForgeLogger } from './logger.ts';
|
|
45
|
+
export { noopLogger } from './logger.ts';
|
|
40
46
|
|
|
41
47
|
// ── Providers ─────────────────────────────────────────────────────────────────
|
|
42
|
-
export {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
export {
|
|
49
|
+
GitLabProvider,
|
|
50
|
+
parseGitLabRepoId,
|
|
51
|
+
MR_DASHBOARD_FRAGMENT
|
|
52
|
+
} from './GitLabProvider.ts';
|
|
53
|
+
export { GitHubProvider } from './GitHubProvider.ts';
|
|
54
|
+
export { createProvider, SUPPORTED_PROVIDERS } from './providers.ts';
|
|
55
|
+
export type { ProviderSlug } from './providers.ts';
|
|
46
56
|
|
|
47
57
|
// ── GitLab real-time ──────────────────────────────────────────────────────────
|
|
48
|
-
export { ActionCableClient } from
|
|
49
|
-
export type { ActionCableCallbacks } from
|
|
58
|
+
export { ActionCableClient } from './ActionCableClient.ts';
|
|
59
|
+
export type { ActionCableCallbacks } from './ActionCableClient.ts';
|
|
50
60
|
|
|
51
61
|
// ── GitLab detail + mutations ─────────────────────────────────────────────────
|
|
52
|
-
export { MRDetailFetcher } from
|
|
53
|
-
export { NoteMutator } from
|
|
54
|
-
export type { CreatedNote } from
|
|
62
|
+
export { MRDetailFetcher } from './MRDetailFetcher.ts';
|
|
63
|
+
export { NoteMutator } from './NoteMutator.ts';
|
|
64
|
+
export type { CreatedNote } from './NoteMutator.ts';
|
package/src/types.ts
CHANGED
|
@@ -84,6 +84,117 @@ export interface PullRequest {
|
|
|
84
84
|
detailedMergeStatus: string | null;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
// ── MR/PR mutation inputs ─────────────────────────────────────────────────────
|
|
88
|
+
|
|
89
|
+
/** Input for creating a new merge request / pull request. */
|
|
90
|
+
export interface CreatePullRequestInput {
|
|
91
|
+
/** Project path (GitLab: "group/project") or owner/repo (GitHub: "owner/repo"). */
|
|
92
|
+
projectPath: string;
|
|
93
|
+
title: string;
|
|
94
|
+
description?: string;
|
|
95
|
+
sourceBranch: string;
|
|
96
|
+
targetBranch: string;
|
|
97
|
+
draft?: boolean;
|
|
98
|
+
/** Usernames to assign as reviewers. */
|
|
99
|
+
reviewers?: string[];
|
|
100
|
+
/** Usernames to assign. */
|
|
101
|
+
assignees?: string[];
|
|
102
|
+
/** Labels to apply (string names). */
|
|
103
|
+
labels?: string[];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Input for updating an existing merge request / pull request. */
|
|
107
|
+
export interface UpdatePullRequestInput {
|
|
108
|
+
title?: string;
|
|
109
|
+
description?: string;
|
|
110
|
+
/** Set draft status. */
|
|
111
|
+
draft?: boolean;
|
|
112
|
+
/** Change the target branch. */
|
|
113
|
+
targetBranch?: string;
|
|
114
|
+
/** Usernames to assign as reviewers (replaces current set). */
|
|
115
|
+
reviewers?: string[];
|
|
116
|
+
/** Usernames to assign (replaces current set). */
|
|
117
|
+
assignees?: string[];
|
|
118
|
+
/** Labels (replaces current set). */
|
|
119
|
+
labels?: string[];
|
|
120
|
+
/** Set MR state: "close" or "reopen". */
|
|
121
|
+
stateEvent?: 'close' | 'reopen';
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Merge strategy override.
|
|
126
|
+
* - "merge" — Standard merge commit.
|
|
127
|
+
* - "squash" — Squash all commits into one before merging.
|
|
128
|
+
* - "rebase" — Rebase the source branch onto the target (fast-forward).
|
|
129
|
+
*
|
|
130
|
+
* When omitted, the provider uses the project's configured default merge method.
|
|
131
|
+
*/
|
|
132
|
+
export type MergeMethod = 'merge' | 'squash' | 'rebase';
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Input for merging (accepting) a pull request / merge request.
|
|
136
|
+
*
|
|
137
|
+
* All fields are **optional**. Omitting them defers to the project-level
|
|
138
|
+
* settings configured in the forge UI (merge method, squash policy,
|
|
139
|
+
* delete-source-branch, etc.). This matches how the web UI works.
|
|
140
|
+
*/
|
|
141
|
+
export interface MergePullRequestInput {
|
|
142
|
+
/** Merge commit message. Omit to use the provider/project default. */
|
|
143
|
+
commitMessage?: string;
|
|
144
|
+
/** Squash commit message (when merge method is "squash"). */
|
|
145
|
+
squashCommitMessage?: string;
|
|
146
|
+
/** Whether to squash commits. Omit to use the MR / project default. */
|
|
147
|
+
squash?: boolean;
|
|
148
|
+
/** Merge strategy override. Omit to use the project's default merge method. */
|
|
149
|
+
mergeMethod?: MergeMethod;
|
|
150
|
+
/** Delete source branch after merge. Omit to use project default. */
|
|
151
|
+
shouldRemoveSourceBranch?: boolean;
|
|
152
|
+
/** SHA that HEAD must match for the merge to proceed (optimistic locking). */
|
|
153
|
+
sha?: string;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Reports which mutation operations a provider supports.
|
|
158
|
+
*
|
|
159
|
+
* Callers should check these flags before invoking vendor-specific methods
|
|
160
|
+
* so they can conditionally show/hide UI affordances without
|
|
161
|
+
* knowing which provider they're talking to.
|
|
162
|
+
*/
|
|
163
|
+
export interface ProviderCapabilities {
|
|
164
|
+
/** Can merge / accept a pull request. */
|
|
165
|
+
canMerge: boolean;
|
|
166
|
+
/** Can approve a pull request. */
|
|
167
|
+
canApprove: boolean;
|
|
168
|
+
/** Can revoke an existing approval. */
|
|
169
|
+
canUnapprove: boolean;
|
|
170
|
+
/** Can rebase the source branch onto the target. */
|
|
171
|
+
canRebase: boolean;
|
|
172
|
+
/** Can enable automatic merge when pipeline succeeds. */
|
|
173
|
+
canAutoMerge: boolean;
|
|
174
|
+
/** Can resolve / unresolve discussion threads. */
|
|
175
|
+
canResolveDiscussions: boolean;
|
|
176
|
+
/** Can retry a pipeline. */
|
|
177
|
+
canRetryPipeline: boolean;
|
|
178
|
+
/** Can re-request review attention from reviewers. */
|
|
179
|
+
canRequestReReview: boolean;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** Branch protection rule (provider-agnostic). */
|
|
183
|
+
export interface BranchProtectionRule {
|
|
184
|
+
/** Branch name or pattern, e.g. "main" or "release/*". */
|
|
185
|
+
pattern: string;
|
|
186
|
+
/** Whether force-pushes are allowed. */
|
|
187
|
+
allowForcePush: boolean;
|
|
188
|
+
/** Whether branch deletions are allowed. */
|
|
189
|
+
allowDeletion: boolean;
|
|
190
|
+
/** Number of required approving reviews (0 = none required). */
|
|
191
|
+
requiredApprovals: number;
|
|
192
|
+
/** Whether the branch requires status checks to pass before merge. */
|
|
193
|
+
requireStatusChecks: boolean;
|
|
194
|
+
/** Raw provider-specific data for fields not covered above. */
|
|
195
|
+
raw?: Record<string, unknown>;
|
|
196
|
+
}
|
|
197
|
+
|
|
87
198
|
/** Snapshot payload sent when a client first connects. */
|
|
88
199
|
export interface PullRequestsSnapshot {
|
|
89
200
|
items: PullRequest[];
|