@browserstack/mcp-server 1.0.12 → 1.0.14
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/README.md +22 -0
- package/dist/config.js +2 -6
- package/dist/index.js +31 -30
- package/dist/lib/api.js +3 -57
- package/dist/lib/constants.js +14 -0
- package/dist/lib/device-cache.js +32 -33
- package/dist/lib/error.js +3 -6
- package/dist/lib/fuzzy.js +1 -4
- package/dist/lib/inmemory-store.js +1 -0
- package/dist/lib/instrumentation.js +12 -18
- package/dist/lib/local.js +27 -35
- package/dist/lib/utils.js +29 -4
- package/dist/logger.js +4 -9
- package/dist/tools/accessibility.js +9 -12
- package/dist/tools/accessiblity-utils/accessibility.js +14 -22
- package/dist/tools/appautomate-utils/appautomate.js +95 -0
- package/dist/tools/appautomate.js +116 -0
- package/dist/tools/applive-utils/fuzzy-search.js +3 -6
- package/dist/tools/applive-utils/start-session.js +14 -20
- package/dist/tools/applive-utils/upload-app.js +12 -51
- package/dist/tools/applive.js +18 -25
- package/dist/tools/automate-utils/fetch-screenshots.js +59 -0
- package/dist/tools/automate.js +44 -37
- package/dist/tools/bstack-sdk.js +14 -18
- package/dist/tools/failurelogs-utils/app-automate.js +88 -0
- package/dist/tools/failurelogs-utils/automate.js +97 -0
- package/dist/tools/getFailureLogs.js +173 -0
- package/dist/tools/live-utils/desktop-filter.js +8 -11
- package/dist/tools/live-utils/mobile-filter.js +7 -10
- package/dist/tools/live-utils/start-session.js +17 -23
- package/dist/tools/live-utils/types.js +2 -5
- package/dist/tools/live-utils/version-resolver.js +1 -4
- package/dist/tools/live.js +23 -29
- package/dist/tools/observability.js +12 -19
- package/dist/tools/sdk-utils/constants.js +3 -9
- package/dist/tools/sdk-utils/instructions.js +4 -9
- package/dist/tools/sdk-utils/types.js +1 -2
- package/dist/tools/testmanagement-utils/TCG-utils/api.js +259 -0
- package/dist/tools/testmanagement-utils/TCG-utils/config.js +5 -0
- package/dist/tools/testmanagement-utils/TCG-utils/helpers.js +53 -0
- package/dist/tools/testmanagement-utils/TCG-utils/types.js +8 -0
- package/dist/tools/testmanagement-utils/add-test-result.js +61 -0
- package/dist/tools/testmanagement-utils/create-project-folder.js +21 -28
- package/dist/tools/testmanagement-utils/create-testcase.js +30 -38
- package/dist/tools/testmanagement-utils/create-testrun.js +23 -30
- package/dist/tools/testmanagement-utils/list-testcases.js +16 -23
- package/dist/tools/testmanagement-utils/list-testruns.js +13 -20
- package/dist/tools/testmanagement-utils/testcase-from-file.js +42 -0
- package/dist/tools/testmanagement-utils/update-testrun.js +16 -23
- package/dist/tools/testmanagement-utils/upload-file.js +101 -0
- package/dist/tools/testmanagement.js +115 -46
- package/package.json +10 -6
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import FormData from "form-data";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import { v4 as uuidv4 } from "uuid";
|
|
7
|
+
import config from "../../config.js";
|
|
8
|
+
import { signedUrlMap } from "../../lib/inmemory-store.js";
|
|
9
|
+
import { projectIdentifierToId } from "./TCG-utils/api.js";
|
|
10
|
+
/**
|
|
11
|
+
* Schema for the upload file tool
|
|
12
|
+
*/
|
|
13
|
+
export const UploadFileSchema = z.object({
|
|
14
|
+
project_identifier: z
|
|
15
|
+
.string()
|
|
16
|
+
.describe("ID of the project where the file should be uploaded. Do not assume it, always ask user for it."),
|
|
17
|
+
file_path: z
|
|
18
|
+
.string()
|
|
19
|
+
.describe("Full path to the file that should be uploaded"),
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* Uploads a file to BrowserStack Test Management and returns the signed URL.
|
|
23
|
+
*/
|
|
24
|
+
export async function uploadFile(args) {
|
|
25
|
+
const { project_identifier, file_path } = args;
|
|
26
|
+
try {
|
|
27
|
+
// Validate file exists
|
|
28
|
+
if (!fs.existsSync(file_path)) {
|
|
29
|
+
return {
|
|
30
|
+
content: [
|
|
31
|
+
{
|
|
32
|
+
type: "text",
|
|
33
|
+
text: `File ${file_path} does not exist.`,
|
|
34
|
+
isError: true,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
isError: true,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// Get the project ID
|
|
41
|
+
const projectIdResponse = await projectIdentifierToId(project_identifier);
|
|
42
|
+
const formData = new FormData();
|
|
43
|
+
formData.append("attachments[]", fs.createReadStream(file_path));
|
|
44
|
+
const uploadUrl = `https://test-management.browserstack.com/api/v1/projects/${projectIdResponse}/generic/attachments/ai_uploads`;
|
|
45
|
+
const response = await axios.post(uploadUrl, formData, {
|
|
46
|
+
headers: {
|
|
47
|
+
...formData.getHeaders(),
|
|
48
|
+
"API-TOKEN": `${config.browserstackUsername}:${config.browserstackAccessKey}`,
|
|
49
|
+
accept: "application/json, text/plain, */*",
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
if (response.status >= 200 &&
|
|
53
|
+
response.status < 300 &&
|
|
54
|
+
response.data.generic_attachment) {
|
|
55
|
+
const attachments = response.data.generic_attachment.map((attachment) => {
|
|
56
|
+
// Generate a unique ID for each attachment
|
|
57
|
+
const fileId = uuidv4();
|
|
58
|
+
// Store the download URL in the signedUrlMap
|
|
59
|
+
const data = {
|
|
60
|
+
fileId: attachment.id,
|
|
61
|
+
downloadUrl: attachment.download_url,
|
|
62
|
+
};
|
|
63
|
+
signedUrlMap.set(fileId, data);
|
|
64
|
+
return {
|
|
65
|
+
name: attachment.name,
|
|
66
|
+
documentID: fileId,
|
|
67
|
+
contentType: attachment.content_type,
|
|
68
|
+
size: attachment.size,
|
|
69
|
+
projectReferenceId: projectIdResponse,
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
content: [
|
|
74
|
+
{
|
|
75
|
+
type: "text",
|
|
76
|
+
text: `Successfully uploaded ${path.basename(file_path)} to BrowserStack Test Management.`,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
type: "text",
|
|
80
|
+
text: JSON.stringify(attachments, null, 2),
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
throw new Error(`Unexpected response: ${JSON.stringify(response.data)}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
return {
|
|
91
|
+
content: [
|
|
92
|
+
{
|
|
93
|
+
type: "text",
|
|
94
|
+
text: `Failed to upload file: ${error instanceof Error ? error.message : "Unknown error"}. Please check your credentials and try again.`,
|
|
95
|
+
isError: true,
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
isError: true,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -1,36 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.createProjectOrFolderTool = createProjectOrFolderTool;
|
|
7
|
-
exports.createTestCaseTool = createTestCaseTool;
|
|
8
|
-
exports.listTestCasesTool = listTestCasesTool;
|
|
9
|
-
exports.createTestRunTool = createTestRunTool;
|
|
10
|
-
exports.listTestRunsTool = listTestRunsTool;
|
|
11
|
-
exports.updateTestRunTool = updateTestRunTool;
|
|
12
|
-
exports.default = addTestManagementTools;
|
|
13
|
-
const instrumentation_1 = require("../lib/instrumentation");
|
|
14
|
-
const logger_1 = __importDefault(require("../logger"));
|
|
15
|
-
const create_project_folder_1 = require("./testmanagement-utils/create-project-folder");
|
|
16
|
-
const create_testcase_1 = require("./testmanagement-utils/create-testcase");
|
|
1
|
+
import { trackMCP } from "../lib/instrumentation.js";
|
|
2
|
+
import logger from "../logger.js";
|
|
3
|
+
import { createProjectOrFolder, CreateProjFoldSchema, } from "./testmanagement-utils/create-project-folder.js";
|
|
4
|
+
import { createTestCase as createTestCaseAPI, sanitizeArgs, CreateTestCaseSchema, } from "./testmanagement-utils/create-testcase.js";
|
|
17
5
|
let serverInstance;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
6
|
+
import { listTestCases, ListTestCasesSchema, } from "./testmanagement-utils/list-testcases.js";
|
|
7
|
+
import { CreateTestRunSchema, createTestRun, } from "./testmanagement-utils/create-testrun.js";
|
|
8
|
+
import { ListTestRunsSchema, listTestRuns, } from "./testmanagement-utils/list-testruns.js";
|
|
9
|
+
import { UpdateTestRunSchema, updateTestRun, } from "./testmanagement-utils/update-testrun.js";
|
|
10
|
+
import { addTestResult, AddTestResultSchema, } from "./testmanagement-utils/add-test-result.js";
|
|
11
|
+
import { UploadFileSchema, uploadFile, } from "./testmanagement-utils/upload-file.js";
|
|
12
|
+
import { createTestCasesFromFile } from "./testmanagement-utils/testcase-from-file.js";
|
|
13
|
+
import { CreateTestCasesFromFileSchema } from "./testmanagement-utils/TCG-utils/types.js";
|
|
22
14
|
//TODO: Moving the traceMCP and catch block to the parent(server) function
|
|
23
15
|
/**
|
|
24
16
|
* Wrapper to call createProjectOrFolder util.
|
|
25
17
|
*/
|
|
26
|
-
async function createProjectOrFolderTool(args) {
|
|
18
|
+
export async function createProjectOrFolderTool(args) {
|
|
27
19
|
try {
|
|
28
|
-
|
|
29
|
-
return await
|
|
20
|
+
trackMCP("createProjectOrFolder", serverInstance.server.getClientVersion());
|
|
21
|
+
return await createProjectOrFolder(args);
|
|
30
22
|
}
|
|
31
23
|
catch (err) {
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
logger.error("Failed to create project/folder: %s", err);
|
|
25
|
+
trackMCP("createProjectOrFolder", serverInstance.server.getClientVersion(), err);
|
|
34
26
|
return {
|
|
35
27
|
content: [
|
|
36
28
|
{
|
|
@@ -46,16 +38,16 @@ async function createProjectOrFolderTool(args) {
|
|
|
46
38
|
/**
|
|
47
39
|
* Creates a test case in BrowserStack Test Management.
|
|
48
40
|
*/
|
|
49
|
-
async function createTestCaseTool(args) {
|
|
41
|
+
export async function createTestCaseTool(args) {
|
|
50
42
|
// Sanitize input arguments
|
|
51
|
-
const cleanedArgs =
|
|
43
|
+
const cleanedArgs = sanitizeArgs(args);
|
|
52
44
|
try {
|
|
53
|
-
|
|
54
|
-
return await (
|
|
45
|
+
trackMCP("createTestCase", serverInstance.server.getClientVersion());
|
|
46
|
+
return await createTestCaseAPI(cleanedArgs);
|
|
55
47
|
}
|
|
56
48
|
catch (err) {
|
|
57
|
-
|
|
58
|
-
|
|
49
|
+
logger.error("Failed to create test case: %s", err);
|
|
50
|
+
trackMCP("createTestCase", serverInstance.server.getClientVersion(), err);
|
|
59
51
|
return {
|
|
60
52
|
content: [
|
|
61
53
|
{
|
|
@@ -71,11 +63,13 @@ async function createTestCaseTool(args) {
|
|
|
71
63
|
/**
|
|
72
64
|
* Lists test cases in a project with optional filters (status, priority, custom fields, etc.)
|
|
73
65
|
*/
|
|
74
|
-
async function listTestCasesTool(args) {
|
|
66
|
+
export async function listTestCasesTool(args) {
|
|
75
67
|
try {
|
|
76
|
-
|
|
68
|
+
trackMCP("listTestCases", serverInstance.server.getClientVersion());
|
|
69
|
+
return await listTestCases(args);
|
|
77
70
|
}
|
|
78
71
|
catch (err) {
|
|
72
|
+
trackMCP("listTestCases", serverInstance.server.getClientVersion(), err);
|
|
79
73
|
return {
|
|
80
74
|
content: [
|
|
81
75
|
{
|
|
@@ -91,11 +85,13 @@ async function listTestCasesTool(args) {
|
|
|
91
85
|
/**
|
|
92
86
|
* Creates a test run in BrowserStack Test Management.
|
|
93
87
|
*/
|
|
94
|
-
async function createTestRunTool(args) {
|
|
88
|
+
export async function createTestRunTool(args) {
|
|
95
89
|
try {
|
|
96
|
-
|
|
90
|
+
trackMCP("createTestRun", serverInstance.server.getClientVersion());
|
|
91
|
+
return await createTestRun(args);
|
|
97
92
|
}
|
|
98
93
|
catch (err) {
|
|
94
|
+
trackMCP("createTestRun", serverInstance.server.getClientVersion(), err);
|
|
99
95
|
return {
|
|
100
96
|
content: [
|
|
101
97
|
{
|
|
@@ -111,11 +107,13 @@ async function createTestRunTool(args) {
|
|
|
111
107
|
/**
|
|
112
108
|
* Lists test runs in a project with optional filters (date ranges, assignee, state, etc.)
|
|
113
109
|
*/
|
|
114
|
-
async function listTestRunsTool(args) {
|
|
110
|
+
export async function listTestRunsTool(args) {
|
|
115
111
|
try {
|
|
116
|
-
|
|
112
|
+
trackMCP("listTestRuns", serverInstance.server.getClientVersion());
|
|
113
|
+
return await listTestRuns(args);
|
|
117
114
|
}
|
|
118
115
|
catch (err) {
|
|
116
|
+
trackMCP("listTestRuns", serverInstance.server.getClientVersion(), err);
|
|
119
117
|
return {
|
|
120
118
|
content: [
|
|
121
119
|
{
|
|
@@ -133,11 +131,13 @@ async function listTestRunsTool(args) {
|
|
|
133
131
|
* This function allows for partial updates to an existing test run.
|
|
134
132
|
* It takes the project identifier and test run ID as parameters.
|
|
135
133
|
*/
|
|
136
|
-
async function updateTestRunTool(args) {
|
|
134
|
+
export async function updateTestRunTool(args) {
|
|
137
135
|
try {
|
|
138
|
-
|
|
136
|
+
trackMCP("updateTestRun", serverInstance.server.getClientVersion());
|
|
137
|
+
return await updateTestRun(args);
|
|
139
138
|
}
|
|
140
139
|
catch (err) {
|
|
140
|
+
trackMCP("updateTestRun", serverInstance.server.getClientVersion(), err);
|
|
141
141
|
return {
|
|
142
142
|
content: [
|
|
143
143
|
{
|
|
@@ -150,15 +150,84 @@ async function updateTestRunTool(args) {
|
|
|
150
150
|
};
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Adds a test result to a specific test run via BrowserStack Test Management API.
|
|
155
|
+
*/
|
|
156
|
+
export async function addTestResultTool(args) {
|
|
157
|
+
try {
|
|
158
|
+
trackMCP("addTestResult", serverInstance.server.getClientVersion());
|
|
159
|
+
return await addTestResult(args);
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
trackMCP("addTestResult", serverInstance.server.getClientVersion(), err);
|
|
163
|
+
return {
|
|
164
|
+
content: [
|
|
165
|
+
{
|
|
166
|
+
type: "text",
|
|
167
|
+
text: `Failed to add test result: ${err instanceof Error ? err.message : "Unknown error"}. Please open an issue on GitHub if the problem persists`,
|
|
168
|
+
isError: true,
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
isError: true,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Uploads files such as PDRs or screenshots to BrowserStack Test Management and get file mapping ID back.
|
|
177
|
+
*/
|
|
178
|
+
export async function uploadFileTestManagementTool(args) {
|
|
179
|
+
try {
|
|
180
|
+
trackMCP("uploadFileTestManagement", serverInstance.server.getClientVersion());
|
|
181
|
+
return await uploadFile(args);
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
trackMCP("uploadFileTestManagement", serverInstance.server.getClientVersion(), err);
|
|
185
|
+
return {
|
|
186
|
+
content: [
|
|
187
|
+
{
|
|
188
|
+
type: "text",
|
|
189
|
+
text: `Failed to upload file: ${err instanceof Error ? err.message : "Unknown error"}. Please open an issue on GitHub if the problem persists`,
|
|
190
|
+
isError: true,
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
isError: true,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Creates test cases from a file in BrowserStack Test Management.
|
|
199
|
+
*/
|
|
200
|
+
export async function createTestCasesFromFileTool(args, context) {
|
|
201
|
+
try {
|
|
202
|
+
trackMCP("createTestCasesFromFile", serverInstance.server.getClientVersion());
|
|
203
|
+
return await createTestCasesFromFile(args, context);
|
|
204
|
+
}
|
|
205
|
+
catch (err) {
|
|
206
|
+
trackMCP("createTestCasesFromFile", serverInstance.server.getClientVersion(), err);
|
|
207
|
+
return {
|
|
208
|
+
content: [
|
|
209
|
+
{
|
|
210
|
+
type: "text",
|
|
211
|
+
text: `Failed to create test cases from file: ${err instanceof Error ? err.message : "Unknown error"}. Please open an issue on GitHub if the problem persists`,
|
|
212
|
+
isError: true,
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
isError: true,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
}
|
|
153
219
|
/**
|
|
154
220
|
* Registers both project/folder and test-case tools.
|
|
155
221
|
*/
|
|
156
|
-
function addTestManagementTools(server) {
|
|
222
|
+
export default function addTestManagementTools(server) {
|
|
157
223
|
serverInstance = server;
|
|
158
|
-
server.tool("createProjectOrFolder", "Create a project and/or folder in BrowserStack Test Management.",
|
|
159
|
-
server.tool("createTestCase", "Use this tool to create a test case in BrowserStack Test Management.",
|
|
160
|
-
server.tool("listTestCases", "List test cases in a project with optional filters (status, priority, custom fields, etc.)",
|
|
161
|
-
server.tool("createTestRun", "Create a test run in BrowserStack Test Management.",
|
|
162
|
-
server.tool("listTestRuns", "List test runs in a project with optional filters (date ranges, assignee, state, etc.)",
|
|
163
|
-
server.tool("updateTestRun", "Update a test run in BrowserStack Test Management.",
|
|
224
|
+
server.tool("createProjectOrFolder", "Create a project and/or folder in BrowserStack Test Management.", CreateProjFoldSchema.shape, createProjectOrFolderTool);
|
|
225
|
+
server.tool("createTestCase", "Use this tool to create a test case in BrowserStack Test Management.", CreateTestCaseSchema.shape, createTestCaseTool);
|
|
226
|
+
server.tool("listTestCases", "List test cases in a project with optional filters (status, priority, custom fields, etc.)", ListTestCasesSchema.shape, listTestCasesTool);
|
|
227
|
+
server.tool("createTestRun", "Create a test run in BrowserStack Test Management.", CreateTestRunSchema.shape, createTestRunTool);
|
|
228
|
+
server.tool("listTestRuns", "List test runs in a project with optional filters (date ranges, assignee, state, etc.)", ListTestRunsSchema.shape, listTestRunsTool);
|
|
229
|
+
server.tool("updateTestRun", "Update a test run in BrowserStack Test Management.", UpdateTestRunSchema.shape, updateTestRunTool);
|
|
230
|
+
server.tool("addTestResult", "Add a test result to a specific test run via BrowserStack Test Management API.", AddTestResultSchema.shape, addTestResultTool);
|
|
231
|
+
server.tool("uploadFileTestManagement", "Upload files such as PDRs or PDFs to BrowserStack Test Management and get file mapping ID back. Its Used for generating test cases from file.", UploadFileSchema.shape, uploadFileTestManagementTool);
|
|
232
|
+
server.tool("createTestCasesFromFile", "Create test cases from a file in BrowserStack Test Management.", CreateTestCasesFromFileSchema.shape, createTestCasesFromFileTool);
|
|
164
233
|
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@browserstack/mcp-server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"description": "BrowserStack's Official MCP Server",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/browserstack/mcp-server.git"
|
|
9
9
|
},
|
|
10
|
+
"type": "module",
|
|
10
11
|
"scripts": {
|
|
11
12
|
"build": "npm run lint && npm run format && npm test && tsc",
|
|
12
13
|
"start": "node dist/index.js",
|
|
13
14
|
"dev": "tsx watch --clear-screen=false src/index.ts",
|
|
14
|
-
"test": "
|
|
15
|
+
"test": "vitest run",
|
|
15
16
|
"lint": "eslint . --ext .ts",
|
|
16
17
|
"format": "prettier --write \"src/**/*.ts\""
|
|
17
18
|
},
|
|
@@ -41,18 +42,21 @@
|
|
|
41
42
|
"form-data": "^4.0.2",
|
|
42
43
|
"pino": "^9.6.0",
|
|
43
44
|
"pino-pretty": "^13.0.0",
|
|
45
|
+
"sharp": "^0.34.1",
|
|
46
|
+
"uuid": "^11.1.0",
|
|
47
|
+
"webdriverio": "^9.13.0",
|
|
44
48
|
"zod": "^3.24.3"
|
|
45
49
|
},
|
|
46
50
|
"devDependencies": {
|
|
47
51
|
"@eslint/js": "^9.25.0",
|
|
48
|
-
"@types/jest": "^29.5.14",
|
|
49
52
|
"@types/node": "^22.14.1",
|
|
53
|
+
"@types/uuid": "^10.0.0",
|
|
50
54
|
"eslint": "^9.25.0",
|
|
51
|
-
"jest": "^29.7.0",
|
|
52
55
|
"prettier": "^3.5.3",
|
|
53
|
-
"ts-jest": "^29.3.2",
|
|
54
56
|
"tsx": "^4.19.3",
|
|
55
57
|
"typescript": "^5.8.3",
|
|
56
|
-
"typescript-eslint": "^8.30.1"
|
|
58
|
+
"typescript-eslint": "^8.30.1",
|
|
59
|
+
"vite": "^6.3.5",
|
|
60
|
+
"vitest": "^3.1.3"
|
|
57
61
|
}
|
|
58
62
|
}
|