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 { dirname } from "path";
import fs from "fs"; import fs from "fs";
import path from "path"; 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 * Read version from package.json
*/ */
@ -826,19 +826,139 @@ async function getProject(projectId, options = {}) {
* @returns {Promise<GitLabProject[]>} List of projects * @returns {Promise<GitLabProject[]>} List of projects
*/ */
async function listProjects(options = {}) { async function listProjects(options = {}) {
const url = new URL(`${GITLAB_API_URL}/projects`); // Construct the query parameters
// Add all the query parameters from options 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]) => { Object.entries(options).forEach(([key, value]) => {
if (value !== undefined) { 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(), { const response = await fetch(url.toString(), {
headers: DEFAULT_HEADERS, headers: DEFAULT_HEADERS,
}); });
// Handle errors
await handleGitLabError(response); await handleGitLabError(response);
// Parse and return the data
const data = await response.json(); 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 () => { server.setRequestHandler(ListToolsRequestSchema, async () => {
return { return {
@ -973,6 +1093,31 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
description: "List projects accessible by the current user", description: "List projects accessible by the current user",
inputSchema: zodToJsonSchema(ListProjectsSchema), 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": { case "list_projects": {
const args = ListProjectsSchema.parse(request.params.arguments); const args = ListProjectsSchema.parse(request.params.arguments);
const url = new URL(`${GITLAB_API_URL}/projects`); const projects = await listProjects(args);
// 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);
return { return {
content: [{ type: "text", text: JSON.stringify(projects, null, 2) }], 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) }], 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: default:
throw new Error(`Unknown tool: ${request.params.name}`); throw new Error(`Unknown tool: ${request.params.name}`);
} }

View File

@ -207,7 +207,15 @@ export const GitLabLabelSchema = z.object({
id: z.number(), id: z.number(),
name: z.string(), name: z.string(),
color: z.string(), color: z.string(),
description: z.string().optional(), text_color: z.string(),
description: z.string().nullable(),
description_html: z.string().nullable(),
open_issues_count: z.number().optional(),
closed_issues_count: z.number().optional(),
open_merge_requests_count: z.number().optional(),
subscribed: z.boolean().optional(),
priority: z.number().nullable().optional(),
is_project_label: z.boolean().optional(),
}); });
export const GitLabUserSchema = z.object({ export const GitLabUserSchema = z.object({
username: z.string(), // Changed from login to match GitLab API username: z.string(), // Changed from login to match GitLab API
@ -295,7 +303,7 @@ export const GitLabMergeRequestSchema = z.object({
assignees: z.array(GitLabUserSchema).optional(), assignees: z.array(GitLabUserSchema).optional(),
source_branch: z.string(), source_branch: z.string(),
target_branch: z.string(), target_branch: z.string(),
diff_refs: GitLabMergeRequestDiffRefSchema.optional(), diff_refs: GitLabMergeRequestDiffRefSchema.nullable().optional(),
web_url: z.string(), web_url: z.string(),
created_at: z.string(), created_at: z.string(),
updated_at: z.string(), updated_at: z.string(),
@ -308,10 +316,10 @@ export const GitLabMergeRequestSchema = z.object({
work_in_progress: z.boolean().optional(), work_in_progress: z.boolean().optional(),
blocking_discussions_resolved: z.boolean().optional(), blocking_discussions_resolved: z.boolean().optional(),
should_remove_source_branch: z.boolean().nullable().optional(), should_remove_source_branch: z.boolean().nullable().optional(),
force_remove_source_branch: z.boolean().optional(), force_remove_source_branch: z.boolean().nullable().optional(),
allow_collaboration: z.boolean().optional(), allow_collaboration: z.boolean().optional(),
allow_maintainer_to_push: z.boolean().optional(), allow_maintainer_to_push: z.boolean().optional(),
changes_count: z.string().optional(), changes_count: z.string().nullable().optional(),
merge_when_pipeline_succeeds: z.boolean().optional(), merge_when_pipeline_succeeds: z.boolean().optional(),
squash: z.boolean().optional(), squash: z.boolean().optional(),
labels: z.array(z.string()).optional(), labels: z.array(z.string()).optional(),
@ -558,3 +566,34 @@ export const ListProjectsSchema = z.object({
with_merge_requests_enabled: z.boolean().optional().describe("Filter projects with merge requests feature enabled"), with_merge_requests_enabled: z.boolean().optional().describe("Filter projects with merge requests feature enabled"),
min_access_level: z.number().optional().describe("Filter by minimum access level"), min_access_level: z.number().optional().describe("Filter by minimum access level"),
}); });
// Label operation schemas
export const ListLabelsSchema = z.object({
project_id: z.string().describe("Project ID or URL-encoded path"),
with_counts: z.boolean().optional().describe("Whether or not to include issue and merge request counts"),
include_ancestor_groups: z.boolean().optional().describe("Include ancestor groups"),
search: z.string().optional().describe("Keyword to filter labels by"),
});
export const GetLabelSchema = z.object({
project_id: z.string().describe("Project ID or URL-encoded path"),
label_id: z.union([z.number(), z.string()]).describe("The ID or title of a project's label"),
include_ancestor_groups: z.boolean().optional().describe("Include ancestor groups"),
});
export const CreateLabelSchema = z.object({
project_id: z.string().describe("Project ID or URL-encoded path"),
name: z.string().describe("The name of the label"),
color: z.string().describe("The color of the label given in 6-digit hex notation with leading '#' sign"),
description: z.string().optional().describe("The description of the label"),
priority: z.number().nullable().optional().describe("The priority of the label"),
});
export const UpdateLabelSchema = z.object({
project_id: z.string().describe("Project ID or URL-encoded path"),
label_id: z.union([z.number(), z.string()]).describe("The ID or title of a project's label"),
new_name: z.string().optional().describe("The new name of the label"),
color: z.string().optional().describe("The color of the label given in 6-digit hex notation with leading '#' sign"),
description: z.string().optional().describe("The new description of the label"),
priority: z.number().nullable().optional().describe("The new priority of the label"),
});
export const DeleteLabelSchema = z.object({
project_id: z.string().describe("Project ID or URL-encoded path"),
label_id: z.union([z.number(), z.string()]).describe("The ID or title of a project's label"),
});

54
build/test-note.js Normal file
View File

@ -0,0 +1,54 @@
/**
* This test file verifies that the createNote function works correctly
* with the fixed endpoint URL construction that uses plural resource names
* (issues instead of issue, merge_requests instead of merge_request).
*/
import fetch from "node-fetch";
// GitLab API configuration (replace with actual values when testing)
const GITLAB_API_URL = process.env.GITLAB_API_URL || "https://gitlab.com";
const GITLAB_PERSONAL_ACCESS_TOKEN = process.env.GITLAB_TOKEN || "";
const PROJECT_ID = process.env.PROJECT_ID || "your/project";
const ISSUE_IID = Number(process.env.ISSUE_IID || "1");
async function testCreateIssueNote() {
try {
// Using plural form "issues" in the URL
const url = new URL(`${GITLAB_API_URL}/api/v4/projects/${encodeURIComponent(PROJECT_ID)}/issues/${ISSUE_IID}/notes`);
const response = await fetch(url.toString(), {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
},
body: JSON.stringify({ body: "Test note from API - with plural endpoint" }),
});
if (!response.ok) {
const errorBody = await response.text();
throw new Error(`GitLab API error: ${response.status} ${response.statusText}\n${errorBody}`);
}
const data = await response.json();
console.log("Successfully created note:");
console.log(JSON.stringify(data, null, 2));
return true;
}
catch (error) {
console.error("Error creating note:", error);
return false;
}
}
// Only run the test if executed directly
if (require.main === module) {
console.log("Testing note creation with plural 'issues' endpoint...");
testCreateIssueNote().then(success => {
if (success) {
console.log("✅ Test successful!");
process.exit(0);
}
else {
console.log("❌ Test failed!");
process.exit(1);
}
});
}
// Export for use in other tests
export { testCreateIssueNote };

311
package-lock.json generated
View File

@ -1,26 +1,29 @@
{ {
"name": "@modelcontextprotocol/server-gitlab", "name": "@zereight/mcp-gitlab",
"version": "0.6.2", "version": "1.0.20",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@modelcontextprotocol/server-gitlab", "name": "@zereight/mcp-gitlab",
"version": "0.6.2", "version": "1.0.20",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@modelcontextprotocol/sdk": "1.0.1", "@modelcontextprotocol/sdk": "1.0.1",
"@types/node-fetch": "^2.6.12", "@types/node-fetch": "^2.6.12",
"dotenv": "^16.4.7",
"node-fetch": "^3.3.2", "node-fetch": "^3.3.2",
"zod-to-json-schema": "^3.23.5" "zod-to-json-schema": "^3.23.5"
}, },
"bin": { "bin": {
"mcp-server-gitlab": "build/index.js" "mcp-gitlab": "build/index.js"
}, },
"devDependencies": { "devDependencies": {
"shx": "^0.3.4", "@types/node": "^22.13.10",
"typescript": "^5.6.2" "typescript": "^5.8.2",
"zod": "3.21.4"
},
"engines": {
"node": ">=14"
} }
}, },
"node_modules/@modelcontextprotocol/sdk": { "node_modules/@modelcontextprotocol/sdk": {
@ -34,10 +37,19 @@
"zod": "^3.23.8" "zod": "^3.23.8"
} }
}, },
"node_modules/@modelcontextprotocol/sdk/node_modules/zod": {
"version": "3.24.2",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz",
"integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.13.1", "version": "22.13.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz",
"integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==", "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~6.20.0" "undici-types": "~6.20.0"
@ -59,24 +71,6 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
"license": "MIT"
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/bytes": { "node_modules/bytes": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@ -98,13 +92,6 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true,
"license": "MIT"
},
"node_modules/content-type": { "node_modules/content-type": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
@ -141,18 +128,6 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/dotenv": {
"version": "16.4.7",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
"integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://dotenvx.com"
}
},
"node_modules/fetch-blob": { "node_modules/fetch-blob": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
@ -202,58 +177,6 @@
"node": ">=12.20.0" "node": ">=12.20.0"
} }
}, },
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true,
"license": "ISC"
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"dev": true,
"license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/http-errors": { "node_modules/http-errors": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@ -282,50 +205,12 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
"dev": true,
"license": "ISC",
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"node_modules/inherits": { "node_modules/inherits": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/interpret": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
"integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/is-core-module": {
"version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
"dev": true,
"license": "MIT",
"dependencies": {
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/mime-db": { "node_modules/mime-db": {
"version": "1.52.0", "version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@ -347,29 +232,6 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/node-domexception": { "node_modules/node-domexception": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
@ -407,33 +269,6 @@
"url": "https://opencollective.com/node-fetch" "url": "https://opencollective.com/node-fetch"
} }
}, },
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"license": "ISC",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true,
"license": "MIT"
},
"node_modules/raw-body": { "node_modules/raw-body": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
@ -449,39 +284,6 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/rechoir": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
"integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
"dev": true,
"dependencies": {
"resolve": "^1.1.6"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/resolve": {
"version": "1.22.10",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
"integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-core-module": "^2.16.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/safer-buffer": { "node_modules/safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
@ -494,41 +296,6 @@
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/shelljs": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz",
"integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"glob": "^7.0.0",
"interpret": "^1.0.0",
"rechoir": "^0.6.2"
},
"bin": {
"shjs": "bin/shjs"
},
"engines": {
"node": ">=4"
}
},
"node_modules/shx": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz",
"integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==",
"dev": true,
"license": "MIT",
"dependencies": {
"minimist": "^1.2.3",
"shelljs": "^0.8.5"
},
"bin": {
"shx": "lib/cli.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/statuses": { "node_modules/statuses": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@ -538,19 +305,6 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/toidentifier": { "node_modules/toidentifier": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
@ -561,9 +315,9 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "5.7.3", "version": "5.8.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
"integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
@ -598,17 +352,10 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true,
"license": "ISC"
},
"node_modules/zod": { "node_modules/zod": {
"version": "3.24.1", "version": "3.21.4",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz",
"integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==",
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"url": "https://github.com/sponsors/colinhacks" "url": "https://github.com/sponsors/colinhacks"