@wascartech/devbot 0.0.0-stage → 2.1.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/LICENSE +202 -0
- package/README.md +638 -2
- package/dist/access-grant-store.js +99 -0
- package/dist/access-grant-store.js.map +1 -0
- package/dist/access-resolve.js +11 -0
- package/dist/access-resolve.js.map +1 -0
- package/dist/access-rule-store.js +99 -0
- package/dist/access-rule-store.js.map +1 -0
- package/dist/admin/access-routes.js +73 -0
- package/dist/admin/access-routes.js.map +1 -0
- package/dist/admin/access-rule-routes.js +107 -0
- package/dist/admin/access-rule-routes.js.map +1 -0
- package/dist/admin/custom-repos-routes.js +93 -0
- package/dist/admin/custom-repos-routes.js.map +1 -0
- package/dist/admin/env-routes.js +74 -0
- package/dist/admin/env-routes.js.map +1 -0
- package/dist/admin/global-settings-routes.js +254 -0
- package/dist/admin/global-settings-routes.js.map +1 -0
- package/dist/admin/mcp-cleanup.js +12 -0
- package/dist/admin/mcp-cleanup.js.map +1 -0
- package/dist/admin/mcp-routes.js +169 -0
- package/dist/admin/mcp-routes.js.map +1 -0
- package/dist/admin/query-params.js +80 -0
- package/dist/admin/query-params.js.map +1 -0
- package/dist/admin/routes.js +150 -0
- package/dist/admin/routes.js.map +1 -0
- package/dist/admin/run-history-routes.js +44 -0
- package/dist/admin/run-history-routes.js.map +1 -0
- package/dist/admin/run-routes.js +99 -0
- package/dist/admin/run-routes.js.map +1 -0
- package/dist/admin/settings-routes.js +119 -0
- package/dist/admin/settings-routes.js.map +1 -0
- package/dist/admin/stats-routes.js +51 -0
- package/dist/admin/stats-routes.js.map +1 -0
- package/dist/admin/task-routes.js +213 -0
- package/dist/admin/task-routes.js.map +1 -0
- package/dist/admin/test-routes.js +38 -0
- package/dist/admin/test-routes.js.map +1 -0
- package/dist/admin/volume-routes.js +82 -0
- package/dist/admin/volume-routes.js.map +1 -0
- package/dist/admin/webhook-routes.js +174 -0
- package/dist/admin/webhook-routes.js.map +1 -0
- package/dist/agents.js +48 -0
- package/dist/agents.js.map +1 -0
- package/dist/assignee-value.js +6 -0
- package/dist/assignee-value.js.map +1 -0
- package/dist/attachments.js +76 -0
- package/dist/attachments.js.map +1 -0
- package/dist/auto-commands.js +88 -0
- package/dist/auto-commands.js.map +1 -0
- package/dist/auto-features.js +32 -0
- package/dist/auto-features.js.map +1 -0
- package/dist/base-branch-store.js +40 -0
- package/dist/base-branch-store.js.map +1 -0
- package/dist/base-branches.js +9 -0
- package/dist/base-branches.js.map +1 -0
- package/dist/build-workflow.js +116 -0
- package/dist/build-workflow.js.map +1 -0
- package/dist/change-request-lifecycle.js +16 -0
- package/dist/change-request-lifecycle.js.map +1 -0
- package/dist/change-request-store.js +72 -0
- package/dist/change-request-store.js.map +1 -0
- package/dist/ci-failure.js +80 -0
- package/dist/ci-failure.js.map +1 -0
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -0
- package/dist/conflict-fix.js +178 -0
- package/dist/conflict-fix.js.map +1 -0
- package/dist/cookie.js +70 -0
- package/dist/cookie.js.map +1 -0
- package/dist/crypto-util.js +40 -0
- package/dist/crypto-util.js.map +1 -0
- package/dist/custom-repos-store.js +90 -0
- package/dist/custom-repos-store.js.map +1 -0
- package/dist/custom-repos-sync.js +118 -0
- package/dist/custom-repos-sync.js.map +1 -0
- package/dist/db.js +12 -0
- package/dist/db.js.map +1 -0
- package/dist/devbot-scripts.js +18 -0
- package/dist/devbot-scripts.js.map +1 -0
- package/dist/devcontainer.js +141 -0
- package/dist/devcontainer.js.map +1 -0
- package/dist/env-config-store.js +132 -0
- package/dist/env-config-store.js.map +1 -0
- package/dist/error-log-store.js +193 -0
- package/dist/error-log-store.js.map +1 -0
- package/dist/git.js +605 -0
- package/dist/git.js.map +1 -0
- package/dist/global-queue.js +127 -0
- package/dist/global-queue.js.map +1 -0
- package/dist/global-settings-store.js +307 -0
- package/dist/global-settings-store.js.map +1 -0
- package/dist/help.js +41 -0
- package/dist/help.js.map +1 -0
- package/dist/http-csp.js +15 -0
- package/dist/http-csp.js.map +1 -0
- package/dist/http-util.js +40 -0
- package/dist/http-util.js.map +1 -0
- package/dist/idempotency.js +50 -0
- package/dist/idempotency.js.map +1 -0
- package/dist/lifecycle.js +234 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/logger.js +33 -0
- package/dist/logger.js.map +1 -0
- package/dist/lsp-servers.js +81 -0
- package/dist/lsp-servers.js.map +1 -0
- package/dist/mcp/auth.js +62 -0
- package/dist/mcp/auth.js.map +1 -0
- package/dist/mcp/effective-mcp.js +42 -0
- package/dist/mcp/effective-mcp.js.map +1 -0
- package/dist/mcp/oauth-refresh.js +138 -0
- package/dist/mcp/oauth-refresh.js.map +1 -0
- package/dist/mcp/peer-sync.js +109 -0
- package/dist/mcp/peer-sync.js.map +1 -0
- package/dist/mcp/registry.js +54 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/runner-bridge.js +93 -0
- package/dist/mcp/runner-bridge.js.map +1 -0
- package/dist/mcp/server.js +173 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/_helpers.js +88 -0
- package/dist/mcp/tools/_helpers.js.map +1 -0
- package/dist/mcp/tools/attachments.js +117 -0
- package/dist/mcp/tools/attachments.js.map +1 -0
- package/dist/mcp/tools/cicd.js +105 -0
- package/dist/mcp/tools/cicd.js.map +1 -0
- package/dist/mcp/tools/discovery.js +34 -0
- package/dist/mcp/tools/discovery.js.map +1 -0
- package/dist/mcp/tools/issues.js +56 -0
- package/dist/mcp/tools/issues.js.map +1 -0
- package/dist/mcp/tools/merge_requests.js +67 -0
- package/dist/mcp/tools/merge_requests.js.map +1 -0
- package/dist/mcp/tools/metadata.js +127 -0
- package/dist/mcp/tools/metadata.js.map +1 -0
- package/dist/mcp/tools/peer_sync.js +43 -0
- package/dist/mcp/tools/peer_sync.js.map +1 -0
- package/dist/mcp/tools/repository.js +178 -0
- package/dist/mcp/tools/repository.js.map +1 -0
- package/dist/mcp/tools/work_tracking.js +125 -0
- package/dist/mcp/tools/work_tracking.js.map +1 -0
- package/dist/mcp/tools/workitems.js +30 -0
- package/dist/mcp/tools/workitems.js.map +1 -0
- package/dist/mcp/volume-files.js +187 -0
- package/dist/mcp/volume-files.js.map +1 -0
- package/dist/mcp-auth-store.js +134 -0
- package/dist/mcp-auth-store.js.map +1 -0
- package/dist/mcp-config-store.js +83 -0
- package/dist/mcp-config-store.js.map +1 -0
- package/dist/mention.js +512 -0
- package/dist/mention.js.map +1 -0
- package/dist/migrate.js +73 -0
- package/dist/migrate.js.map +1 -0
- package/dist/mr-assignee.js +71 -0
- package/dist/mr-assignee.js.map +1 -0
- package/dist/mr-content.js +90 -0
- package/dist/mr-content.js.map +1 -0
- package/dist/oauth-routes.js +54 -0
- package/dist/oauth-routes.js.map +1 -0
- package/dist/onboarding-allowlist.js +32 -0
- package/dist/onboarding-allowlist.js.map +1 -0
- package/dist/opencode.js +291 -0
- package/dist/opencode.js.map +1 -0
- package/dist/outbound-webhook-store.js +229 -0
- package/dist/outbound-webhook-store.js.map +1 -0
- package/dist/outbound-webhook.js +314 -0
- package/dist/outbound-webhook.js.map +1 -0
- package/dist/path-sandbox.js +200 -0
- package/dist/path-sandbox.js.map +1 -0
- package/dist/platform/git-auth.js +34 -0
- package/dist/platform/git-auth.js.map +1 -0
- package/dist/platform/gitealike/attachments.js +62 -0
- package/dist/platform/gitealike/attachments.js.map +1 -0
- package/dist/platform/gitealike/base.js +935 -0
- package/dist/platform/gitealike/base.js.map +1 -0
- package/dist/platform/gitealike/forgejo.js +16 -0
- package/dist/platform/gitealike/forgejo.js.map +1 -0
- package/dist/platform/gitealike/gitea.js +16 -0
- package/dist/platform/gitealike/gitea.js.map +1 -0
- package/dist/platform/gitealike/http.js +152 -0
- package/dist/platform/gitealike/http.js.map +1 -0
- package/dist/platform/gitealike/schemas.js +284 -0
- package/dist/platform/gitealike/schemas.js.map +1 -0
- package/dist/platform/github/attachments.js +52 -0
- package/dist/platform/github/attachments.js.map +1 -0
- package/dist/platform/github/http.js +153 -0
- package/dist/platform/github/http.js.map +1 -0
- package/dist/platform/github/index.js +936 -0
- package/dist/platform/github/index.js.map +1 -0
- package/dist/platform/github/schemas.js +308 -0
- package/dist/platform/github/schemas.js.map +1 -0
- package/dist/platform/github/zip.js +85 -0
- package/dist/platform/github/zip.js.map +1 -0
- package/dist/platform/gitlab/admin.js +105 -0
- package/dist/platform/gitlab/admin.js.map +1 -0
- package/dist/platform/gitlab/api.js +229 -0
- package/dist/platform/gitlab/api.js.map +1 -0
- package/dist/platform/gitlab/attachments.js +79 -0
- package/dist/platform/gitlab/attachments.js.map +1 -0
- package/dist/platform/gitlab/http.js +165 -0
- package/dist/platform/gitlab/http.js.map +1 -0
- package/dist/platform/gitlab/index.js +630 -0
- package/dist/platform/gitlab/index.js.map +1 -0
- package/dist/platform/gitlab/oauth.js +58 -0
- package/dist/platform/gitlab/oauth.js.map +1 -0
- package/dist/platform/gitlab/read.js +182 -0
- package/dist/platform/gitlab/read.js.map +1 -0
- package/dist/platform/gitlab/schemas-read.js +274 -0
- package/dist/platform/gitlab/schemas-read.js.map +1 -0
- package/dist/platform/gitlab/schemas.js +251 -0
- package/dist/platform/gitlab/schemas.js.map +1 -0
- package/dist/platform/gitlab/signature.js +52 -0
- package/dist/platform/gitlab/signature.js.map +1 -0
- package/dist/platform/index.js +38 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/port.js +26 -0
- package/dist/platform/port.js.map +1 -0
- package/dist/platform/types.js +80 -0
- package/dist/platform/types.js.map +1 -0
- package/dist/podman.js +119 -0
- package/dist/podman.js.map +1 -0
- package/dist/project-sync.js +69 -0
- package/dist/project-sync.js.map +1 -0
- package/dist/prompt.js +47 -0
- package/dist/prompt.js.map +1 -0
- package/dist/queue-store.js +236 -0
- package/dist/queue-store.js.map +1 -0
- package/dist/queue.js +129 -0
- package/dist/queue.js.map +1 -0
- package/dist/redact.js +23 -0
- package/dist/redact.js.map +1 -0
- package/dist/run-files.js +297 -0
- package/dist/run-files.js.map +1 -0
- package/dist/run-filters.js +54 -0
- package/dist/run-filters.js.map +1 -0
- package/dist/run-history-store.js +229 -0
- package/dist/run-history-store.js.map +1 -0
- package/dist/run-log-sink.js +270 -0
- package/dist/run-log-sink.js.map +1 -0
- package/dist/run-log.js +97 -0
- package/dist/run-log.js.map +1 -0
- package/dist/run-usage.js +29 -0
- package/dist/run-usage.js.map +1 -0
- package/dist/run-view.js +112 -0
- package/dist/run-view.js.map +1 -0
- package/dist/runner.js +1094 -0
- package/dist/runner.js.map +1 -0
- package/dist/runtime-apply.js +26 -0
- package/dist/runtime-apply.js.map +1 -0
- package/dist/runtime-settings.js +71 -0
- package/dist/runtime-settings.js.map +1 -0
- package/dist/runtime-state.js +19 -0
- package/dist/runtime-state.js.map +1 -0
- package/dist/server.js +119 -0
- package/dist/server.js.map +1 -0
- package/dist/settings-store.js +320 -0
- package/dist/settings-store.js.map +1 -0
- package/dist/status.js +121 -0
- package/dist/status.js.map +1 -0
- package/dist/stop.js +56 -0
- package/dist/stop.js.map +1 -0
- package/dist/sweeps.js +87 -0
- package/dist/sweeps.js.map +1 -0
- package/dist/task-log.js +279 -0
- package/dist/task-log.js.map +1 -0
- package/dist/task-view.js +62 -0
- package/dist/task-view.js.map +1 -0
- package/dist/token-store.js +68 -0
- package/dist/token-store.js.map +1 -0
- package/dist/types/access.js +74 -0
- package/dist/types/access.js.map +1 -0
- package/dist/types/custom-repos.js +28 -0
- package/dist/types/custom-repos.js.map +1 -0
- package/dist/types/env-config.js +25 -0
- package/dist/types/env-config.js.map +1 -0
- package/dist/types/env.js +190 -0
- package/dist/types/env.js.map +1 -0
- package/dist/types/global-settings.js +178 -0
- package/dist/types/global-settings.js.map +1 -0
- package/dist/types/lsp-servers.js +145 -0
- package/dist/types/lsp-servers.js.map +1 -0
- package/dist/types/mcp-config.js +77 -0
- package/dist/types/mcp-config.js.map +1 -0
- package/dist/types/opencode.js +59 -0
- package/dist/types/opencode.js.map +1 -0
- package/dist/types/outbound-webhook.js +56 -0
- package/dist/types/outbound-webhook.js.map +1 -0
- package/dist/types/project-settings.js +114 -0
- package/dist/types/project-settings.js.map +1 -0
- package/dist/types/provider-registry.js +37 -0
- package/dist/types/provider-registry.js.map +1 -0
- package/dist/types/runtime-settings.js +78 -0
- package/dist/types/runtime-settings.js.map +1 -0
- package/dist/usage-stats.js +159 -0
- package/dist/usage-stats.js.map +1 -0
- package/dist/version.js +19 -0
- package/dist/version.js.map +1 -0
- package/dist/volume-gc.js +193 -0
- package/dist/volume-gc.js.map +1 -0
- package/dist/volume-manage.js +191 -0
- package/dist/volume-manage.js.map +1 -0
- package/dist/volume-store.js +122 -0
- package/dist/volume-store.js.map +1 -0
- package/dist/webhook.js +1106 -0
- package/dist/webhook.js.map +1 -0
- package/dist/work-item-auto-store.js +75 -0
- package/dist/work-item-auto-store.js.map +1 -0
- package/dist/work-item-branch-store.js +37 -0
- package/dist/work-item-branch-store.js.map +1 -0
- package/migrations/0001_initial.sql +59 -0
- package/migrations/0002_queue_status.sql +15 -0
- package/migrations/0003_work_item_base_branch.sql +14 -0
- package/migrations/0004_project_settings.sql +15 -0
- package/migrations/0005_global_settings.sql +34 -0
- package/migrations/0006_model_variants.sql +8 -0
- package/migrations/0007_container_error_logs.sql +21 -0
- package/migrations/0008_project_access_grants.sql +16 -0
- package/migrations/0009_drop_imported_legacy.sql +4 -0
- package/migrations/0010_container_error_log_model.sql +6 -0
- package/migrations/0011_container_error_log_title.sql +5 -0
- package/migrations/0012_pending_task_cancel.sql +6 -0
- package/migrations/0013_builder_image.sql +6 -0
- package/migrations/0014_build_workflow.sql +7 -0
- package/migrations/0015_access_rules.sql +24 -0
- package/migrations/0016_trigger_policy.sql +17 -0
- package/migrations/0017_attachment_upload.sql +8 -0
- package/migrations/0018_work_item_branch.sql +11 -0
- package/migrations/0019_auto_push_mr.sql +18 -0
- package/migrations/0020_outbound_webhooks.sql +47 -0
- package/migrations/0021_runtime_settings.sql +12 -0
- package/migrations/0022_auto_resolve_conflicts.sql +17 -0
- package/migrations/0023_ci_fail_auto_report.sql +27 -0
- package/migrations/0024_work_item_auto_override.sql +22 -0
- package/migrations/0025_run_history.sql +37 -0
- package/migrations/0026_run_history_task_seq.sql +6 -0
- package/migrations/0027_custom_repos.sql +11 -0
- package/migrations/0028_run_usage.sql +14 -0
- package/migrations/0029_drop_ocr_langs.sql +6 -0
- package/migrations/0030_mr_assignee.sql +9 -0
- package/migrations/0031_lsp_servers.sql +14 -0
- package/opencode-config/managed/devbot-agent-policy.md +61 -0
- package/opencode-config/managed/opencode.json +77 -0
- package/opencode-config/opencode.json +211 -0
- package/opencode-config/plugins/devbot-path-guard.js +224 -0
- package/package.json +157 -4
- package/public/assets/DashboardSidebarCollapse-rIuzCmVm.js +1 -0
- package/public/assets/DashboardToolbar-DFCUqZ4Z.js +1 -0
- package/public/assets/ErrorLogModal.vue_vue_type_script_setup_true_lang-BCyNIf1E.js +1 -0
- package/public/assets/ErrorLogsPage-DyYK2Rop.js +1 -0
- package/public/assets/LogSlideover.vue_vue_type_script_setup_true_lang-33xie7TE.js +1 -0
- package/public/assets/OverviewPage-CFfa0uwg.js +1 -0
- package/public/assets/PageGrid-CBROIU87.js +1 -0
- package/public/assets/PeriodRangePicker.vue_vue_type_script_setup_true_lang-DiFUNem7.js +1 -0
- package/public/assets/ProjectDetailPage-CreyvUit.js +1 -0
- package/public/assets/ProjectsPage-CFx8-elJ.js +1 -0
- package/public/assets/RunDetailSlideover.vue_vue_type_script_setup_true_lang-DopYYmCT.js +1 -0
- package/public/assets/RunsPage-CRnnXU4P.js +1 -0
- package/public/assets/Select-Bvx32Diz.js +1 -0
- package/public/assets/SelectMenu-BjMxc4VB.js +1 -0
- package/public/assets/SettingsPage-Bb6LM3wO.js +60 -0
- package/public/assets/TimeCell.vue_vue_type_script_setup_true_lang-DW_UB0Fu.js +1 -0
- package/public/assets/UsagePage-BLMDEsv-.js +332 -0
- package/public/assets/UsagePage-DodEeAjB.css +1 -0
- package/public/assets/VolumesPage-CxcLc3L2.js +1 -0
- package/public/assets/WebhookConfigPanel.vue_vue_type_script_setup_true_lang-B2V2GF6b.js +1 -0
- package/public/assets/WorkItemCell.vue_vue_type_script_setup_true_lang-BQn6vTjd.js +1 -0
- package/public/assets/index-BMbMibyb.js +4 -0
- package/public/assets/index-C5RBBrPj.js +30 -0
- package/public/assets/index-CgX29UgC.css +1 -0
- package/public/assets/usage-format-jsb31_O8.js +1 -0
- package/public/assets/useManagedProjects-8rtjRqVJ.js +1 -0
- package/public/assets/useRouteTab-DfwrcMic.js +1 -0
- package/public/favicon.ico +0 -0
- package/public/favicon.png +0 -0
- package/public/index.html +15 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../../src/platform/gitlab/admin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { NoteSchema, IssueNoteSchema, MergeRequestSchema, IssueDetailSchema, IssueListItemSchema, MergeRequestListItemSchema, ProjectMemberSchema, UserLookupSchema, DiscussionSchema, MergeRequestDiscussionSchema, } from "./schemas.js";
|
|
2
|
+
import { gitlabRequest, gitlabRequestArray, GITLAB_API } from "./http.js";
|
|
3
|
+
import { config } from "../../config.js";
|
|
4
|
+
import { log } from "../../logger.js";
|
|
5
|
+
const BOT = { kind: "bot" };
|
|
6
|
+
export function postNote(projectId, iid, body) {
|
|
7
|
+
// ponytail: GitLab routes issue-type work item notes through the Issues API
|
|
8
|
+
// (/projects/:id/issues/:iid/notes). The Work Items API notes endpoint
|
|
9
|
+
// (/projects/:id/work_items/:iid/notes) 404s on this instance even for
|
|
10
|
+
// issue-type work items (verified on GitLab 19.2). The webhook fires with
|
|
11
|
+
// noteable_type "Issue" and the issue's _links.notes points here, so this
|
|
12
|
+
// is the correct path for every work item this bot handles today. Switch
|
|
13
|
+
// to a type-dispatched call if/when this bot handles non-issue work item
|
|
14
|
+
// types (epic/objective/etc.) that genuinely need the Work Items API.
|
|
15
|
+
return gitlabRequest(`/projects/${projectId}/issues/${iid}/notes`, {
|
|
16
|
+
method: "POST",
|
|
17
|
+
body: JSON.stringify({ body }),
|
|
18
|
+
}, NoteSchema, BOT);
|
|
19
|
+
}
|
|
20
|
+
export async function listIssueNotes(projectId, iid) {
|
|
21
|
+
// ponytail: per_page=100 + no pagination loop. 100 is the API max; a work
|
|
22
|
+
// item crossing that is rare for this bot — walk X-Next-Page if one ever
|
|
23
|
+
// does. activity_filter=only_comments drops system notes (label/state/
|
|
24
|
+
// milestone changes) server-side, so no client-side system filter needed.
|
|
25
|
+
// sort=asc gives chronological order for the transcript.
|
|
26
|
+
return gitlabRequestArray(`/projects/${projectId}/issues/${iid}/notes?sort=asc&per_page=100&activity_filter=only_comments`, { method: "GET" }, IssueNoteSchema, BOT);
|
|
27
|
+
}
|
|
28
|
+
export function createMergeRequest(projectId, body) {
|
|
29
|
+
return gitlabRequest(`/projects/${projectId}/merge_requests`, {
|
|
30
|
+
method: "POST",
|
|
31
|
+
body: JSON.stringify(body),
|
|
32
|
+
}, MergeRequestSchema, BOT);
|
|
33
|
+
}
|
|
34
|
+
export function updateMergeRequest(projectId, mrIid, body) {
|
|
35
|
+
return gitlabRequest(`/projects/${projectId}/merge_requests/${mrIid}`, {
|
|
36
|
+
method: "PUT",
|
|
37
|
+
body: JSON.stringify(body),
|
|
38
|
+
}, MergeRequestSchema, BOT);
|
|
39
|
+
}
|
|
40
|
+
// GET /projects/:id/issues/:iid. Used by the /reset authorization check to
|
|
41
|
+
// read the issue's current author + assignees (live, at reset time).
|
|
42
|
+
export function fetchIssue(projectId, iid) {
|
|
43
|
+
return gitlabRequest(`/projects/${projectId}/issues/${iid}`, { method: "GET" }, IssueDetailSchema, BOT);
|
|
44
|
+
}
|
|
45
|
+
// GET /projects/:id/members/all/:user_id — inherited membership, resolves
|
|
46
|
+
// group-level roles. Like the throwing variant below but maps a 404 (not a
|
|
47
|
+
// member) to null so the caller can distinguish "no role" from a lookup
|
|
48
|
+
// failure. Non-404 errors throw (fail-closed). Raw fetch so a 404 does not
|
|
49
|
+
// throw. Used by the trigger-authorization gate.
|
|
50
|
+
export async function fetchProjectMemberOrNull(projectId, userId) {
|
|
51
|
+
const url = `${GITLAB_API}/projects/${projectId}/members/all/${userId}`;
|
|
52
|
+
const res = await fetch(url, { headers: { "PRIVATE-TOKEN": config.PLATFORM_TOKEN } });
|
|
53
|
+
if (res.status === 404)
|
|
54
|
+
return null;
|
|
55
|
+
if (!res.ok) {
|
|
56
|
+
const body = await res.text();
|
|
57
|
+
throw new Error(`GitLab ${res.status} ${url}: ${body}`);
|
|
58
|
+
}
|
|
59
|
+
const parsed = ProjectMemberSchema.safeParse(await res.json());
|
|
60
|
+
if (!parsed.success) {
|
|
61
|
+
log.error("gitlab response schema mismatch", { url, issues: parsed.error.issues });
|
|
62
|
+
throw new Error(`GitLab schema mismatch for ${url}`);
|
|
63
|
+
}
|
|
64
|
+
return parsed.data;
|
|
65
|
+
}
|
|
66
|
+
// GET /users?username=<login> — resolve a username to its stable numeric id.
|
|
67
|
+
// Exact match (case-insensitive) is required: GitLab's search is prefix-based,
|
|
68
|
+
// so "alice" also matches "alice-bot". Returns null on no exact match. This is
|
|
69
|
+
// the single forge-coupling point for access-rule add; when the Platform port
|
|
70
|
+
// lands (wi-19), this becomes a port method (GitLab/ForgeJo/Gitea/GitHub each
|
|
71
|
+
// implement resolveUser) and this function is replaced by that call.
|
|
72
|
+
export async function findUserByUsername(username) {
|
|
73
|
+
const target = username.trim().toLowerCase();
|
|
74
|
+
if (!target)
|
|
75
|
+
return null;
|
|
76
|
+
const users = await gitlabRequest(`/users?username=${encodeURIComponent(username.trim())}`, { method: "GET" }, UserLookupSchema.array(), BOT);
|
|
77
|
+
return users.find((u) => u.username.toLowerCase() === target) ?? null;
|
|
78
|
+
}
|
|
79
|
+
// Map a triggering note id → its discussion id, so a Step-0 error reply can be
|
|
80
|
+
// posted in the same thread as the mention. Walks
|
|
81
|
+
// GET /projects/:id/issues/:iid/discussions paginated (per_page=100), capped
|
|
82
|
+
// at ~10 pages. Returns the discussion id whose notes[].id === noteId, or
|
|
83
|
+
// null on miss/exhaustion/error. Errors are swallowed (null) — the caller
|
|
84
|
+
// falls back to a top-level note; never throws.
|
|
85
|
+
export async function findNoteDiscussionId(projectId, iid, noteId) {
|
|
86
|
+
const MAX_PAGES = 10;
|
|
87
|
+
try {
|
|
88
|
+
for (let page = 1; page <= MAX_PAGES; page++) {
|
|
89
|
+
const discussions = await gitlabRequestArray(`/projects/${projectId}/issues/${iid}/discussions?per_page=100&page=${page}`, { method: "GET" }, DiscussionSchema, BOT);
|
|
90
|
+
if (discussions.length === 0)
|
|
91
|
+
break;
|
|
92
|
+
const hit = discussions.find((d) => d.notes.some((n) => n.id === noteId));
|
|
93
|
+
if (hit)
|
|
94
|
+
return hit.id;
|
|
95
|
+
if (discussions.length < 100)
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
log.warn("findNoteDiscussionId failed", { projectId, iid, noteId, err: e });
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
// POST /projects/:id/issues/:iid/discussions/:discussion_id/notes — reply in
|
|
105
|
+
// the same thread as the triggering note.
|
|
106
|
+
export function postDiscussionReply(projectId, iid, discussionId, body) {
|
|
107
|
+
return gitlabRequest(`/projects/${projectId}/issues/${iid}/discussions/${discussionId}/notes`, { method: "POST", body: JSON.stringify({ body }) }, NoteSchema, BOT);
|
|
108
|
+
}
|
|
109
|
+
// Post a Step-0 error reply. If triggeringNoteId is set, resolve its discussion
|
|
110
|
+
// and reply in-thread; on miss/error fall back to a top-level note. If
|
|
111
|
+
// triggeringNoteId is undefined (e.g. work-item-creation mention), post
|
|
112
|
+
// top-level directly. Swallows + logs internal errors — never throws. A
|
|
113
|
+
// silent drop would be worse than a top-level fallback for an error message.
|
|
114
|
+
export async function postErrorReply(projectId, iid, triggeringNoteId, body) {
|
|
115
|
+
try {
|
|
116
|
+
if (triggeringNoteId !== undefined) {
|
|
117
|
+
const discussionId = await findNoteDiscussionId(projectId, iid, triggeringNoteId);
|
|
118
|
+
if (discussionId) {
|
|
119
|
+
await postDiscussionReply(projectId, iid, discussionId, body);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
await postNote(projectId, iid, body);
|
|
124
|
+
}
|
|
125
|
+
catch (e) {
|
|
126
|
+
log.warn("postErrorReply failed", { projectId, iid, triggeringNoteId, err: e });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// GET /projects/:id/repository/branches/:branch — verifies a /base <branch>
|
|
130
|
+
// exists on the remote before the first-run clone tries it. Returns true on
|
|
131
|
+
// 200, false on 404 (branch missing), rethrows on other statuses (fail-closed:
|
|
132
|
+
// a 5xx during the gate denies the mention rather than dispatching a run that
|
|
133
|
+
// would clone off the wrong base). Direct fetch (not gitlabVoid, which returns
|
|
134
|
+
// void) so the boolean result is preserved. Branch name is URL-encoded per
|
|
135
|
+
// GitLab's path-param rule (slashes in branch names like release/2.0 must be
|
|
136
|
+
// encoded so the path segment isn't split).
|
|
137
|
+
export async function branchExists(projectId, branch) {
|
|
138
|
+
const url = `${GITLAB_API}/projects/${projectId}/repository/branches/${encodeURIComponent(branch)}`;
|
|
139
|
+
const res = await fetch(url, { headers: { "PRIVATE-TOKEN": config.PLATFORM_TOKEN } });
|
|
140
|
+
if (res.status === 404)
|
|
141
|
+
return false;
|
|
142
|
+
if (!res.ok) {
|
|
143
|
+
const body = await res.text();
|
|
144
|
+
throw new Error(`GitLab ${res.status} ${url}: ${body}`);
|
|
145
|
+
}
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
// GET /projects/:id/issues/:iid — return just the work item's state, or null
|
|
149
|
+
// when the work item no longer exists (404 / deleted). Used by the volume GC
|
|
150
|
+
// liveness pass to reclaim volumes for closed or deleted work items instead
|
|
151
|
+
// of waiting out the inactivity TTL. A deleted work item can never run again,
|
|
152
|
+
// so its volume is freed immediately; closed items are freed to match the
|
|
153
|
+
// close-hook behavior. Non-404 errors throw (fail-closed: the sweep leaves
|
|
154
|
+
// the row for the TTL path rather than purging on an unverifiable read).
|
|
155
|
+
// Raw fetch (not gitlabRequest) so a 404 maps to null instead of a throw.
|
|
156
|
+
export async function fetchIssueStateOrNull(projectId, iid) {
|
|
157
|
+
const url = `${GITLAB_API}/projects/${projectId}/issues/${iid}`;
|
|
158
|
+
const res = await fetch(url, { headers: { "PRIVATE-TOKEN": config.PLATFORM_TOKEN } });
|
|
159
|
+
if (res.status === 404)
|
|
160
|
+
return null;
|
|
161
|
+
if (!res.ok) {
|
|
162
|
+
const body = await res.text();
|
|
163
|
+
throw new Error(`GitLab ${res.status} ${url}: ${body}`);
|
|
164
|
+
}
|
|
165
|
+
const json = (await res.json());
|
|
166
|
+
return json.state === "opened" || json.state === "closed" ? json.state : null;
|
|
167
|
+
}
|
|
168
|
+
// Walk a list of branch names in order; return the first that exists remotely,
|
|
169
|
+
// or null if none do. Used to resolve the BASE_BRANCHES env fallback (and is
|
|
170
|
+
// the engine behind both the clone slot-2 target and the build-mode mrTarget
|
|
171
|
+
// when no /base was set for the work item). 5xx on any branch rethrows
|
|
172
|
+
// (fail-closed, consistent with the /base Step-0 gate) — the caller treats a
|
|
173
|
+
// throw as "none verifiable" and posts a retry note rather than silently
|
|
174
|
+
// skipping an unverifiable branch. 404 on a branch is the normal "try next"
|
|
175
|
+
// signal, not an error.
|
|
176
|
+
export async function firstExistingBranch(projectId, branches) {
|
|
177
|
+
for (const b of branches) {
|
|
178
|
+
if (await branchExists(projectId, b))
|
|
179
|
+
return b;
|
|
180
|
+
}
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
// ponytail: per_page=100 + no pagination walk. A project crossing 100 open
|
|
184
|
+
// issues is rare for this bot's scope; walk X-Next-Page if one ever does.
|
|
185
|
+
export async function listIssues(projectId, opts = {}) {
|
|
186
|
+
const params = new URLSearchParams();
|
|
187
|
+
params.set("scope", "all");
|
|
188
|
+
if (opts.state)
|
|
189
|
+
params.set("state", opts.state);
|
|
190
|
+
if (opts.search)
|
|
191
|
+
params.set("search", opts.search);
|
|
192
|
+
if (opts.labels)
|
|
193
|
+
params.set("labels", opts.labels);
|
|
194
|
+
params.set("per_page", String(opts.perPage ?? 100));
|
|
195
|
+
if (opts.page)
|
|
196
|
+
params.set("page", String(opts.page));
|
|
197
|
+
return gitlabRequest(`/projects/${projectId}/issues?${params.toString()}`, { method: "GET" }, IssueListItemSchema.array(), BOT);
|
|
198
|
+
}
|
|
199
|
+
export function getIssueFull(projectId, iid) {
|
|
200
|
+
return gitlabRequest(`/projects/${projectId}/issues/${iid}`, { method: "GET" }, IssueListItemSchema, BOT);
|
|
201
|
+
}
|
|
202
|
+
export async function listMergeRequests(projectId, opts = {}) {
|
|
203
|
+
const params = new URLSearchParams();
|
|
204
|
+
if (opts.state)
|
|
205
|
+
params.set("state", opts.state);
|
|
206
|
+
if (opts.search)
|
|
207
|
+
params.set("search", opts.search);
|
|
208
|
+
if (opts.sourceBranch)
|
|
209
|
+
params.set("source_branch", opts.sourceBranch);
|
|
210
|
+
params.set("per_page", String(opts.perPage ?? 100));
|
|
211
|
+
if (opts.page)
|
|
212
|
+
params.set("page", String(opts.page));
|
|
213
|
+
return gitlabRequest(`/projects/${projectId}/merge_requests?${params.toString()}`, { method: "GET" }, MergeRequestListItemSchema.array(), BOT);
|
|
214
|
+
}
|
|
215
|
+
// GET /projects/:id/merge_requests/:iid/discussions — MR discussions include
|
|
216
|
+
// diff-anchored annotations (DiffNote with position), general threads, and
|
|
217
|
+
// system notes. Used by the get_merge_request_discussions MCP tool so an agent
|
|
218
|
+
// reviewing an MR can pull review comments as context.
|
|
219
|
+
// ponytail: per_page=100 + no pagination walk. 100 is the API max; an MR
|
|
220
|
+
// crossing that is rare — walk X-Next-Page if one ever does (page param lets
|
|
221
|
+
// the agent page further explicitly).
|
|
222
|
+
export async function listMergeRequestDiscussions(projectId, mrIid, opts = {}) {
|
|
223
|
+
const params = new URLSearchParams();
|
|
224
|
+
params.set("per_page", String(opts.perPage ?? 100));
|
|
225
|
+
if (opts.page)
|
|
226
|
+
params.set("page", String(opts.page));
|
|
227
|
+
return gitlabRequestArray(`/projects/${projectId}/merge_requests/${mrIid}/discussions?${params.toString()}`, { method: "GET" }, MergeRequestDiscussionSchema, BOT);
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/platform/gitlab/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// GitLab attachment discovery + fetch. GitLab embeds uploads as Markdown
|
|
2
|
+
// `` (relative, project upload) or
|
|
3
|
+
// `[text](<host>/uploads/...)` (absolute). Bare `/uploads/...` URLs outside
|
|
4
|
+
// markdown also appear (older clients). The secret is a 32-char hex string per
|
|
5
|
+
// GitLab's Markdown uploads API. Discovery is GitLab-specific; the extraction
|
|
6
|
+
// engine lives in ../../attachments.ts.
|
|
7
|
+
import { runtime } from "../../runtime-state.js";
|
|
8
|
+
import { gitlabFetchRaw, gitlabUpload } from "./http.js";
|
|
9
|
+
import { UploadSchema } from "./schemas.js";
|
|
10
|
+
import { MD_LINK, safeDecode, stripCodeSpans, } from "../../attachments.js";
|
|
11
|
+
const UPLOAD_PATH = /\/uploads\/([0-9a-f]{32})\/([^)\s]+)/i;
|
|
12
|
+
export function findAttachmentRefs(body) {
|
|
13
|
+
// Strip code spans so upload refs inside them aren't matched.
|
|
14
|
+
const stripped = stripCodeSpans(body);
|
|
15
|
+
const refs = [];
|
|
16
|
+
const seen = new Set();
|
|
17
|
+
// Markdown image/link form first:  and [text](url).
|
|
18
|
+
for (const m of stripped.matchAll(MD_LINK)) {
|
|
19
|
+
const url = m[2] ?? "";
|
|
20
|
+
const hit = UPLOAD_PATH.exec(url);
|
|
21
|
+
if (!hit)
|
|
22
|
+
continue;
|
|
23
|
+
const secret = hit[1] ?? "";
|
|
24
|
+
const filename = safeDecode(hit[2] ?? "");
|
|
25
|
+
if (!secret)
|
|
26
|
+
continue;
|
|
27
|
+
const key = `${secret}/${filename}`;
|
|
28
|
+
if (seen.has(key))
|
|
29
|
+
continue;
|
|
30
|
+
seen.add(key);
|
|
31
|
+
refs.push({
|
|
32
|
+
raw: m[0] ?? "",
|
|
33
|
+
secret,
|
|
34
|
+
filename,
|
|
35
|
+
absolute: /^https?:\/\//i.test(url),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
// Bare `/uploads/...` URLs not wrapped in markdown (older clients). Avoid
|
|
39
|
+
// double-counting ones already captured by a markdown link above.
|
|
40
|
+
for (const m of stripped.matchAll(new RegExp(UPLOAD_PATH.source, "g"))) {
|
|
41
|
+
const secret = m[1] ?? "";
|
|
42
|
+
const filename = safeDecode(m[2] ?? "");
|
|
43
|
+
if (!secret)
|
|
44
|
+
continue;
|
|
45
|
+
const key = `${secret}/${filename}`;
|
|
46
|
+
if (seen.has(key))
|
|
47
|
+
continue;
|
|
48
|
+
seen.add(key);
|
|
49
|
+
refs.push({
|
|
50
|
+
raw: m[0] ?? "",
|
|
51
|
+
secret,
|
|
52
|
+
filename,
|
|
53
|
+
absolute: false,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return refs;
|
|
57
|
+
}
|
|
58
|
+
/** Fetch one GitLab upload's full bytes. */
|
|
59
|
+
export async function downloadAttachment(projectId, ref) {
|
|
60
|
+
// GitLab's download-by-secret endpoint: GET /projects/:id/uploads/:secret/:filename.
|
|
61
|
+
// Works for both relative (project) and absolute (host-prefixed) refs — the
|
|
62
|
+
// endpoint path is the same; the host is in config.PLATFORM_URL.
|
|
63
|
+
const path = `/projects/${projectId}/uploads/${ref.secret}/${encodeURIComponent(ref.filename)}`;
|
|
64
|
+
const { bytes, contentType } = await gitlabFetchRaw(path, { kind: "bot" }, runtime().attachmentMaxBytes);
|
|
65
|
+
return { bytes, contentType };
|
|
66
|
+
}
|
|
67
|
+
// Outbound upload via the Markdown uploads API. GitLab accepts multipart field
|
|
68
|
+
// `file` at POST /projects/:id/uploads and returns the server-rendered markdown.
|
|
69
|
+
export async function uploadAttachment(projectId, file) {
|
|
70
|
+
const form = new FormData();
|
|
71
|
+
form.append("file", new Blob([file.bytes], { type: file.contentType }), file.filename);
|
|
72
|
+
const r = await gitlabUpload(`/projects/${projectId}/uploads`, form, UploadSchema, { kind: "bot" });
|
|
73
|
+
return {
|
|
74
|
+
markdown: r.markdown,
|
|
75
|
+
url: r.full_path ?? r.url,
|
|
76
|
+
filename: file.filename,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=attachments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../../src/platform/gitlab/attachments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { log } from "../../logger.js";
|
|
2
|
+
import { config } from "../../config.js";
|
|
3
|
+
import { TailAccumulator } from "../types.js";
|
|
4
|
+
const API = `${config.PLATFORM_URL.replace(/\/$/, "")}/api/v4`;
|
|
5
|
+
// Schema-validated fetch with consistent error handling. Returns parsed data
|
|
6
|
+
// or throws a generic Error (schema details stay server-side in logs).
|
|
7
|
+
export async function gitlabRequest(path, init, schema, auth) {
|
|
8
|
+
const url = path.startsWith("http") ? path : `${API}${path}`;
|
|
9
|
+
const headers = {
|
|
10
|
+
"Content-Type": "application/json",
|
|
11
|
+
...(auth.kind === "bot"
|
|
12
|
+
? { "PRIVATE-TOKEN": config.PLATFORM_TOKEN }
|
|
13
|
+
: { Authorization: `Bearer ${auth.token}` }),
|
|
14
|
+
};
|
|
15
|
+
const res = await fetch(url, { ...init, headers });
|
|
16
|
+
if (!res.ok) {
|
|
17
|
+
const body = await res.text();
|
|
18
|
+
throw new Error(`GitLab ${res.status} ${url}: ${body}`);
|
|
19
|
+
}
|
|
20
|
+
const json = await res.json();
|
|
21
|
+
const parsed = schema.safeParse(json);
|
|
22
|
+
if (!parsed.success) {
|
|
23
|
+
log.error("gitlab response schema mismatch", { url, issues: parsed.error.issues });
|
|
24
|
+
throw new Error(`GitLab schema mismatch for ${url}`);
|
|
25
|
+
}
|
|
26
|
+
return parsed.data;
|
|
27
|
+
}
|
|
28
|
+
// Array variant — GitLab list endpoints return an array; non-array responses
|
|
29
|
+
// are treated as a schema mismatch (same as returning [] today, but now throws
|
|
30
|
+
// instead of silently returning empty — matches the Tier 1 fix for gitlab.ts).
|
|
31
|
+
export async function gitlabRequestArray(path, init, schema, auth) {
|
|
32
|
+
const url = path.startsWith("http") ? path : `${API}${path}`;
|
|
33
|
+
const headers = {
|
|
34
|
+
"Content-Type": "application/json",
|
|
35
|
+
...(auth.kind === "bot"
|
|
36
|
+
? { "PRIVATE-TOKEN": config.PLATFORM_TOKEN }
|
|
37
|
+
: { Authorization: `Bearer ${auth.token}` }),
|
|
38
|
+
};
|
|
39
|
+
const res = await fetch(url, { ...init, headers });
|
|
40
|
+
if (!res.ok) {
|
|
41
|
+
const body = await res.text();
|
|
42
|
+
throw new Error(`GitLab ${res.status} ${url}: ${body}`);
|
|
43
|
+
}
|
|
44
|
+
const json = await res.json();
|
|
45
|
+
if (!Array.isArray(json)) {
|
|
46
|
+
log.error("gitlab expected array response", { url });
|
|
47
|
+
throw new Error(`GitLab expected array response from ${url}`);
|
|
48
|
+
}
|
|
49
|
+
const parsed = schema.array().safeParse(json);
|
|
50
|
+
if (!parsed.success) {
|
|
51
|
+
log.error("gitlab response schema mismatch", { url, issues: parsed.error.issues });
|
|
52
|
+
throw new Error(`GitLab schema mismatch for ${url}`);
|
|
53
|
+
}
|
|
54
|
+
return parsed.data;
|
|
55
|
+
}
|
|
56
|
+
// Raw-bytes variant — binary download (attachment bytes), no JSON parse.
|
|
57
|
+
// Returns the bytes + Content-Type. Honors `maxBytes` by aborting the body
|
|
58
|
+
// stream past the limit (avoids downloading a 200MB PDF just to reject it);
|
|
59
|
+
// throws an OversizedError when the cap is exceeded so the caller can classify
|
|
60
|
+
// the rejection (oversized is user-actionable, distinct from a fetch failure).
|
|
61
|
+
// Not used for the JSON endpoints above; those stay schema-validated.
|
|
62
|
+
export class OversizedError extends Error {
|
|
63
|
+
bytesSoFar;
|
|
64
|
+
maxBytes;
|
|
65
|
+
constructor(bytesSoFar, maxBytes) {
|
|
66
|
+
super(`attachment exceeds ${maxBytes} bytes (got ${bytesSoFar})`);
|
|
67
|
+
this.name = "OversizedError";
|
|
68
|
+
this.bytesSoFar = bytesSoFar;
|
|
69
|
+
this.maxBytes = maxBytes;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// `overflow` controls what happens past `maxBytes`:
|
|
73
|
+
// "abort" (default) — cancel the stream and throw OversizedError (attachments:
|
|
74
|
+
// an over-cap attachment is rejected, not partially read).
|
|
75
|
+
// "tail" — keep reading and retain only the last maxBytes (job logs: the
|
|
76
|
+
// failure is at the end, so the tail is what matters). Bounded memory.
|
|
77
|
+
export async function gitlabFetchRaw(path, auth, maxBytes, overflow = "abort") {
|
|
78
|
+
const url = path.startsWith("http") ? path : `${API}${path}`;
|
|
79
|
+
const headers = {
|
|
80
|
+
...(auth.kind === "bot"
|
|
81
|
+
? { "PRIVATE-TOKEN": config.PLATFORM_TOKEN }
|
|
82
|
+
: { Authorization: `Bearer ${auth.token}` }),
|
|
83
|
+
};
|
|
84
|
+
const res = await fetch(url, { method: "GET", headers });
|
|
85
|
+
if (!res.ok) {
|
|
86
|
+
const body = await res.text();
|
|
87
|
+
throw new Error(`GitLab ${res.status} ${url}: ${body}`);
|
|
88
|
+
}
|
|
89
|
+
const contentType = res.headers.get("content-type") ?? "application/octet-stream";
|
|
90
|
+
if (res.body === null) {
|
|
91
|
+
return { bytes: Buffer.alloc(0), contentType, totalBytes: 0 };
|
|
92
|
+
}
|
|
93
|
+
const reader = res.body.getReader();
|
|
94
|
+
if (overflow === "tail") {
|
|
95
|
+
const acc = new TailAccumulator(maxBytes);
|
|
96
|
+
for (;;) {
|
|
97
|
+
const { done, value } = await reader.read();
|
|
98
|
+
if (done)
|
|
99
|
+
break;
|
|
100
|
+
if (value)
|
|
101
|
+
acc.push(value);
|
|
102
|
+
}
|
|
103
|
+
return { ...acc.result(), contentType };
|
|
104
|
+
}
|
|
105
|
+
const chunks = [];
|
|
106
|
+
let total = 0;
|
|
107
|
+
for (;;) {
|
|
108
|
+
const { done, value } = await reader.read();
|
|
109
|
+
if (done)
|
|
110
|
+
break;
|
|
111
|
+
if (value) {
|
|
112
|
+
total += value.byteLength;
|
|
113
|
+
if (total > maxBytes) {
|
|
114
|
+
await reader.cancel().catch(() => { });
|
|
115
|
+
throw new OversizedError(total, maxBytes);
|
|
116
|
+
}
|
|
117
|
+
chunks.push(Buffer.from(value));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const bytes = Buffer.concat(chunks);
|
|
121
|
+
return { bytes, contentType, totalBytes: bytes.byteLength };
|
|
122
|
+
}
|
|
123
|
+
// Void variant — same fetch+error handling, no schema, for calls that return
|
|
124
|
+
// no body (DELETE, PUT, POST with 409/404-as-success). okStatuses lets callers
|
|
125
|
+
// accept specific non-2xx statuses as success (e.g. [409] for "already a member",
|
|
126
|
+
// [404] for "already deleted").
|
|
127
|
+
export async function gitlabVoid(path, init, auth, opts = {}) {
|
|
128
|
+
const url = path.startsWith("http") ? path : `${API}${path}`;
|
|
129
|
+
const headers = {
|
|
130
|
+
"Content-Type": "application/json",
|
|
131
|
+
...(auth.kind === "bot"
|
|
132
|
+
? { "PRIVATE-TOKEN": config.PLATFORM_TOKEN }
|
|
133
|
+
: { Authorization: `Bearer ${auth.token}` }),
|
|
134
|
+
};
|
|
135
|
+
const res = await fetch(url, { ...init, headers });
|
|
136
|
+
if (opts.okStatuses?.includes(res.status))
|
|
137
|
+
return;
|
|
138
|
+
if (!res.ok) {
|
|
139
|
+
const body = await res.text();
|
|
140
|
+
throw new Error(`GitLab ${res.status} ${url}: ${body}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Multipart upload variant — schema-validated JSON response. The caller passes a
|
|
144
|
+
// prebuilt FormData; we must NOT set Content-Type so fetch adds the multipart
|
|
145
|
+
// boundary. Auth is header-only (same as the JSON helpers).
|
|
146
|
+
export async function gitlabUpload(path, form, schema, auth) {
|
|
147
|
+
const url = path.startsWith("http") ? path : `${API}${path}`;
|
|
148
|
+
const headers = auth.kind === "bot"
|
|
149
|
+
? { "PRIVATE-TOKEN": config.PLATFORM_TOKEN }
|
|
150
|
+
: { Authorization: `Bearer ${auth.token}` };
|
|
151
|
+
const res = await fetch(url, { method: "POST", headers, body: form });
|
|
152
|
+
if (!res.ok) {
|
|
153
|
+
const body = await res.text();
|
|
154
|
+
throw new Error(`GitLab ${res.status} ${url}: ${body}`);
|
|
155
|
+
}
|
|
156
|
+
const json = await res.json();
|
|
157
|
+
const parsed = schema.safeParse(json);
|
|
158
|
+
if (!parsed.success) {
|
|
159
|
+
log.error("gitlab upload response schema mismatch", { url, issues: parsed.error.issues });
|
|
160
|
+
throw new Error(`GitLab schema mismatch for ${url}`);
|
|
161
|
+
}
|
|
162
|
+
return parsed.data;
|
|
163
|
+
}
|
|
164
|
+
export { API as GITLAB_API };
|
|
165
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/platform/gitlab/http.ts"],"names":[],"mappings":"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"}
|