feat(mcp): expand Vikunja server with project, delete, and comment tools
All checks were successful
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 2s
Monorepo Pipeline / 🧪 Test (push) Successful in 1m20s
Monorepo Pipeline / 🏗️ Build (push) Successful in 3m3s
Monorepo Pipeline / 🧹 Lint (push) Successful in 3m13s
Monorepo Pipeline / 🚀 Release (push) Has been skipped
Monorepo Pipeline / 🐳 Build Gatekeeper (Product) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Build-Base (push) Has been skipped
Monorepo Pipeline / 🐳 Build Production Runtime (push) Has been skipped
All checks were successful
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 2s
Monorepo Pipeline / 🧪 Test (push) Successful in 1m20s
Monorepo Pipeline / 🏗️ Build (push) Successful in 3m3s
Monorepo Pipeline / 🧹 Lint (push) Successful in 3m13s
Monorepo Pipeline / 🚀 Release (push) Has been skipped
Monorepo Pipeline / 🐳 Build Gatekeeper (Product) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Build-Base (push) Has been skipped
Monorepo Pipeline / 🐳 Build Production Runtime (push) Has been skipped
This commit is contained in:
@@ -7,7 +7,8 @@
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node dist/start.js",
|
||||
"dev": "tsx watch src/index.ts"
|
||||
"dev": "tsx watch src/index.ts",
|
||||
"test:unit": "vitest run"
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "^1.5.0",
|
||||
@@ -19,6 +20,7 @@
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^20.14.10",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "^5.5.3"
|
||||
"typescript": "^5.5.3",
|
||||
"vitest": "^2.1.3"
|
||||
}
|
||||
}
|
||||
|
||||
180
packages/vikunja-mcp/src/index.test.ts
Normal file
180
packages/vikunja-mcp/src/index.test.ts
Normal file
@@ -0,0 +1,180 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
|
||||
// Mock axios
|
||||
const mockGet = vi.fn();
|
||||
const mockPost = vi.fn();
|
||||
const mockPut = vi.fn();
|
||||
const mockDelete = vi.fn();
|
||||
|
||||
vi.mock('axios', () => {
|
||||
return {
|
||||
default: {
|
||||
create: vi.fn().mockImplementation(() => ({
|
||||
get: mockGet,
|
||||
post: mockPost,
|
||||
put: mockPut,
|
||||
delete: mockDelete,
|
||||
})),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
// Set env vars
|
||||
process.env.VIKUNJA_API_TOKEN = 'test-token';
|
||||
process.env.VIKUNJA_BASE_URL = 'https://tasks.test.me';
|
||||
|
||||
// Mock express to avoid starting a real server
|
||||
vi.mock('express', () => {
|
||||
const mockApp = {
|
||||
use: vi.fn(),
|
||||
get: vi.fn(),
|
||||
post: vi.fn(),
|
||||
listen: vi.fn().mockImplementation((port, host, cb) => cb && cb()),
|
||||
};
|
||||
const mockExpress = () => mockApp;
|
||||
(mockExpress as any).json = () => vi.fn();
|
||||
return { default: mockExpress };
|
||||
});
|
||||
|
||||
let server: any;
|
||||
|
||||
describe('Vikunja MCP Server - New Tools (RED)', () => {
|
||||
beforeEach(async () => {
|
||||
vi.clearAllMocks();
|
||||
if (!server) {
|
||||
const mod = await import('./index.js');
|
||||
server = mod.server;
|
||||
}
|
||||
});
|
||||
|
||||
it('should support vikunja_create_project', async () => {
|
||||
mockPut.mockResolvedValueOnce({
|
||||
data: { id: 10, title: 'New Project', description: 'Testing' }
|
||||
});
|
||||
|
||||
const handler = (server as any)._requestHandlers.get('tools/call');
|
||||
expect(handler).toBeDefined();
|
||||
|
||||
const response = await handler({
|
||||
method: 'tools/call',
|
||||
params: {
|
||||
name: 'vikunja_create_project',
|
||||
arguments: {
|
||||
title: 'New Project',
|
||||
description: 'Testing',
|
||||
hex_color: 'ff0000',
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(mockPut).toHaveBeenCalledWith('/projects', {
|
||||
title: 'New Project',
|
||||
description: 'Testing',
|
||||
hex_color: 'ff0000',
|
||||
});
|
||||
expect(response.isError).toBeUndefined();
|
||||
expect(JSON.parse(response.content[0].text)).toEqual({
|
||||
id: 10,
|
||||
title: 'New Project',
|
||||
description: 'Testing',
|
||||
});
|
||||
});
|
||||
|
||||
it('should support vikunja_get_task', async () => {
|
||||
mockGet.mockResolvedValueOnce({
|
||||
data: { id: 42, title: 'My Task', project_id: 1 }
|
||||
});
|
||||
|
||||
const handler = (server as any)._requestHandlers.get('tools/call');
|
||||
const response = await handler({
|
||||
method: 'tools/call',
|
||||
params: {
|
||||
name: 'vikunja_get_task',
|
||||
arguments: {
|
||||
task_id: 42,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(mockGet).toHaveBeenCalledWith('/tasks/42');
|
||||
expect(response.isError).toBeUndefined();
|
||||
expect(JSON.parse(response.content[0].text)).toEqual({
|
||||
id: 42,
|
||||
title: 'My Task',
|
||||
project_id: 1,
|
||||
});
|
||||
});
|
||||
|
||||
it('should support vikunja_delete_task', async () => {
|
||||
mockDelete.mockResolvedValueOnce({
|
||||
data: { message: 'success' }
|
||||
});
|
||||
|
||||
const handler = (server as any)._requestHandlers.get('tools/call');
|
||||
const response = await handler({
|
||||
method: 'tools/call',
|
||||
params: {
|
||||
name: 'vikunja_delete_task',
|
||||
arguments: {
|
||||
task_id: 42,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(mockDelete).toHaveBeenCalledWith('/tasks/42');
|
||||
expect(response.isError).toBeUndefined();
|
||||
expect(JSON.parse(response.content[0].text)).toEqual({
|
||||
message: 'success',
|
||||
});
|
||||
});
|
||||
|
||||
it('should support vikunja_create_task_comment', async () => {
|
||||
mockPut.mockResolvedValueOnce({
|
||||
data: { id: 1, comment: 'New Comment', task_id: 42 }
|
||||
});
|
||||
|
||||
const handler = (server as any)._requestHandlers.get('tools/call');
|
||||
const response = await handler({
|
||||
method: 'tools/call',
|
||||
params: {
|
||||
name: 'vikunja_create_task_comment',
|
||||
arguments: {
|
||||
task_id: 42,
|
||||
comment: 'New Comment',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(mockPut).toHaveBeenCalledWith('/tasks/42/comments', {
|
||||
comment: 'New Comment',
|
||||
});
|
||||
expect(response.isError).toBeUndefined();
|
||||
expect(JSON.parse(response.content[0].text)).toEqual({
|
||||
id: 1,
|
||||
comment: 'New Comment',
|
||||
task_id: 42,
|
||||
});
|
||||
});
|
||||
|
||||
it('should support vikunja_get_task_comments', async () => {
|
||||
mockGet.mockResolvedValueOnce({
|
||||
data: [{ id: 1, comment: 'New Comment', task_id: 42 }]
|
||||
});
|
||||
|
||||
const handler = (server as any)._requestHandlers.get('tools/call');
|
||||
const response = await handler({
|
||||
method: 'tools/call',
|
||||
params: {
|
||||
name: 'vikunja_get_task_comments',
|
||||
arguments: {
|
||||
task_id: 42,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(mockGet).toHaveBeenCalledWith('/tasks/42/comments');
|
||||
expect(response.isError).toBeUndefined();
|
||||
expect(JSON.parse(response.content[0].text)).toEqual([
|
||||
{ id: 1, comment: 'New Comment', task_id: 42 }
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -83,8 +83,71 @@ const UPDATE_TASK_TOOL: Tool = {
|
||||
},
|
||||
};
|
||||
|
||||
const CREATE_PROJECT_TOOL: Tool = {
|
||||
name: "vikunja_create_project",
|
||||
description: "Create a new project (list) in Vikunja",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
title: { type: "string", description: "The title of the project" },
|
||||
description: { type: "string", description: "Optional description of the project" },
|
||||
hex_color: { type: "string", description: "Optional hex color without the '#' prefix" }
|
||||
},
|
||||
required: ["title"]
|
||||
}
|
||||
};
|
||||
|
||||
const GET_TASK_TOOL: Tool = {
|
||||
name: "vikunja_get_task",
|
||||
description: "Get details for a specific task by ID",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
task_id: { type: "number", description: "The ID of the task" }
|
||||
},
|
||||
required: ["task_id"]
|
||||
}
|
||||
};
|
||||
|
||||
const DELETE_TASK_TOOL: Tool = {
|
||||
name: "vikunja_delete_task",
|
||||
description: "Delete a task by ID",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
task_id: { type: "number", description: "The ID of the task to delete" }
|
||||
},
|
||||
required: ["task_id"]
|
||||
}
|
||||
};
|
||||
|
||||
const CREATE_TASK_COMMENT_TOOL: Tool = {
|
||||
name: "vikunja_create_task_comment",
|
||||
description: "Add a comment to a task",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
task_id: { type: "number", description: "The ID of the task to comment on" },
|
||||
comment: { type: "string", description: "The comment text" }
|
||||
},
|
||||
required: ["task_id", "comment"]
|
||||
}
|
||||
};
|
||||
|
||||
const GET_TASK_COMMENTS_TOOL: Tool = {
|
||||
name: "vikunja_get_task_comments",
|
||||
description: "Get all comments for a specific task",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
task_id: { type: "number", description: "The ID of the task" }
|
||||
},
|
||||
required: ["task_id"]
|
||||
}
|
||||
};
|
||||
|
||||
// --- Server Setup ---
|
||||
const server = new Server(
|
||||
export const server = new Server(
|
||||
{ name: "vikunja-mcp", version: "1.0.0" },
|
||||
{ capabilities: { tools: {} } }
|
||||
);
|
||||
@@ -94,7 +157,12 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
||||
GET_PROJECTS_TOOL,
|
||||
GET_TASKS_TOOL,
|
||||
CREATE_TASK_TOOL,
|
||||
UPDATE_TASK_TOOL
|
||||
UPDATE_TASK_TOOL,
|
||||
CREATE_PROJECT_TOOL,
|
||||
GET_TASK_TOOL,
|
||||
DELETE_TASK_TOOL,
|
||||
CREATE_TASK_COMMENT_TOOL,
|
||||
GET_TASK_COMMENTS_TOOL
|
||||
],
|
||||
}));
|
||||
|
||||
@@ -133,6 +201,42 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||
return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] };
|
||||
}
|
||||
|
||||
if (request.params.name === "vikunja_create_project") {
|
||||
const { title, description, hex_color } = request.params.arguments as any;
|
||||
// Vikunja standard: creating a new root resource uses PUT /projects in this version
|
||||
const res = await api.put('/projects', {
|
||||
title,
|
||||
description: description || "",
|
||||
hex_color: hex_color || ""
|
||||
});
|
||||
return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] };
|
||||
}
|
||||
|
||||
if (request.params.name === "vikunja_get_task") {
|
||||
const { task_id } = request.params.arguments as any;
|
||||
const res = await api.get(`/tasks/${task_id}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] };
|
||||
}
|
||||
|
||||
if (request.params.name === "vikunja_delete_task") {
|
||||
const { task_id } = request.params.arguments as any;
|
||||
const res = await api.delete(`/tasks/${task_id}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] };
|
||||
}
|
||||
|
||||
if (request.params.name === "vikunja_create_task_comment") {
|
||||
const { task_id, comment } = request.params.arguments as any;
|
||||
// Vikunja standard: task sub-resources (like comments) are typically appended using PUT /tasks/{id}/comments
|
||||
const res = await api.put(`/tasks/${task_id}/comments`, { comment });
|
||||
return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] };
|
||||
}
|
||||
|
||||
if (request.params.name === "vikunja_get_task_comments") {
|
||||
const { task_id } = request.params.arguments as any;
|
||||
const res = await api.get(`/tasks/${task_id}/comments`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] };
|
||||
}
|
||||
|
||||
throw new Error(`Unknown tool: ${request.params.name}`);
|
||||
} catch (e: any) {
|
||||
const msg = e.response?.data?.message || e.message;
|
||||
|
||||
83
pnpm-lock.yaml
generated
83
pnpm-lock.yaml
generated
@@ -235,7 +235,7 @@ importers:
|
||||
version: 5.9.3
|
||||
vitest:
|
||||
specifier: ^3.0.5
|
||||
version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.33)(@vitest/ui@4.0.18)(happy-dom@20.5.3)(jsdom@27.4.0(canvas@3.2.1))(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)
|
||||
version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.33)(@vitest/ui@4.0.18)(happy-dom@20.5.3)(jiti@2.6.1)(jsdom@27.4.0(canvas@3.2.1))(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
|
||||
packages/content-engine:
|
||||
dependencies:
|
||||
@@ -537,7 +537,7 @@ importers:
|
||||
version: 5.9.3
|
||||
vitest:
|
||||
specifier: ^3.0.4
|
||||
version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@4.0.18)(happy-dom@20.5.3)(jsdom@27.4.0(canvas@3.2.1))(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)
|
||||
version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@4.0.18)(happy-dom@20.5.3)(jiti@2.6.1)(jsdom@27.4.0(canvas@3.2.1))(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
|
||||
packages/meme-generator:
|
||||
dependencies:
|
||||
@@ -897,7 +897,7 @@ importers:
|
||||
version: 5.9.3
|
||||
vitest:
|
||||
specifier: ^3.0.5
|
||||
version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.33)(@vitest/ui@4.0.18)(happy-dom@20.5.3)(jsdom@27.4.0(canvas@3.2.1))(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)
|
||||
version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.33)(@vitest/ui@4.0.18)(happy-dom@20.5.3)(jiti@2.6.1)(jsdom@27.4.0(canvas@3.2.1))(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
|
||||
packages/serpbear-mcp:
|
||||
dependencies:
|
||||
@@ -979,6 +979,37 @@ importers:
|
||||
specifier: ^5.5.3
|
||||
version: 5.9.3
|
||||
|
||||
packages/vikunja-mcp:
|
||||
dependencies:
|
||||
'@modelcontextprotocol/sdk':
|
||||
specifier: ^1.5.0
|
||||
version: 1.27.1(zod@3.25.76)
|
||||
axios:
|
||||
specifier: ^1.7.2
|
||||
version: 1.13.5
|
||||
dotenv:
|
||||
specifier: ^17.3.1
|
||||
version: 17.3.1
|
||||
express:
|
||||
specifier: ^4.19.2
|
||||
version: 4.22.1
|
||||
devDependencies:
|
||||
'@types/express':
|
||||
specifier: ^4.17.21
|
||||
version: 4.17.25
|
||||
'@types/node':
|
||||
specifier: ^20.14.10
|
||||
version: 20.19.33
|
||||
tsx:
|
||||
specifier: ^4.19.2
|
||||
version: 4.21.0
|
||||
typescript:
|
||||
specifier: ^5.5.3
|
||||
version: 5.9.3
|
||||
vitest:
|
||||
specifier: ^2.1.3
|
||||
version: 2.1.9(@types/node@20.19.33)(@vitest/ui@4.0.18)(happy-dom@20.5.3)(jsdom@27.4.0(canvas@3.2.1))(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)
|
||||
|
||||
packages:
|
||||
|
||||
'@acemir/cssom@0.9.31':
|
||||
@@ -16946,15 +16977,16 @@ snapshots:
|
||||
- supports-color
|
||||
- terser
|
||||
|
||||
vite-node@3.2.4(@types/node@20.19.33)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0):
|
||||
vite-node@3.2.4(@types/node@20.19.33)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2):
|
||||
dependencies:
|
||||
cac: 6.7.14
|
||||
debug: 4.4.3
|
||||
es-module-lexer: 1.7.0
|
||||
pathe: 2.0.3
|
||||
vite: 5.4.21(@types/node@20.19.33)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)
|
||||
vite: 7.3.1(@types/node@20.19.33)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- jiti
|
||||
- less
|
||||
- lightningcss
|
||||
- sass
|
||||
@@ -16963,16 +16995,19 @@ snapshots:
|
||||
- sugarss
|
||||
- supports-color
|
||||
- terser
|
||||
- tsx
|
||||
- yaml
|
||||
|
||||
vite-node@3.2.4(@types/node@22.19.10)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0):
|
||||
vite-node@3.2.4(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2):
|
||||
dependencies:
|
||||
cac: 6.7.14
|
||||
debug: 4.4.3
|
||||
es-module-lexer: 1.7.0
|
||||
pathe: 2.0.3
|
||||
vite: 5.4.21(@types/node@22.19.10)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)
|
||||
vite: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- jiti
|
||||
- less
|
||||
- lightningcss
|
||||
- sass
|
||||
@@ -16981,6 +17016,8 @@ snapshots:
|
||||
- sugarss
|
||||
- supports-color
|
||||
- terser
|
||||
- tsx
|
||||
- yaml
|
||||
|
||||
vite@5.4.21(@types/node@20.19.33)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0):
|
||||
dependencies:
|
||||
@@ -17024,6 +17061,24 @@ snapshots:
|
||||
tsx: 4.21.0
|
||||
yaml: 2.8.2
|
||||
|
||||
vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2):
|
||||
dependencies:
|
||||
esbuild: 0.27.3
|
||||
fdir: 6.5.0(picomatch@4.0.3)
|
||||
picomatch: 4.0.3
|
||||
postcss: 8.5.6
|
||||
rollup: 4.57.1
|
||||
tinyglobby: 0.2.15
|
||||
optionalDependencies:
|
||||
'@types/node': 22.19.10
|
||||
fsevents: 2.3.3
|
||||
jiti: 2.6.1
|
||||
lightningcss: 1.30.2
|
||||
sass: 1.97.3
|
||||
terser: 5.46.0
|
||||
tsx: 4.21.0
|
||||
yaml: 2.8.2
|
||||
|
||||
vitest@2.1.9(@types/node@20.19.33)(@vitest/ui@4.0.18)(happy-dom@20.5.3)(jsdom@27.4.0(canvas@3.2.1))(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0):
|
||||
dependencies:
|
||||
'@vitest/expect': 2.1.9
|
||||
@@ -17100,7 +17155,7 @@ snapshots:
|
||||
- supports-color
|
||||
- terser
|
||||
|
||||
vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.33)(@vitest/ui@4.0.18)(happy-dom@20.5.3)(jsdom@27.4.0(canvas@3.2.1))(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0):
|
||||
vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.33)(@vitest/ui@4.0.18)(happy-dom@20.5.3)(jiti@2.6.1)(jsdom@27.4.0(canvas@3.2.1))(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2):
|
||||
dependencies:
|
||||
'@types/chai': 5.2.3
|
||||
'@vitest/expect': 3.2.4
|
||||
@@ -17123,7 +17178,7 @@ snapshots:
|
||||
tinypool: 1.1.1
|
||||
tinyrainbow: 2.0.0
|
||||
vite: 5.4.21(@types/node@20.19.33)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)
|
||||
vite-node: 3.2.4(@types/node@20.19.33)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)
|
||||
vite-node: 3.2.4(@types/node@20.19.33)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
why-is-node-running: 2.3.0
|
||||
optionalDependencies:
|
||||
'@types/debug': 4.1.12
|
||||
@@ -17132,6 +17187,7 @@ snapshots:
|
||||
happy-dom: 20.5.3
|
||||
jsdom: 27.4.0(canvas@3.2.1)
|
||||
transitivePeerDependencies:
|
||||
- jiti
|
||||
- less
|
||||
- lightningcss
|
||||
- msw
|
||||
@@ -17141,8 +17197,10 @@ snapshots:
|
||||
- sugarss
|
||||
- supports-color
|
||||
- terser
|
||||
- tsx
|
||||
- yaml
|
||||
|
||||
vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@4.0.18)(happy-dom@20.5.3)(jsdom@27.4.0(canvas@3.2.1))(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0):
|
||||
vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@4.0.18)(happy-dom@20.5.3)(jiti@2.6.1)(jsdom@27.4.0(canvas@3.2.1))(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2):
|
||||
dependencies:
|
||||
'@types/chai': 5.2.3
|
||||
'@vitest/expect': 3.2.4
|
||||
@@ -17165,7 +17223,7 @@ snapshots:
|
||||
tinypool: 1.1.1
|
||||
tinyrainbow: 2.0.0
|
||||
vite: 5.4.21(@types/node@22.19.10)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)
|
||||
vite-node: 3.2.4(@types/node@22.19.10)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)
|
||||
vite-node: 3.2.4(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
why-is-node-running: 2.3.0
|
||||
optionalDependencies:
|
||||
'@types/debug': 4.1.12
|
||||
@@ -17174,6 +17232,7 @@ snapshots:
|
||||
happy-dom: 20.5.3
|
||||
jsdom: 27.4.0(canvas@3.2.1)
|
||||
transitivePeerDependencies:
|
||||
- jiti
|
||||
- less
|
||||
- lightningcss
|
||||
- msw
|
||||
@@ -17183,6 +17242,8 @@ snapshots:
|
||||
- sugarss
|
||||
- supports-color
|
||||
- terser
|
||||
- tsx
|
||||
- yaml
|
||||
|
||||
vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.33)(@vitest/ui@4.0.18)(happy-dom@20.5.3)(jiti@2.6.1)(jsdom@27.4.0(canvas@3.2.1))(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2):
|
||||
dependencies:
|
||||
|
||||
Reference in New Issue
Block a user