Build upd.

This commit is contained in:
Rudolf Raevskiy
2025-03-20 14:25:52 +01:00
parent 0e0b5c897e
commit 5d1040141d
4 changed files with 313 additions and 304 deletions

View File

@ -9,7 +9,7 @@ import { fileURLToPath } from "url";
import { dirname } from "path";
import fs from "fs";
import path from "path";
import { GitLabForkSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabIssueSchema, GitLabMergeRequestSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabSearchResponseSchema, GitLabTreeSchema, GitLabCommitSchema, GitLabNamespaceSchema, GitLabNamespaceExistsResponseSchema, GitLabProjectSchema, CreateOrUpdateFileSchema, SearchRepositoriesSchema, CreateRepositorySchema, GetFileContentsSchema, PushFilesSchema, CreateIssueSchema, CreateMergeRequestSchema, ForkRepositorySchema, CreateBranchSchema, GitLabMergeRequestDiffSchema, GetMergeRequestSchema, GetMergeRequestDiffsSchema, UpdateMergeRequestSchema, ListIssuesSchema, GetIssueSchema, UpdateIssueSchema, DeleteIssueSchema, GitLabIssueLinkSchema, GitLabIssueWithLinkDetailsSchema, ListIssueLinksSchema, GetIssueLinkSchema, CreateIssueLinkSchema, DeleteIssueLinkSchema, ListNamespacesSchema, GetNamespaceSchema, VerifyNamespaceSchema, GetProjectSchema, ListProjectsSchema, CreateNoteSchema, } from "./schemas.js";
import { GitLabForkSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabIssueSchema, GitLabMergeRequestSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabSearchResponseSchema, GitLabTreeSchema, GitLabCommitSchema, GitLabNamespaceSchema, GitLabNamespaceExistsResponseSchema, GitLabProjectSchema, CreateOrUpdateFileSchema, SearchRepositoriesSchema, CreateRepositorySchema, GetFileContentsSchema, PushFilesSchema, CreateIssueSchema, CreateMergeRequestSchema, ForkRepositorySchema, CreateBranchSchema, GitLabMergeRequestDiffSchema, GetMergeRequestSchema, GetMergeRequestDiffsSchema, UpdateMergeRequestSchema, ListIssuesSchema, GetIssueSchema, UpdateIssueSchema, DeleteIssueSchema, GitLabIssueLinkSchema, GitLabIssueWithLinkDetailsSchema, ListIssueLinksSchema, GetIssueLinkSchema, CreateIssueLinkSchema, DeleteIssueLinkSchema, ListNamespacesSchema, GetNamespaceSchema, VerifyNamespaceSchema, GetProjectSchema, ListProjectsSchema, ListLabelsSchema, GetLabelSchema, CreateLabelSchema, UpdateLabelSchema, DeleteLabelSchema, CreateNoteSchema, } from "./schemas.js";
/**
* Read version from package.json
*/
@ -826,19 +826,139 @@ async function getProject(projectId, options = {}) {
* @returns {Promise<GitLabProject[]>} List of projects
*/
async function listProjects(options = {}) {
const url = new URL(`${GITLAB_API_URL}/projects`);
// Add all the query parameters from options
// Construct the query parameters
const params = new URLSearchParams();
for (const [key, value] of Object.entries(options)) {
if (value !== undefined && value !== null) {
if (typeof value === "boolean") {
params.append(key, value ? "true" : "false");
}
else {
params.append(key, String(value));
}
}
}
// Make the API request
const response = await fetch(`${GITLAB_API_URL}/projects?${params.toString()}`, {
method: "GET",
headers: DEFAULT_HEADERS,
});
// Handle errors
await handleGitLabError(response);
// Parse and return the data
const data = await response.json();
return z.array(GitLabProjectSchema).parse(data);
}
/**
* List labels for a project
*
* @param projectId The ID or URL-encoded path of the project
* @param options Optional parameters for listing labels
* @returns Array of GitLab labels
*/
async function listLabels(projectId, options = {}) {
// Construct the URL with project path
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels`);
// Add query parameters
Object.entries(options).forEach(([key, value]) => {
if (value !== undefined) {
url.searchParams.append(key, value.toString());
if (typeof value === "boolean") {
url.searchParams.append(key, value ? "true" : "false");
}
else {
url.searchParams.append(key, String(value));
}
}
});
// Make the API request
const response = await fetch(url.toString(), {
headers: DEFAULT_HEADERS,
});
// Handle errors
await handleGitLabError(response);
// Parse and return the data
const data = await response.json();
return z.array(GitLabRepositorySchema).parse(data);
return data;
}
/**
* Get a single label from a project
*
* @param projectId The ID or URL-encoded path of the project
* @param labelId The ID or name of the label
* @param includeAncestorGroups Whether to include ancestor groups
* @returns GitLab label
*/
async function getLabel(projectId, labelId, includeAncestorGroups) {
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels/${encodeURIComponent(String(labelId))}`);
// Add query parameters
if (includeAncestorGroups !== undefined) {
url.searchParams.append("include_ancestor_groups", includeAncestorGroups ? "true" : "false");
}
// Make the API request
const response = await fetch(url.toString(), {
headers: DEFAULT_HEADERS,
});
// Handle errors
await handleGitLabError(response);
// Parse and return the data
const data = await response.json();
return data;
}
/**
* Create a new label in a project
*
* @param projectId The ID or URL-encoded path of the project
* @param options Options for creating the label
* @returns Created GitLab label
*/
async function createLabel(projectId, options) {
// Make the API request
const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels`, {
method: "POST",
headers: DEFAULT_HEADERS,
body: JSON.stringify(options),
});
// Handle errors
await handleGitLabError(response);
// Parse and return the data
const data = await response.json();
return data;
}
/**
* Update an existing label in a project
*
* @param projectId The ID or URL-encoded path of the project
* @param labelId The ID or name of the label to update
* @param options Options for updating the label
* @returns Updated GitLab label
*/
async function updateLabel(projectId, labelId, options) {
// Make the API request
const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels/${encodeURIComponent(String(labelId))}`, {
method: "PUT",
headers: DEFAULT_HEADERS,
body: JSON.stringify(options),
});
// Handle errors
await handleGitLabError(response);
// Parse and return the data
const data = await response.json();
return data;
}
/**
* Delete a label from a project
*
* @param projectId The ID or URL-encoded path of the project
* @param labelId The ID or name of the label to delete
*/
async function deleteLabel(projectId, labelId) {
// Make the API request
const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels/${encodeURIComponent(String(labelId))}`, {
method: "DELETE",
headers: DEFAULT_HEADERS,
});
// Handle errors
await handleGitLabError(response);
}
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
@ -973,6 +1093,31 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
description: "List projects accessible by the current user",
inputSchema: zodToJsonSchema(ListProjectsSchema),
},
{
name: "list_labels",
description: "List labels for a project",
inputSchema: zodToJsonSchema(ListLabelsSchema),
},
{
name: "get_label",
description: "Get a single label from a project",
inputSchema: zodToJsonSchema(GetLabelSchema),
},
{
name: "create_label",
description: "Create a new label in a project",
inputSchema: zodToJsonSchema(CreateLabelSchema),
},
{
name: "update_label",
description: "Update an existing label in a project",
inputSchema: zodToJsonSchema(UpdateLabelSchema),
},
{
name: "delete_label",
description: "Delete a label from a project",
inputSchema: zodToJsonSchema(DeleteLabelSchema),
},
],
};
});
@ -1162,19 +1307,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
}
case "list_projects": {
const args = ListProjectsSchema.parse(request.params.arguments);
const url = new URL(`${GITLAB_API_URL}/projects`);
// Add query parameters for filtering
Object.entries(args).forEach(([key, value]) => {
if (value !== undefined) {
url.searchParams.append(key, value.toString());
}
});
const response = await fetch(url.toString(), {
headers: DEFAULT_HEADERS,
});
await handleGitLabError(response);
const data = await response.json();
const projects = z.array(GitLabProjectSchema).parse(data);
const projects = await listProjects(args);
return {
content: [{ type: "text", text: JSON.stringify(projects, null, 2) }],
};
@ -1245,6 +1378,42 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
content: [{ type: "text", text: JSON.stringify({ status: "success", message: "Issue link deleted successfully" }, null, 2) }],
};
}
case "list_labels": {
const args = ListLabelsSchema.parse(request.params.arguments);
const labels = await listLabels(args.project_id, args);
return {
content: [{ type: "text", text: JSON.stringify(labels, null, 2) }],
};
}
case "get_label": {
const args = GetLabelSchema.parse(request.params.arguments);
const label = await getLabel(args.project_id, args.label_id, args.include_ancestor_groups);
return {
content: [{ type: "text", text: JSON.stringify(label, null, 2) }],
};
}
case "create_label": {
const args = CreateLabelSchema.parse(request.params.arguments);
const label = await createLabel(args.project_id, args);
return {
content: [{ type: "text", text: JSON.stringify(label, null, 2) }],
};
}
case "update_label": {
const args = UpdateLabelSchema.parse(request.params.arguments);
const { project_id, label_id, ...options } = args;
const label = await updateLabel(project_id, label_id, options);
return {
content: [{ type: "text", text: JSON.stringify(label, null, 2) }],
};
}
case "delete_label": {
const args = DeleteLabelSchema.parse(request.params.arguments);
await deleteLabel(args.project_id, args.label_id);
return {
content: [{ type: "text", text: JSON.stringify({ status: "success", message: "Label deleted successfully" }, null, 2) }],
};
}
default:
throw new Error(`Unknown tool: ${request.params.name}`);
}