cucumberstudio-mcp 1.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.
Files changed (130) hide show
  1. package/.env.example +36 -0
  2. package/.github/workflows/pr-checks.yml +41 -0
  3. package/.github/workflows/release.yml +194 -0
  4. package/.prettierignore +26 -0
  5. package/.prettierrc +14 -0
  6. package/CLAUDE.md +140 -0
  7. package/Dockerfile +50 -0
  8. package/Dockerfile.dev +31 -0
  9. package/LICENSE +21 -0
  10. package/README.md +395 -0
  11. package/build/api/client.d.ts +49 -0
  12. package/build/api/client.d.ts.map +1 -0
  13. package/build/api/client.js +204 -0
  14. package/build/api/client.js.map +1 -0
  15. package/build/api/types.d.ts +113 -0
  16. package/build/api/types.d.ts.map +1 -0
  17. package/build/api/types.js +2 -0
  18. package/build/api/types.js.map +1 -0
  19. package/build/config/settings.d.ts +123 -0
  20. package/build/config/settings.d.ts.map +1 -0
  21. package/build/config/settings.js +97 -0
  22. package/build/config/settings.js.map +1 -0
  23. package/build/constants.d.ts +16 -0
  24. package/build/constants.d.ts.map +1 -0
  25. package/build/constants.js +24 -0
  26. package/build/constants.js.map +1 -0
  27. package/build/generated/version.d.ts +3 -0
  28. package/build/generated/version.d.ts.map +1 -0
  29. package/build/generated/version.js +5 -0
  30. package/build/generated/version.js.map +1 -0
  31. package/build/index.d.ts +3 -0
  32. package/build/index.d.ts.map +1 -0
  33. package/build/index.js +81 -0
  34. package/build/index.js.map +1 -0
  35. package/build/mcp-server.d.ts +6 -0
  36. package/build/mcp-server.d.ts.map +1 -0
  37. package/build/mcp-server.js +263 -0
  38. package/build/mcp-server.js.map +1 -0
  39. package/build/tools/action-words.d.ts +18 -0
  40. package/build/tools/action-words.d.ts.map +1 -0
  41. package/build/tools/action-words.js +191 -0
  42. package/build/tools/action-words.js.map +1 -0
  43. package/build/tools/projects.d.ts +19 -0
  44. package/build/tools/projects.d.ts.map +1 -0
  45. package/build/tools/projects.js +123 -0
  46. package/build/tools/projects.js.map +1 -0
  47. package/build/tools/scenarios.d.ts +18 -0
  48. package/build/tools/scenarios.d.ts.map +1 -0
  49. package/build/tools/scenarios.js +194 -0
  50. package/build/tools/scenarios.js.map +1 -0
  51. package/build/tools/test-runs.d.ts +21 -0
  52. package/build/tools/test-runs.d.ts.map +1 -0
  53. package/build/tools/test-runs.js +324 -0
  54. package/build/tools/test-runs.js.map +1 -0
  55. package/build/transports/http.d.ts +38 -0
  56. package/build/transports/http.d.ts.map +1 -0
  57. package/build/transports/http.js +381 -0
  58. package/build/transports/http.js.map +1 -0
  59. package/build/transports/index.d.ts +22 -0
  60. package/build/transports/index.d.ts.map +1 -0
  61. package/build/transports/index.js +10 -0
  62. package/build/transports/index.js.map +1 -0
  63. package/build/transports/stdio.d.ts +13 -0
  64. package/build/transports/stdio.d.ts.map +1 -0
  65. package/build/transports/stdio.js +24 -0
  66. package/build/transports/stdio.js.map +1 -0
  67. package/build/utils/errors.d.ts +10 -0
  68. package/build/utils/errors.d.ts.map +1 -0
  69. package/build/utils/errors.js +35 -0
  70. package/build/utils/errors.js.map +1 -0
  71. package/build/utils/logger-constants.d.ts +15 -0
  72. package/build/utils/logger-constants.d.ts.map +1 -0
  73. package/build/utils/logger-constants.js +16 -0
  74. package/build/utils/logger-constants.js.map +1 -0
  75. package/build/utils/logger.d.ts +55 -0
  76. package/build/utils/logger.d.ts.map +1 -0
  77. package/build/utils/logger.js +113 -0
  78. package/build/utils/logger.js.map +1 -0
  79. package/build/utils/validation.d.ts +89 -0
  80. package/build/utils/validation.d.ts.map +1 -0
  81. package/build/utils/validation.js +78 -0
  82. package/build/utils/validation.js.map +1 -0
  83. package/docker-compose.yml +20 -0
  84. package/eslint.config.js +97 -0
  85. package/package.json +92 -0
  86. package/scripts/generate-version.js +31 -0
  87. package/src/api/client.ts +286 -0
  88. package/src/api/types.ts +137 -0
  89. package/src/config/settings.ts +113 -0
  90. package/src/constants.ts +29 -0
  91. package/src/index.ts +99 -0
  92. package/src/mcp-server.ts +342 -0
  93. package/src/tools/action-words.ts +240 -0
  94. package/src/tools/projects.ts +144 -0
  95. package/src/tools/scenarios.ts +231 -0
  96. package/src/tools/test-runs.ts +400 -0
  97. package/src/transports/http.ts +467 -0
  98. package/src/transports/index.ts +26 -0
  99. package/src/transports/stdio.ts +28 -0
  100. package/src/utils/errors.ts +45 -0
  101. package/src/utils/logger-constants.ts +18 -0
  102. package/src/utils/logger.ts +150 -0
  103. package/src/utils/validation.ts +94 -0
  104. package/test/api/client-with-msw.test.ts +122 -0
  105. package/test/api/client.test.ts +326 -0
  106. package/test/api/types.test.ts +88 -0
  107. package/test/config/settings.test.ts +204 -0
  108. package/test/mocks/data/action-words.ts +40 -0
  109. package/test/mocks/data/index.ts +13 -0
  110. package/test/mocks/data/projects.ts +38 -0
  111. package/test/mocks/data/scenarios.ts +53 -0
  112. package/test/mocks/data/test-runs.ts +101 -0
  113. package/test/mocks/handlers/action-words.ts +52 -0
  114. package/test/mocks/handlers/index.ts +10 -0
  115. package/test/mocks/handlers/projects.ts +45 -0
  116. package/test/mocks/handlers/scenarios.ts +72 -0
  117. package/test/mocks/handlers/test-runs.ts +106 -0
  118. package/test/mocks/server.ts +26 -0
  119. package/test/setup/vitest.setup.ts +18 -0
  120. package/test/tools/coverage-boost.test.ts +252 -0
  121. package/test/tools/projects.test.ts +290 -0
  122. package/test/tools/tools-basic.test.ts +146 -0
  123. package/test/transports/http-basic.test.ts +87 -0
  124. package/test/transports/http-simple.test.ts +33 -0
  125. package/test/transports/stdio.test.ts +73 -0
  126. package/test/utils/errors.test.ts +117 -0
  127. package/test/utils/validation.test.ts +261 -0
  128. package/tsconfig.build.json +8 -0
  129. package/tsconfig.json +27 -0
  130. package/vitest.config.ts +43 -0
