@cat-factory/gitlab 0.1.2 → 0.1.4

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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Igor Savin
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Igor Savin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,77 @@
1
+ import type { Clock, CommitFilesResult, GitHubBranch, GitHubCheckRun, GitHubCodeSearchHit, GitHubCommit, GitHubIssue, GitHubIssueDetail, GitHubIssueSearchHit, GitHubPullRequest, GitHubRepo, ListOptions, Paged, RepoContentEntry, RepoEntry, RepoFileContent, VcsClient, VcsConnectionRef, VcsRepoRef } from '@cat-factory/kernel';
2
+ import type { CommitFilesInput, MergePullRequestInput, OpenPullRequestInput } from '@cat-factory/contracts';
3
+ import type { GitLabTokenSource } from './tokenSource.js';
4
+ export interface FetchGitLabClientDependencies {
5
+ tokenSource: GitLabTokenSource;
6
+ clock: Clock;
7
+ /** Injected for tests; defaults to the global `fetch`. */
8
+ fetchImpl?: typeof fetch;
9
+ /**
10
+ * Optional sink, warned when a listing hits the {@link MAX_PAGES} page cap with more
11
+ * results still available — so a truncated sync is surfaced rather than silently dropped
12
+ * (CLAUDE.md "no silent caps"). Defaults to no-op.
13
+ */
14
+ logger?: {
15
+ warn: (message: string) => void;
16
+ };
17
+ }
18
+ export declare class FetchGitLabClient implements VcsClient {
19
+ private readonly deps;
20
+ constructor(deps: FetchGitLabClientDependencies);
21
+ listRepos(connection: VcsConnectionRef): Promise<Paged<GitHubRepo>>;
22
+ getRepo(connection: VcsConnectionRef, ref: VcsRepoRef): Promise<GitHubRepo>;
23
+ canPush(connection: VcsConnectionRef, ref: VcsRepoRef): Promise<boolean>;
24
+ listBranches(connection: VcsConnectionRef, ref: VcsRepoRef): Promise<Paged<GitHubBranch>>;
25
+ branchHeadSha(connection: VcsConnectionRef, ref: VcsRepoRef, branch: string): Promise<string | null>;
26
+ listRootEntries(connection: VcsConnectionRef, ref: VcsRepoRef): Promise<RepoEntry[]>;
27
+ listDirectory(connection: VcsConnectionRef, ref: VcsRepoRef, path: string, gitRef?: string): Promise<RepoContentEntry[]>;
28
+ getFileContent(connection: VcsConnectionRef, ref: VcsRepoRef, path: string, gitRef?: string): Promise<RepoFileContent | null>;
29
+ listPullRequests(connection: VcsConnectionRef, ref: VcsRepoRef, opts?: ListOptions): Promise<Paged<GitHubPullRequest>>;
30
+ listIssues(connection: VcsConnectionRef, ref: VcsRepoRef, opts?: ListOptions): Promise<Paged<GitHubIssue>>;
31
+ getIssue(connection: VcsConnectionRef, ref: VcsRepoRef, issueNumber: number): Promise<GitHubIssueDetail>;
32
+ searchIssues(connection: VcsConnectionRef, query: string, limit?: number): Promise<GitHubIssueSearchHit[]>;
33
+ searchCode(): Promise<GitHubCodeSearchHit[]>;
34
+ listCommits(connection: VcsConnectionRef, ref: VcsRepoRef, opts?: ListOptions & {
35
+ sha?: string;
36
+ }): Promise<Paged<GitHubCommit>>;
37
+ listCheckRuns(connection: VcsConnectionRef, ref: VcsRepoRef, sha: string): Promise<Paged<GitHubCheckRun>>;
38
+ createBranch(connection: VcsConnectionRef, ref: VcsRepoRef, name: string, fromSha: string): Promise<void>;
39
+ commitFiles(connection: VcsConnectionRef, ref: VcsRepoRef, input: CommitFilesInput): Promise<CommitFilesResult>;
40
+ createIssue(connection: VcsConnectionRef, ref: VcsRepoRef, input: {
41
+ title: string;
42
+ body: string;
43
+ }): Promise<{
44
+ number: number;
45
+ url: string;
46
+ }>;
47
+ closeIssue(connection: VcsConnectionRef, ref: VcsRepoRef, number: number): Promise<void>;
48
+ openPullRequest(connection: VcsConnectionRef, ref: VcsRepoRef, input: OpenPullRequestInput): Promise<GitHubPullRequest>;
49
+ updatePullRequest(connection: VcsConnectionRef, ref: VcsRepoRef, number: number, patch: {
50
+ title?: string;
51
+ body?: string;
52
+ state?: 'open' | 'closed';
53
+ base?: string;
54
+ }): Promise<GitHubPullRequest>;
55
+ getPullRequestMergeability(connection: VcsConnectionRef, ref: VcsRepoRef, number: number): Promise<{
56
+ mergeable: boolean | null;
57
+ mergeableState: string;
58
+ headSha: string | null;
59
+ }>;
60
+ mergePullRequest(connection: VcsConnectionRef, ref: VcsRepoRef, number: number, input?: MergePullRequestInput): Promise<void>;
61
+ mergeBranch(_connection: VcsConnectionRef, _ref: VcsRepoRef, _input: {
62
+ base: string;
63
+ head: string;
64
+ }): Promise<'merged' | 'noop' | 'conflict'>;
65
+ deleteBranch(connection: VcsConnectionRef, ref: VcsRepoRef, branch: string): Promise<void>;
66
+ comment(connection: VcsConnectionRef, ref: VcsRepoRef, issueOrPrNumber: number, body: string): Promise<void>;
67
+ /** Resolve a project's default branch (for the files API, which needs a concrete ref). */
68
+ private defaultBranch;
69
+ private paginate;
70
+ private request;
71
+ }
72
+ /** Carries the HTTP status so callers can decide whether to retry. */
73
+ export declare class GitLabApiError extends Error {
74
+ readonly status: number;
75
+ constructor(status: number, message: string);
76
+ }
77
+ //# sourceMappingURL=FetchGitLabClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FetchGitLabClient.d.ts","sourceRoot":"","sources":["../src/FetchGitLabClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,435 @@
1
+ import { mergeabilityFromStatus, toBranchProjection, toCheckRunProjection, toCommitProjection, toIssueProjection, toMergeRequestProjection, toRepoProjection, } from './projection.js';
2
+ // ---------------------------------------------------------------------------
3
+ // Thin `fetch`-based VcsClient for GitLab (REST v4), the GitLab analogue of the
4
+ // GitHub `FetchGitHubClient`. It authenticates with a per-connection token
5
+ // (`PRIVATE-TOKEN` header), follows `Link` pagination up to a bounded number of
6
+ // pages, and maps responses to the shared projection entities via the pure mappers.
7
+ //
8
+ // Each method is keyed by a `VcsConnectionRef` (which connection's token) + a
9
+ // `VcsRepoRef` (which project). GitLab projects are addressed by their numeric id
10
+ // (the ref's `repoId`); when absent the URL-encoded `owner/repo` path is used.
11
+ // ---------------------------------------------------------------------------
12
+ const PER_PAGE = 100;
13
+ const MAX_PAGES = 10;
14
+ export class FetchGitLabClient {
15
+ deps;
16
+ constructor(deps) {
17
+ this.deps = deps;
18
+ }
19
+ // ---- reads --------------------------------------------------------------
20
+ async listRepos(connection) {
21
+ const syncedAt = this.deps.clock.now();
22
+ const numericId = connectionNumericId(connection);
23
+ const items = await this.paginate(`/projects?membership=true&per_page=${PER_PAGE}`, { connection }, (json) => json.map((p) => toRepoProjection(p, numericId, syncedAt)));
24
+ return { items };
25
+ }
26
+ async getRepo(connection, ref) {
27
+ const { json } = await this.request(`/projects/${projectPath(ref)}`, { connection });
28
+ return toRepoProjection(json, connectionNumericId(connection), this.deps.clock.now());
29
+ }
30
+ async canPush(connection, ref) {
31
+ try {
32
+ const { json } = await this.request(`/projects/${projectPath(ref)}`, { connection });
33
+ const p = json;
34
+ // GitLab access levels: 30 = Developer (can push to non-protected branches),
35
+ // 40 = Maintainer, 50 = Owner. Developer+ is enough to push a work branch.
36
+ const project = p.permissions?.project_access?.access_level ?? 0;
37
+ const group = p.permissions?.group_access?.access_level ?? 0;
38
+ return Math.max(project, group) >= 30;
39
+ }
40
+ catch (err) {
41
+ if (err instanceof GitLabApiError && (err.status === 403 || err.status === 404))
42
+ return false;
43
+ throw err;
44
+ }
45
+ }
46
+ async listBranches(connection, ref) {
47
+ const syncedAt = this.deps.clock.now();
48
+ const repoId = numericRepoId(ref);
49
+ const items = await this.paginate(`/projects/${projectPath(ref)}/repository/branches?per_page=${PER_PAGE}`, { connection }, (json) => json.map((b) => toBranchProjection(b, repoId, syncedAt)));
50
+ return { items };
51
+ }
52
+ async branchHeadSha(connection, ref, branch) {
53
+ try {
54
+ const { json } = await this.request(`/projects/${projectPath(ref)}/repository/branches/${encodeURIComponent(branch)}`, { connection });
55
+ return json.commit?.id ?? null;
56
+ }
57
+ catch (err) {
58
+ if (err instanceof GitLabApiError && err.status === 404)
59
+ return null;
60
+ throw err;
61
+ }
62
+ }
63
+ async listRootEntries(connection, ref) {
64
+ return (await this.listDirectory(connection, ref, '')).map((e) => ({
65
+ path: e.path,
66
+ type: e.type,
67
+ }));
68
+ }
69
+ async listDirectory(connection, ref, path, gitRef) {
70
+ const clean = path.replace(/^\/+|\/+$/g, '');
71
+ const params = new URLSearchParams({ per_page: String(PER_PAGE) });
72
+ if (clean)
73
+ params.set('path', clean);
74
+ if (gitRef)
75
+ params.set('ref', gitRef);
76
+ let json;
77
+ try {
78
+ ;
79
+ ({ json } = await this.request(`/projects/${projectPath(ref)}/repository/tree?${params.toString()}`, { connection }));
80
+ }
81
+ catch (err) {
82
+ if (err instanceof GitLabApiError && err.status === 404)
83
+ return [];
84
+ throw err;
85
+ }
86
+ const entries = (Array.isArray(json) ? json : []);
87
+ // GitLab tree `type` is `blob` | `tree`; normalise to the neutral file/dir vocabulary.
88
+ return entries.map((e) => ({
89
+ path: e.path ?? e.name ?? '',
90
+ name: e.name ?? (e.path ?? '').split('/').pop() ?? '',
91
+ type: e.type === 'tree' ? 'dir' : 'file',
92
+ sha: e.id ?? '',
93
+ }));
94
+ }
95
+ async getFileContent(connection, ref, path, gitRef) {
96
+ const clean = path.replace(/^\/+/, '');
97
+ // GitLab's files API REQUIRES a concrete `ref` (branch/tag/commit); unlike GitHub it
98
+ // does not default to the repo's default branch, and `HEAD` is not a reliable ref on
99
+ // every instance. Resolve the project default branch when the caller passes none.
100
+ const resolvedRef = gitRef ?? (await this.defaultBranch(connection, ref));
101
+ const params = new URLSearchParams({ ref: resolvedRef });
102
+ let json;
103
+ try {
104
+ ;
105
+ ({ json } = await this.request(`/projects/${projectPath(ref)}/repository/files/${encodeURIComponent(clean)}?${params.toString()}`, { connection }));
106
+ }
107
+ catch (err) {
108
+ if (err instanceof GitLabApiError && err.status === 404)
109
+ return null;
110
+ throw err;
111
+ }
112
+ const file = json;
113
+ if (typeof file.content !== 'string')
114
+ return null;
115
+ const content = file.encoding === 'base64' ? decodeBase64Utf8(file.content) : file.content;
116
+ return { content, sha: file.blob_id ?? '' };
117
+ }
118
+ async listPullRequests(connection, ref, opts = {}) {
119
+ const syncedAt = this.deps.clock.now();
120
+ const repoId = numericRepoId(ref);
121
+ const since = opts.since ? `&updated_after=${encodeURIComponent(opts.since)}` : '';
122
+ const items = await this.paginate(`/projects/${projectPath(ref)}/merge_requests?state=all&order_by=updated_at&sort=desc&per_page=${PER_PAGE}${since}`, { connection }, (json) => json.map((m) => toMergeRequestProjection(m, repoId, syncedAt)));
123
+ return { items };
124
+ }
125
+ async listIssues(connection, ref, opts = {}) {
126
+ const syncedAt = this.deps.clock.now();
127
+ const repoId = numericRepoId(ref);
128
+ const since = opts.since ? `&updated_after=${encodeURIComponent(opts.since)}` : '';
129
+ const items = await this.paginate(`/projects/${projectPath(ref)}/issues?scope=all&order_by=updated_at&sort=desc&per_page=${PER_PAGE}${since}`, { connection }, (json) => json.map((i) => toIssueProjection(i, repoId, syncedAt)));
130
+ return { items };
131
+ }
132
+ async getIssue(connection, ref, issueNumber) {
133
+ const base = `/projects/${projectPath(ref)}/issues/${issueNumber}`;
134
+ const { json } = await this.request(base, { connection });
135
+ const issue = (json ?? {});
136
+ const notesRes = await this.request(`${base}/notes?sort=asc&order_by=created_at&per_page=${PER_PAGE}`, {
137
+ connection,
138
+ });
139
+ const rawNotes = (notesRes.json ?? []);
140
+ return {
141
+ number: issue.iid ?? issueNumber,
142
+ title: issue.title ?? '(untitled)',
143
+ state: issue.state === 'opened' ? 'open' : 'closed',
144
+ url: issue.web_url ?? '',
145
+ author: issue.author?.username ?? null,
146
+ assignee: issue.assignee?.username ?? null,
147
+ labels: (issue.labels ?? [])
148
+ .map((l) => (typeof l === 'string' ? l : (l?.name ?? '')))
149
+ .filter(Boolean),
150
+ body: issue.description ?? '',
151
+ // Skip GitLab "system" notes (label/assignee change events) — they are not human comments.
152
+ comments: (Array.isArray(rawNotes) ? rawNotes : [])
153
+ .filter((n) => !n.system)
154
+ .map((n) => ({
155
+ author: n.author?.username ?? '',
156
+ createdAt: n.created_at ?? '',
157
+ body: n.body ?? '',
158
+ })),
159
+ };
160
+ }
161
+ async searchIssues(connection, query, limit = 20) {
162
+ const per = Math.min(Math.max(limit, 1), 100);
163
+ const { json } = await this.request(`/search?scope=issues&search=${encodeURIComponent(query)}&per_page=${per}`, { connection });
164
+ const items = (Array.isArray(json) ? json : []);
165
+ const hits = [];
166
+ for (const item of items) {
167
+ const parts = parseProjectWebUrl(item.web_url ?? '');
168
+ if (!parts)
169
+ continue;
170
+ hits.push({
171
+ owner: parts.owner,
172
+ repo: parts.repo,
173
+ number: item.iid ?? 0,
174
+ title: item.title ?? '(untitled)',
175
+ state: item.state === 'opened' ? 'open' : 'closed',
176
+ url: item.web_url ?? '',
177
+ });
178
+ }
179
+ return hits.slice(0, limit);
180
+ }
181
+ async searchCode() {
182
+ // GitLab blob (code) search needs the instance's Advanced Search (Elasticsearch) and
183
+ // does not return a usable `owner/repo/url` per hit on the basic API. The neutral
184
+ // doc-search box degrades to "no results" rather than returning misleading hits.
185
+ return [];
186
+ }
187
+ async listCommits(connection, ref, opts = {}) {
188
+ const syncedAt = this.deps.clock.now();
189
+ const repoId = numericRepoId(ref);
190
+ const since = opts.since ? `&since=${encodeURIComponent(opts.since)}` : '';
191
+ const refName = opts.sha ? `&ref_name=${encodeURIComponent(opts.sha)}` : '';
192
+ const items = await this.paginate(`/projects/${projectPath(ref)}/repository/commits?per_page=${PER_PAGE}${since}${refName}`, { connection }, (json) => json.map((c) => toCommitProjection(c, repoId, syncedAt)));
193
+ return { items };
194
+ }
195
+ async listCheckRuns(connection, ref, sha) {
196
+ const syncedAt = this.deps.clock.now();
197
+ const repoId = numericRepoId(ref);
198
+ const items = await this.paginate(`/projects/${projectPath(ref)}/repository/commits/${encodeURIComponent(sha)}/statuses?per_page=${PER_PAGE}`, { connection }, (json) => json.map((s) => toCheckRunProjection(s, repoId, syncedAt)));
199
+ return { items };
200
+ }
201
+ // ---- writes -------------------------------------------------------------
202
+ async createBranch(connection, ref, name, fromSha) {
203
+ const params = new URLSearchParams({ branch: name, ref: fromSha });
204
+ await this.request(`/projects/${projectPath(ref)}/repository/branches?${params.toString()}`, {
205
+ connection,
206
+ method: 'POST',
207
+ });
208
+ }
209
+ async commitFiles(connection, ref, input) {
210
+ // GitLab commits files atomically via a single actions[] payload. Each existing path
211
+ // is an `update`; a path that doesn't exist yet must be `create`, so probe per file
212
+ // against the parent the commit will build on: `baseSha` when the caller pinned one
213
+ // (so the create/update classification matches the parent the commit is rooted at),
214
+ // else the branch tip.
215
+ const probeRef = input.baseSha ?? input.branch;
216
+ const actions = [];
217
+ for (const file of input.files) {
218
+ const exists = (await this.getFileContent(connection, ref, file.path, probeRef)) !== null;
219
+ actions.push({
220
+ action: exists ? 'update' : 'create',
221
+ file_path: file.path,
222
+ content: file.content,
223
+ });
224
+ }
225
+ for (const path of input.deletions ?? []) {
226
+ actions.push({ action: 'delete', file_path: path });
227
+ }
228
+ const body = {
229
+ branch: input.branch,
230
+ commit_message: input.message,
231
+ actions,
232
+ };
233
+ // Pin the parent to `baseSha`: GitLab honours `start_sha` only when `branch` does not
234
+ // yet exist (it creates the branch from that commit) — for an existing branch this API
235
+ // always appends to the tip, so unlike the GitHub Git-Data path it cannot force a
236
+ // specific parent. Passing it still gives the right parent on first-commit/branch-create.
237
+ if (input.baseSha)
238
+ body.start_sha = input.baseSha;
239
+ const { json } = await this.request(`/projects/${projectPath(ref)}/repository/commits`, {
240
+ connection,
241
+ method: 'POST',
242
+ body,
243
+ });
244
+ return { sha: json.id ?? '' };
245
+ }
246
+ async createIssue(connection, ref, input) {
247
+ const params = new URLSearchParams({ title: input.title, description: input.body });
248
+ const { json } = await this.request(`/projects/${projectPath(ref)}/issues?${params.toString()}`, { connection, method: 'POST' });
249
+ const issue = (json ?? {});
250
+ return { number: issue.iid ?? 0, url: issue.web_url ?? '' };
251
+ }
252
+ async closeIssue(connection, ref, number) {
253
+ await this.request(`/projects/${projectPath(ref)}/issues/${number}?state_event=close`, {
254
+ connection,
255
+ method: 'PUT',
256
+ });
257
+ }
258
+ async openPullRequest(connection, ref, input) {
259
+ const { json } = await this.request(`/projects/${projectPath(ref)}/merge_requests`, {
260
+ connection,
261
+ method: 'POST',
262
+ body: {
263
+ source_branch: input.head,
264
+ target_branch: input.base,
265
+ title: input.title,
266
+ description: input.body ?? '',
267
+ },
268
+ });
269
+ return toMergeRequestProjection(json, numericRepoId(ref), this.deps.clock.now());
270
+ }
271
+ async updatePullRequest(connection, ref, number, patch) {
272
+ const body = {};
273
+ if (patch.title !== undefined)
274
+ body.title = patch.title;
275
+ if (patch.body !== undefined)
276
+ body.description = patch.body;
277
+ if (patch.base !== undefined)
278
+ body.target_branch = patch.base;
279
+ if (patch.state === 'closed')
280
+ body.state_event = 'close';
281
+ if (patch.state === 'open')
282
+ body.state_event = 'reopen';
283
+ const { json } = await this.request(`/projects/${projectPath(ref)}/merge_requests/${number}`, {
284
+ connection,
285
+ method: 'PUT',
286
+ body,
287
+ });
288
+ return toMergeRequestProjection(json, numericRepoId(ref), this.deps.clock.now());
289
+ }
290
+ async getPullRequestMergeability(connection, ref, number) {
291
+ const { json } = await this.request(`/projects/${projectPath(ref)}/merge_requests/${number}`, {
292
+ connection,
293
+ });
294
+ const mr = (json ?? {});
295
+ return {
296
+ ...mergeabilityFromStatus(mr.detailed_merge_status, mr.merge_status),
297
+ headSha: mr.sha ?? null,
298
+ };
299
+ }
300
+ async mergePullRequest(connection, ref, number, input) {
301
+ // GitLab's squash flag is per-merge; rebase is a separate endpoint. Map the neutral
302
+ // method: 'squash' → squash=true, else a plain merge commit.
303
+ const body = {};
304
+ if (input?.method === 'squash')
305
+ body.squash = true;
306
+ await this.request(`/projects/${projectPath(ref)}/merge_requests/${number}/merge`, {
307
+ connection,
308
+ method: 'PUT',
309
+ body,
310
+ });
311
+ }
312
+ async mergeBranch(_connection, _ref, _input) {
313
+ // GitLab has no server-side "merge branch A into branch B" endpoint (the GitHub Merges
314
+ // API analogue). The human-testing gate's "pull latest base into the branch" action is
315
+ // therefore unsupported here; surface it explicitly rather than silently no-op.
316
+ throw new GitLabApiError(501, 'mergeBranch is not supported on GitLab (no server-side branch merge API).');
317
+ }
318
+ async deleteBranch(connection, ref, branch) {
319
+ try {
320
+ await this.request(`/projects/${projectPath(ref)}/repository/branches/${encodeURIComponent(branch)}`, { connection, method: 'DELETE' });
321
+ }
322
+ catch (err) {
323
+ if (err instanceof GitLabApiError && err.status === 404)
324
+ return;
325
+ throw err;
326
+ }
327
+ }
328
+ async comment(connection, ref, issueOrPrNumber, body) {
329
+ // GitLab issues and MRs have SEPARATE iid spaces and distinct notes endpoints, so the
330
+ // neutral `comment(number)` is ambiguous. The platform uses `comment` for PR/MR
331
+ // conversation (the gates), so route to merge-request notes.
332
+ const params = new URLSearchParams({ body });
333
+ await this.request(`/projects/${projectPath(ref)}/merge_requests/${issueOrPrNumber}/notes?${params.toString()}`, { connection, method: 'POST' });
334
+ }
335
+ // ---- internals ----------------------------------------------------------
336
+ /** Resolve a project's default branch (for the files API, which needs a concrete ref). */
337
+ async defaultBranch(connection, ref) {
338
+ const repo = await this.getRepo(connection, ref);
339
+ return repo.defaultBranch ?? 'HEAD';
340
+ }
341
+ async paginate(path, opts, map) {
342
+ const all = [];
343
+ let url = path;
344
+ let page = 0;
345
+ for (; url && page < MAX_PAGES; page++) {
346
+ const response = await this.request(url, opts);
347
+ all.push(...map(response.json));
348
+ url = response.next;
349
+ }
350
+ // A `next` link still set at the cap means GitLab had more pages we did not fetch.
351
+ if (url) {
352
+ this.deps.logger?.warn(`GitLab listing truncated at MAX_PAGES=${MAX_PAGES} (~${PER_PAGE * MAX_PAGES} items) for "${path}"; remaining results were dropped.`);
353
+ }
354
+ return all;
355
+ }
356
+ async request(pathOrUrl, opts) {
357
+ const apiBase = this.deps.tokenSource.apiBase(opts.connection);
358
+ const url = pathOrUrl.startsWith('http') ? pathOrUrl : `${apiBase}${pathOrUrl}`;
359
+ const token = await this.deps.tokenSource.token(opts.connection);
360
+ const headers = {
361
+ 'private-token': token,
362
+ accept: 'application/json',
363
+ 'user-agent': 'cat-factory',
364
+ };
365
+ if (opts.body !== undefined)
366
+ headers['content-type'] = 'application/json';
367
+ const fetchImpl = this.deps.fetchImpl ?? fetch;
368
+ const res = await fetchImpl(url, {
369
+ method: opts.method ?? 'GET',
370
+ headers,
371
+ body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,
372
+ });
373
+ if (!res.ok) {
374
+ const text = await res.text().catch(() => '');
375
+ throw new GitLabApiError(res.status, `GitLab ${opts.method ?? 'GET'} ${url} → ${res.status}: ${text.slice(0, 300)}`);
376
+ }
377
+ const json = res.status === 204 ? null : await res.json().catch(() => null);
378
+ return { status: res.status, json, next: parseNextLink(res.headers.get('link')) };
379
+ }
380
+ }
381
+ /** Carries the HTTP status so callers can decide whether to retry. */
382
+ export class GitLabApiError extends Error {
383
+ status;
384
+ constructor(status, message) {
385
+ super(message);
386
+ this.status = status;
387
+ this.name = 'GitLabApiError';
388
+ }
389
+ }
390
+ /** The project segment for a path: prefer the numeric project id, else the encoded path. */
391
+ function projectPath(ref) {
392
+ if (ref.repoId && /^\d+$/.test(ref.repoId))
393
+ return ref.repoId;
394
+ return encodeURIComponent(`${ref.owner}/${ref.repo}`);
395
+ }
396
+ /** The numeric project id used to stamp projection rows (0 when the ref carries a path). */
397
+ function numericRepoId(ref) {
398
+ const n = Number(ref.repoId);
399
+ return Number.isInteger(n) ? n : 0;
400
+ }
401
+ /** A connection id stringified from a number maps back to a number for projection rows. */
402
+ function connectionNumericId(connection) {
403
+ const n = Number(connection.connectionId);
404
+ return Number.isInteger(n) ? n : 0;
405
+ }
406
+ /** Derive `{owner, repo}` from a GitLab issue/MR `web_url`. */
407
+ function parseProjectWebUrl(url) {
408
+ // e.g. https://gitlab.com/group/sub/project/-/issues/12
409
+ const m = url.match(/^https?:\/\/[^/]+\/(.+?)\/-\/(?:issues|merge_requests)\//);
410
+ if (!m)
411
+ return null;
412
+ const full = m[1];
413
+ const idx = full.lastIndexOf('/');
414
+ if (idx < 0)
415
+ return { owner: '', repo: full };
416
+ return { owner: full.slice(0, idx), repo: full.slice(idx + 1) };
417
+ }
418
+ function decodeBase64Utf8(value) {
419
+ const binary = atob(value.replace(/\s+/g, ''));
420
+ const bytes = new Uint8Array(binary.length);
421
+ for (let i = 0; i < binary.length; i++)
422
+ bytes[i] = binary.charCodeAt(i);
423
+ return new TextDecoder().decode(bytes);
424
+ }
425
+ function parseNextLink(link) {
426
+ if (!link)
427
+ return undefined;
428
+ for (const part of link.split(',')) {
429
+ const match = part.match(/<([^>]+)>\s*;\s*rel="next"/);
430
+ if (match)
431
+ return match[1];
432
+ }
433
+ return undefined;
434
+ }
435
+ //# sourceMappingURL=FetchGitLabClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FetchGitLabClient.js","sourceRoot":"","sources":["../src/FetchGitLabClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type Clock } from '@cat-factory/kernel';
2
+ import type { GitLabTokenSource } from './tokenSource.js';
3
+ export { FetchGitLabClient, GitLabApiError } from './FetchGitLabClient.js';
4
+ export type { FetchGitLabClientDependencies } from './FetchGitLabClient.js';
5
+ export { GitLabProvisioningClient } from './provisioning.js';
6
+ export type { GitLabProvisioningDependencies } from './provisioning.js';
7
+ export { GitLabWebhookMapper, GitLabWebhookVerifier } from './webhook.js';
8
+ export { type GitLabTokenSource, StaticGitLabTokenSource, GITLAB_PUBLIC_API_BASE, } from './tokenSource.js';
9
+ export * as gitlabProjection from './projection.js';
10
+ export interface RegisterGitLabOptions {
11
+ tokenSource: GitLabTokenSource;
12
+ clock: Clock;
13
+ /** The shared webhook secret compared against the `X-Gitlab-Token` header. */
14
+ webhookSecret?: string;
15
+ /** Injected for tests; defaults to the global `fetch`. */
16
+ fetchImpl?: typeof fetch;
17
+ /** Optional sink warned when a listing is truncated at the page cap. */
18
+ logger?: {
19
+ warn: (message: string) => void;
20
+ };
21
+ }
22
+ /**
23
+ * Register the GitLab provider bundle (client + webhook verifier/mapper + provisioning)
24
+ * in the process-wide VCS registry. Call once at startup. Idempotent — a later call
25
+ * replaces the earlier registration.
26
+ */
27
+ export declare function registerGitLab(options: RegisterGitLabOptions): void;
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAIrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAUzD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAC1E,YAAY,EAAE,6BAA6B,EAAE,MAAM,wBAAwB,CAAA;AAC3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAC5D,YAAY,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAA;AACvE,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AACzE,OAAO,EACL,KAAK,iBAAiB,EACtB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,gBAAgB,MAAM,iBAAiB,CAAA;AAEnD,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,iBAAiB,CAAA;IAC9B,KAAK,EAAE,KAAK,CAAA;IACZ,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACxB,wEAAwE;IACxE,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAA;CAC7C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CASnE"}