package/README.md ADDED
@@ -0,0 +1,395 @@
1
+ # Cucumber Studio MCP Server
2
+
3
+ [![NPM Version](https://img.shields.io/npm/v/cucumberstudio-mcp)](https://www.npmjs.com/package/cucumberstudio-mcp)
4
+ [![NPM Downloads](https://img.shields.io/npm/dm/cucumberstudio-mcp)](https://www.npmjs.com/package/cucumberstudio-mcp)
5
+ [![Docker Pulls](https://img.shields.io/docker/pulls/herosizy/cucumberstudio-mcp)](https://hub.docker.com/r/herosizy/cucumberstudio-mcp)
6
+ [![GitHub Release](https://img.shields.io/github/v/release/HeroSizy/cucumberstudio-mcp)](https://github.com/HeroSizy/cucumberstudio-mcp/releases)
7
+ [![Build Status](https://img.shields.io/github/actions/workflow/status/HeroSizy/cucumberstudio-mcp/release.yml)](https://github.com/HeroSizy/cucumberstudio-mcp/actions)
8
+ [![Test Coverage](https://img.shields.io/badge/coverage-82%25-brightgreen)](https://github.com/HeroSizy/cucumberstudio-mcp)
9
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.8-blue)](https://www.typescriptlang.org/)
10
+ [![License](https://img.shields.io/github/license/HeroSizy/cucumberstudio-mcp)](https://github.com/HeroSizy/cucumberstudio-mcp/blob/master/LICENSE)
11
+
12
+ A Model Context Protocol (MCP) server that provides LLM access to Cucumber Studio's testing platform. This server enables AI assistants to retrieve test scenarios, action words, test runs, and project information from Cucumber Studio.
13
+
14
+ ## Features
15
+
16
+ - **Dual Transport Support** - STDIO and Streamable HTTP transports with session management
17
+ - **Project Management** - List and retrieve project details
18
+ - **Scenario Access** - Browse test scenarios and search by tags
19
+ - **Action Words** - Access reusable test steps and definitions
20
+ - **Test Execution** - View test runs, executions, and build information
21
+ - **Hot Reload Development** - Instant server restart on file changes with tsx --watch
22
+ - **Configurable Logging** - Structured logging with multiple output destinations
23
+ - **Comprehensive Error Handling** - Robust error handling with detailed feedback
24
+ - **Type Safety** - Full TypeScript implementation with Zod validation
25
+ - **Comprehensive Testing** - 82%+ test coverage with Vitest and MSW
26
+
27
+ ## Installation
28
+
29
+ ### Quick Start (Recommended)
30
+
31
+ Run directly with npx (no installation required):
32
+ ```bash
33
+ npx cucumberstudio-mcp
34
+ ```
35
+
36
+ Set your environment variables first:
37
+ ```bash
38
+ export CUCUMBERSTUDIO_ACCESS_TOKEN="your_token"
39
+ export CUCUMBERSTUDIO_CLIENT_ID="your_client_id"
40
+ export CUCUMBERSTUDIO_UID="your_uid"
41
+ ```
42
+
43
+ ### Development Installation
44
+
45
+ 1. Clone the repository:
46
+ ```bash
47
+ git clone https://github.com/HeroSizy/cucumberstudio-mcp.git
48
+ cd cucumberstudio-mcp
49
+ ```
50
+
51
+ 2. Install dependencies:
52
+ ```bash
53
+ npm install
54
+ ```
55
+
56
+ 3. Set up environment variables:
57
+ ```bash
58
+ cp .env.example .env
59
+ # Edit .env with your Cucumber Studio API credentials
60
+ ```
61
+
62
+ 4. Build the server:
63
+ ```bash
64
+ npm run build
65
+ ```
66
+
67
+ ## Docker Support
68
+
69
+ ### Using Pre-built Image (Recommended)
70
+
71
+ Run the official Docker image from Docker Hub:
72
+ ```bash
73
+ # With environment file
74
+ docker run --env-file .env herosizy/cucumberstudio-mcp
75
+
76
+ # With environment variables
77
+ docker run -e CUCUMBERSTUDIO_ACCESS_TOKEN=your_token \
78
+ -e CUCUMBERSTUDIO_CLIENT_ID=your_client_id \
79
+ -e CUCUMBERSTUDIO_UID=your_uid \
80
+ herosizy/cucumberstudio-mcp
81
+ ```
82
+
83
+ ### Using Docker Compose
84
+
85
+ 1. Set up environment variables:
86
+ ```bash
87
+ cp .env.example .env
88
+ # Edit .env with your Cucumber Studio API credentials
89
+ ```
90
+
91
+ 2. Update docker-compose.yml to use the pre-built image:
92
+ ```yaml
93
+ version: '3.8'
94
+ services:
95
+ cucumberstudio-mcp:
96
+ image: herosizy/cucumberstudio-mcp
97
+ env_file:
98
+ - .env
99
+ restart: unless-stopped
100
+ ports:
101
+ - "${MCP_PORT:-3000}:3000"
102
+ ```
103
+
104
+ 3. Run with Docker Compose:
105
+ ```bash
106
+ docker-compose up
107
+ ```
108
+
109
+ ### Building Locally
110
+
111
+ 1. Build the image:
112
+ ```bash
113
+ npm run docker:build
114
+ ```
115
+
116
+ 2. Run the container:
117
+ ```bash
118
+ npm run docker:run
119
+ ```
120
+
121
+ The Docker setup includes health checks and automatic restarts for production use.
122
+
123
+ ## Configuration
124
+
125
+ The server requires Cucumber Studio API credentials. Get these from your Cucumber Studio account settings:
126
+
127
+ ### Required Environment Variables
128
+ - `CUCUMBERSTUDIO_ACCESS_TOKEN` - Your API access token
129
+ - `CUCUMBERSTUDIO_CLIENT_ID` - Your client ID
130
+ - `CUCUMBERSTUDIO_UID` - Your user ID
131
+
132
+ ### Optional Configuration
133
+ - `CUCUMBERSTUDIO_BASE_URL` - API base URL (default: https://studio.cucumberstudio.com/api)
134
+ - `MCP_TRANSPORT` - Transport type: `stdio` (default), `http`, or `streamable-http`
135
+ - `MCP_PORT` - HTTP transport port (default: 3000)
136
+ - `MCP_HOST` - HTTP transport host (default: 0.0.0.0)
137
+ - `MCP_CORS_ORIGIN` - CORS origin setting (default: true)
138
+
139
+ ### Logging Configuration
140
+ - `LOG_LEVEL` - Log level: `error`, `warn`, `info`, `debug`, `trace` (default: info)
141
+ - `LOG_API_RESPONSES` - Log Cucumber Studio API responses (default: false)
142
+ - `LOG_REQUEST_BODIES` - Log API request bodies for debugging (default: false)
143
+ - `LOG_RESPONSE_BODIES` - Log API response bodies for debugging (default: false)
144
+ - `LOG_TRANSPORT` - Logging output: `console`, `stderr`, `file`, `none` (default: stderr)
145
+ - `LOG_FILE` - Log file path (required if LOG_TRANSPORT=file)
146
+
147
+ ## Usage
148
+
149
+ ### Transport Options
150
+
151
+ The server supports both STDIO and HTTP transports:
152
+
153
+ #### STDIO Transport (Default)
154
+ ```bash
155
+ # Development
156
+ npm run dev
157
+
158
+ # Production
159
+ npm start
160
+ ```
161
+
162
+ #### HTTP Transport
163
+ ```bash
164
+ # Development
165
+ npm run dev:http
166
+
167
+ # Production
168
+ npm run start:http
169
+ ```
170
+
171
+
172
+ ### Using with Claude Desktop
173
+
174
+ #### Option 1: NPX (Recommended)
175
+ ```json
176
+ {
177
+ "mcpServers": {
178
+ "cucumberstudio": {
179
+ "command": "npx",
180
+ "args": ["cucumberstudio-mcp"],
181
+ "env": {
182
+ "CUCUMBERSTUDIO_ACCESS_TOKEN": "your_token",
183
+ "CUCUMBERSTUDIO_CLIENT_ID": "your_client_id",
184
+ "CUCUMBERSTUDIO_UID": "your_uid"
185
+ }
186
+ }
187
+ }
188
+ }
189
+ ```
190
+
191
+ #### Option 2: Local Installation
192
+ ```json
193
+ {
194
+ "mcpServers": {
195
+ "cucumberstudio": {
196
+ "command": "node",
197
+ "args": ["/path/to/cucumberstudio-mcp/build/index.js"],
198
+ "env": {
199
+ "CUCUMBERSTUDIO_ACCESS_TOKEN": "your_token",
200
+ "CUCUMBERSTUDIO_CLIENT_ID": "your_client_id",
201
+ "CUCUMBERSTUDIO_UID": "your_uid"
202
+ }
203
+ }
204
+ }
205
+ }
206
+ ```
207
+
208
+ #### Option 3: Docker Hub Image
209
+ ```json
210
+ {
211
+ "mcpServers": {
212
+ "cucumberstudio": {
213
+ "command": "docker",
214
+ "args": ["run", "--rm", "-i", "--env-file", "/path/to/.env", "herosizy/cucumberstudio-mcp"]
215
+ }
216
+ }
217
+ }
218
+ ```
219
+
220
+ #### Option 4: Local Docker Build
221
+ ```json
222
+ {
223
+ "mcpServers": {
224
+ "cucumberstudio": {
225
+ "command": "docker",
226
+ "args": ["run", "--rm", "-i", "--env-file", "/path/to/.env", "cucumberstudio-mcp"]
227
+ }
228
+ }
229
+ }
230
+ ```
231
+
232
+ ## Available Tools
233
+
234
+ ### Project Tools
235
+ - `cucumberstudio_list_projects` - List all accessible projects
236
+ - `cucumberstudio_get_project` - Get detailed project information
237
+
238
+ ### Scenario Tools
239
+ - `cucumberstudio_list_scenarios` - List scenarios in a project
240
+ - `cucumberstudio_get_scenario` - Get detailed scenario information
241
+ - `cucumberstudio_find_scenarios_by_tags` - Find scenarios by tags
242
+
243
+ ### Action Word Tools
244
+ - `cucumberstudio_list_action_words` - List reusable action words
245
+ - `cucumberstudio_get_action_word` - Get detailed action word information
246
+ - `cucumberstudio_find_action_words_by_tags` - Find action words by tags
247
+
248
+ ### Test Execution Tools
249
+ - `cucumberstudio_list_test_runs` - List test runs
250
+ - `cucumberstudio_get_test_run` - Get detailed test run information
251
+ - `cucumberstudio_get_test_executions` - Get individual test results
252
+ - `cucumberstudio_list_builds` - List builds
253
+ - `cucumberstudio_get_build` - Get build details
254
+ - `cucumberstudio_list_execution_environments` - List execution environments
255
+
256
+ ## Development
257
+
258
+ ### Hot Reload Development
259
+ The server supports hot reload for rapid development:
260
+
261
+ ```bash
262
+ # STDIO transport with hot reload
263
+ npm run dev
264
+
265
+ # HTTP transport with hot reload
266
+ npm run dev:http
267
+ ```
268
+
269
+ Files are automatically recompiled and the server restarts when changes are detected.
270
+
271
+ ### Testing and Quality
272
+ ```bash
273
+ # Install dependencies
274
+ npm install
275
+
276
+ # Run type checking
277
+ npm run typecheck
278
+
279
+ # Run linting
280
+ npm run lint
281
+
282
+ # Build for production
283
+ npm run build
284
+
285
+ # Run tests
286
+ npm test
287
+
288
+ # Run tests in watch mode
289
+ npm run test:watch
290
+
291
+ # Run tests with coverage (82%+ coverage)
292
+ npm run test:coverage
293
+
294
+ # Run tests with UI
295
+ npm run test:ui
296
+ ```
297
+
298
+ ## Architecture
299
+
300
+ The server is built with a modular, production-ready architecture:
301
+
302
+ ### Core Technologies
303
+ - **TypeScript** - Full type safety with strict configuration
304
+ - **Dual Transports** - STDIO for local use, Streamable HTTP for remote access
305
+ - **Zod** - Runtime validation for API inputs and configuration
306
+ - **Axios** - HTTP client with comprehensive error handling and logging
307
+ - **MCP SDK** - Official Model Context Protocol implementation
308
+ - **Express** - HTTP server with CORS, security middleware, and session management
309
+ - **Vitest** - Modern testing framework with 82%+ code coverage
310
+ - **MSW** - Mock Service Worker for realistic API testing
311
+
312
+ ### Key Features
313
+ - **Session Management** - HTTP transport with session tracking and cleanup
314
+ - **Comprehensive Logging** - Structured logging with configurable outputs and levels
315
+ - **Error Handling** - Robust error handling with detailed feedback and recovery
316
+ - **Security** - Origin validation, CORS protection, and input sanitization
317
+ - **Health Monitoring** - Health check endpoints and request/response tracking
318
+ - **Development Workflow** - Hot reload, comprehensive testing, and Docker support
319
+
320
+ ## Testing
321
+
322
+ The project includes comprehensive test coverage:
323
+
324
+ ```bash
325
+ # Run all tests
326
+ npm test
327
+
328
+ # Run tests with coverage report
329
+ npm run test:coverage
330
+
331
+ # Run tests in watch mode (for development)
332
+ npm run test:watch
333
+ ```
334
+
335
+ Test coverage includes:
336
+ - Unit tests for all modules
337
+ - Integration tests for the MCP server
338
+ - Transport layer testing
339
+ - API client mocking and testing
340
+ - Configuration validation
341
+ - Error handling scenarios
342
+
343
+ ## Publishing and Releases
344
+
345
+ This project uses automated releases via GitHub Actions. When a version tag is pushed, it automatically:
346
+
347
+ 1. **Runs full test suite** - Ensures code quality and coverage
348
+ 2. **Publishes to NPM** - Makes the package available via `npx cucumberstudio-mcp`
349
+ 3. **Builds and publishes Docker image** - Pushes multi-platform images to Docker Hub
350
+ 4. **Creates GitHub release** - Generates release notes and links
351
+
352
+ ### Creating a Release
353
+
354
+ 1. Update the version in `package.json`:
355
+ ```bash
356
+ npm version patch|minor|major
357
+ ```
358
+
359
+ 2. Push the tag to trigger the release:
360
+ ```bash
361
+ git push origin --tags
362
+ ```
363
+
364
+ 3. The GitHub Action will automatically:
365
+ - Publish to NPM: https://www.npmjs.com/package/cucumberstudio-mcp
366
+ - Push to Docker Hub: https://hub.docker.com/r/herosizy/cucumberstudio-mcp
367
+ - Create a GitHub release with changelog
368
+
369
+ ### Required Secrets
370
+
371
+ For automated publishing, the following secrets must be configured in the GitHub repository:
372
+
373
+ - `NPM_TOKEN` - NPM authentication token
374
+ - `DOCKER_USERNAME` - Docker Hub username
375
+ - `DOCKER_PASSWORD` - Docker Hub password or access token
376
+
377
+ ## Contributing
378
+
379
+ 1. Fork the repository
380
+ 2. Create a feature branch
381
+ 3. Make your changes
382
+ 4. Add tests for new functionality
383
+ 5. Ensure all tests pass: `npm test`
384
+ 6. Submit a pull request
385
+
386
+ ## License
387
+
388
+ MIT License - see LICENSE file for details
389
+
390
+ ## Resources
391
+
392
+ - [Cucumber Studio API Documentation](https://studio-api.cucumberstudio.com/#introduction)
393
+ - [Cucumber Studio API Reference](https://github.com/SmartBear/cucumberstudio-api-documentation)
394
+ - [Model Context Protocol](https://modelcontextprotocol.io/)
395
+ - [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)
@@ -0,0 +1,49 @@
1
+ import { Config } from '../config/settings.js';
2
+ import { Logger } from '../utils/logger.js';
3
+ import { CucumberStudioResponse, CucumberStudioError, ListParams, Project, Scenario, ActionWord, Folder, TestRun, TestExecution, Build, ExecutionEnvironment } from './types.js';
4
+ export declare class CucumberStudioApiError extends Error {
5
+ status?: number | undefined;
6
+ details?: CucumberStudioError | undefined;
7
+ constructor(message: string, status?: number | undefined, details?: CucumberStudioError | undefined);
8
+ }
9
+ export declare class CucumberStudioApiClient {
10
+ private config;
11
+ private logger;
12
+ private client;
13
+ constructor(config: Config, logger: Logger);
14
+ /**
15
+ * Get logging configuration with safe defaults
16
+ */
17
+ private getLoggingConfig;
18
+ /**
19
+ * Sanitize headers to avoid logging sensitive information
20
+ */
21
+ private sanitizeHeaders;
22
+ /**
23
+ * Generic GET request handler
24
+ */
25
+ private get;
26
+ getProjects(params?: ListParams): Promise<CucumberStudioResponse<Project[]>>;
27
+ getProject(projectId: string): Promise<CucumberStudioResponse<Project>>;
28
+ getScenarios(projectId: string, params?: ListParams): Promise<CucumberStudioResponse<Scenario[]>>;
29
+ getScenario(projectId: string, scenarioId: string): Promise<CucumberStudioResponse<Scenario>>;
30
+ findScenariosByTag(projectId: string, tags: string, params?: ListParams): Promise<CucumberStudioResponse<Scenario[]>>;
31
+ getActionWords(projectId: string, params?: ListParams): Promise<CucumberStudioResponse<ActionWord[]>>;
32
+ getActionWord(projectId: string, actionWordId: string): Promise<CucumberStudioResponse<ActionWord>>;
33
+ findActionWordsByTag(projectId: string, tags: string, params?: ListParams): Promise<CucumberStudioResponse<ActionWord[]>>;
34
+ getFolders(projectId: string, params?: ListParams): Promise<CucumberStudioResponse<Folder[]>>;
35
+ getFolder(projectId: string, folderId: string): Promise<CucumberStudioResponse<Folder>>;
36
+ getFolderChildren(projectId: string, folderId: string, params?: ListParams): Promise<CucumberStudioResponse<Folder[]>>;
37
+ getFolderScenarios(projectId: string, folderId: string, params?: ListParams): Promise<CucumberStudioResponse<Scenario[]>>;
38
+ getTestRuns(projectId: string, params?: ListParams): Promise<CucumberStudioResponse<TestRun[]>>;
39
+ getTestRun(projectId: string, testRunId: string): Promise<CucumberStudioResponse<TestRun>>;
40
+ getTestExecutions(projectId: string, testRunId: string, params?: ListParams): Promise<CucumberStudioResponse<TestExecution[]>>;
41
+ getBuilds(projectId: string, params?: ListParams): Promise<CucumberStudioResponse<Build[]>>;
42
+ getBuild(projectId: string, buildId: string): Promise<CucumberStudioResponse<Build>>;
43
+ getExecutionEnvironments(projectId: string, params?: ListParams): Promise<CucumberStudioResponse<ExecutionEnvironment[]>>;
44
+ /**
45
+ * Test the connection to Cucumber Studio API
46
+ */
47
+ testConnection(): Promise<boolean>;
48
+ }
49
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,204 @@
1
+ import axios from 'axios';
2
+ import { API_VERSION_HEADER, API_TIMEOUT, REDACTED_STRING } from '../constants.js';
3
+ export class CucumberStudioApiError extends Error {
4
+ status;
5
+ details;
6
+ constructor(message, status, details) {
7
+ super(message);
8
+ this.status = status;
9
+ this.details = details;
10
+ this.name = 'CucumberStudioApiError';
11
+ }
12
+ }
13
+ export class CucumberStudioApiClient {
14
+ config;
15
+ logger;
16
+ client;
17
+ constructor(config, logger) {
18
+ this.config = config;
19
+ this.logger = logger;
20
+ this.client = axios.create({
21
+ baseURL: config.cucumberStudio.baseUrl,
22
+ headers: {
23
+ Accept: API_VERSION_HEADER,
24
+ 'Content-Type': 'application/json',
25
+ 'access-token': config.cucumberStudio.accessToken,
26
+ client: config.cucumberStudio.clientId,
27
+ uid: config.cucumberStudio.uid,
28
+ },
29
+ timeout: API_TIMEOUT,
30
+ });
31
+ // Add request interceptor for logging
32
+ this.client.interceptors.request.use((config) => {
33
+ this.logger.debug(`🚀 Request: ${config.method?.toUpperCase()} ${config.url}`, {
34
+ headers: this.sanitizeHeaders(config.headers),
35
+ params: config.params,
36
+ bodySize: config.data ? JSON.stringify(config.data).length : 0,
37
+ });
38
+ if (this.getLoggingConfig().logRequestBodies && config.data) {
39
+ this.logger.trace('📤 Request Body:', config.data);
40
+ }
41
+ return config;
42
+ }, (error) => {
43
+ this.logger.error('❌ Request Error:', error);
44
+ return Promise.reject(error);
45
+ });
46
+ // Add response interceptor for logging and error handling
47
+ this.client.interceptors.response.use((response) => {
48
+ this.logger.debug(`✅ Response: ${response.status} ${response.config.method?.toUpperCase()} ${response.config.url}`, {
49
+ status: response.status,
50
+ statusText: response.statusText,
51
+ headers: response.headers,
52
+ dataSize: response.data ? JSON.stringify(response.data).length : 0,
53
+ });
54
+ if (this.getLoggingConfig().logApiResponses || this.getLoggingConfig().logResponseBodies) {
55
+ this.logger.debug('📥 Cucumber Studio Response:', {
56
+ status: response.status,
57
+ url: response.config.url,
58
+ data: response.data,
59
+ });
60
+ }
61
+ return response;
62
+ }, (error) => {
63
+ if (error.response) {
64
+ const status = error.response.status;
65
+ const data = error.response.data;
66
+ this.logger.error(`❌ API Error: ${status} ${error.config?.method?.toUpperCase()} ${error.config?.url}`, {
67
+ status,
68
+ statusText: error.response.statusText,
69
+ data,
70
+ headers: error.response.headers,
71
+ });
72
+ let message = `API request failed with status ${status}`;
73
+ if (data?.errors?.length > 0) {
74
+ message = data.errors.map((e) => e.detail).join('; ');
75
+ }
76
+ throw new CucumberStudioApiError(message, status, data);
77
+ }
78
+ else if (error.request) {
79
+ this.logger.error('🔌 No Response:', {
80
+ url: error.config?.url,
81
+ timeout: error.code === 'ECONNABORTED',
82
+ });
83
+ throw new CucumberStudioApiError('No response received from Cucumber Studio API');
84
+ }
85
+ else {
86
+ this.logger.error('⚙️ Request Setup Error:', error.message);
87
+ throw new CucumberStudioApiError(`Request setup failed: ${error.message}`);
88
+ }
89
+ });
90
+ }
91
+ /**
92
+ * Get logging configuration with safe defaults
93
+ */
94
+ getLoggingConfig() {
95
+ return (this.config.logging || {
96
+ level: 'info',
97
+ logApiResponses: false,
98
+ logRequestBodies: false,
99
+ logResponseBodies: false,
100
+ });
101
+ }
102
+ /**
103
+ * Sanitize headers to avoid logging sensitive information
104
+ */
105
+ sanitizeHeaders(headers) {
106
+ if (!headers)
107
+ return headers;
108
+ const sanitized = { ...headers };
109
+ const sensitiveKeys = ['access-token', 'authorization', 'cookie', 'x-api-key'];
110
+ for (const key of sensitiveKeys) {
111
+ if (key in sanitized) {
112
+ sanitized[key] = REDACTED_STRING;
113
+ }
114
+ }
115
+ return sanitized;
116
+ }
117
+ /**
118
+ * Generic GET request handler
119
+ */
120
+ async get(endpoint, params) {
121
+ const response = await this.client.get(endpoint, { params });
122
+ return response.data;
123
+ }
124
+ // PROJECT ENDPOINTS
125
+ async getProjects(params) {
126
+ return this.get('/projects', params);
127
+ }
128
+ async getProject(projectId) {
129
+ return this.get(`/projects/${projectId}`);
130
+ }
131
+ // SCENARIO ENDPOINTS
132
+ async getScenarios(projectId, params) {
133
+ return this.get(`/projects/${projectId}/scenarios`, params);
134
+ }
135
+ async getScenario(projectId, scenarioId) {
136
+ return this.get(`/projects/${projectId}/scenarios/${scenarioId}`);
137
+ }
138
+ async findScenariosByTag(projectId, tags, params) {
139
+ return this.get(`/projects/${projectId}/scenarios/find_by_tags`, {
140
+ ...params,
141
+ 'filter[tags]': tags,
142
+ });
143
+ }
144
+ // ACTION WORD ENDPOINTS
145
+ async getActionWords(projectId, params) {
146
+ return this.get(`/projects/${projectId}/actionwords`, params);
147
+ }
148
+ async getActionWord(projectId, actionWordId) {
149
+ return this.get(`/projects/${projectId}/actionwords/${actionWordId}`);
150
+ }
151
+ async findActionWordsByTag(projectId, tags, params) {
152
+ return this.get(`/projects/${projectId}/actionwords/find_by_tags`, {
153
+ ...params,
154
+ 'filter[tags]': tags,
155
+ });
156
+ }
157
+ // FOLDER ENDPOINTS
158
+ async getFolders(projectId, params) {
159
+ return this.get(`/projects/${projectId}/folders`, params);
160
+ }
161
+ async getFolder(projectId, folderId) {
162
+ return this.get(`/projects/${projectId}/folders/${folderId}`);
163
+ }
164
+ async getFolderChildren(projectId, folderId, params) {
165
+ return this.get(`/projects/${projectId}/folders/${folderId}/children`, params);
166
+ }
167
+ async getFolderScenarios(projectId, folderId, params) {
168
+ return this.get(`/projects/${projectId}/folders/${folderId}/scenarios`, params);
169
+ }
170
+ // TEST RUN ENDPOINTS
171
+ async getTestRuns(projectId, params) {
172
+ return this.get(`/projects/${projectId}/test_runs`, params);
173
+ }
174
+ async getTestRun(projectId, testRunId) {
175
+ return this.get(`/projects/${projectId}/test_runs/${testRunId}`);
176
+ }
177
+ async getTestExecutions(projectId, testRunId, params) {
178
+ return this.get(`/projects/${projectId}/test_runs/${testRunId}/test_executions`, params);
179
+ }
180
+ // BUILD ENDPOINTS
181
+ async getBuilds(projectId, params) {
182
+ return this.get(`/projects/${projectId}/builds`, params);
183
+ }
184
+ async getBuild(projectId, buildId) {
185
+ return this.get(`/projects/${projectId}/builds/${buildId}`);
186
+ }
187
+ // EXECUTION ENVIRONMENT ENDPOINTS
188
+ async getExecutionEnvironments(projectId, params) {
189
+ return this.get(`/projects/${projectId}/execution_environments`, params);
190
+ }
191
+ /**
192
+ * Test the connection to Cucumber Studio API
193
+ */
194
+ async testConnection() {
195
+ try {
196
+ await this.getProjects({ 'page[size]': 1 });
197
+ return true;
198
+ }
199
+ catch {
200
+ return false;
201
+ }
202
+ }
203
+ }
204
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}