pinpointmcp 0.1.1 → 0.1.2
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 +316 -7
- package/dist/client-holder.d.ts +4 -1
- package/dist/client-holder.js +12 -1
- package/dist/client.d.ts +20 -1
- package/dist/client.js +180 -13
- package/dist/config-store.d.ts +1 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.js +3 -0
- package/dist/index.js +26 -4
- package/dist/prompts/index.d.ts +1 -0
- package/dist/prompts/index.js +1 -0
- package/dist/prompts/review-request.d.ts +3 -0
- package/dist/prompts/review-request.js +38 -0
- package/dist/resources/bugs.js +1 -1
- package/dist/resources/index.d.ts +2 -0
- package/dist/resources/index.js +2 -0
- package/dist/resources/projects.d.ts +4 -0
- package/dist/resources/projects.js +46 -0
- package/dist/resources/requests.d.ts +3 -0
- package/dist/resources/requests.js +22 -0
- package/dist/tools/add-environment.d.ts +3 -0
- package/dist/tools/add-environment.js +31 -0
- package/dist/tools/configure.js +8 -4
- package/dist/tools/create-project.d.ts +3 -0
- package/dist/tools/create-project.js +62 -0
- package/dist/tools/create-request.d.ts +3 -0
- package/dist/tools/create-request.js +47 -0
- package/dist/tools/delete-project.d.ts +3 -0
- package/dist/tools/delete-project.js +20 -0
- package/dist/tools/download-report.d.ts +3 -0
- package/dist/tools/download-report.js +19 -0
- package/dist/tools/get-report.d.ts +3 -0
- package/dist/tools/get-report.js +32 -0
- package/dist/tools/get-request.d.ts +3 -0
- package/dist/tools/get-request.js +31 -0
- package/dist/tools/index.d.ts +14 -0
- package/dist/tools/index.js +14 -0
- package/dist/tools/list-bugs.js +25 -3
- package/dist/tools/list-dispatch-reports.d.ts +3 -0
- package/dist/tools/list-dispatch-reports.js +23 -0
- package/dist/tools/list-environments.d.ts +3 -0
- package/dist/tools/list-environments.js +27 -0
- package/dist/tools/list-projects.d.ts +3 -0
- package/dist/tools/list-projects.js +26 -0
- package/dist/tools/list-requests.d.ts +3 -0
- package/dist/tools/list-requests.js +35 -0
- package/dist/tools/remove-environment.d.ts +3 -0
- package/dist/tools/remove-environment.js +21 -0
- package/dist/tools/update-environment.d.ts +3 -0
- package/dist/tools/update-environment.js +37 -0
- package/dist/tools/update-project.d.ts +3 -0
- package/dist/tools/update-project.js +36 -0
- package/dist/types.d.ts +117 -0
- package/dist/types.js +26 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Pinpoint MCP Server
|
|
2
2
|
|
|
3
|
-
MCP server for the [Pinpoint](https://testwithpinpoint.com) bug tracking platform. Enables AI agents in Claude Code, Cursor, and other MCP-compatible environments to
|
|
3
|
+
MCP server for the [Pinpoint](https://testwithpinpoint.com) testing and bug tracking platform. Enables AI agents in Claude Code, Cursor, and other MCP-compatible environments to manage projects, environments, test requests, bug reports, and autonomously resolve reported issues.
|
|
4
4
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
@@ -98,6 +98,75 @@ Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_
|
|
|
98
98
|
}
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
+
## Tech Stack
|
|
102
|
+
|
|
103
|
+
- **Runtime:** Node.js >= 18
|
|
104
|
+
- **Language:** TypeScript 5.9+
|
|
105
|
+
- **MCP SDK:** @modelcontextprotocol/sdk 1.27+
|
|
106
|
+
- **Validation:** Zod 4.3+
|
|
107
|
+
- **Testing:** Vitest 4.0+
|
|
108
|
+
- **Build:** TypeScript compiler (tsc)
|
|
109
|
+
|
|
110
|
+
## Project Structure
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
src/
|
|
114
|
+
├── index.ts # Main server entry point
|
|
115
|
+
├── client.ts # Pinpoint API client
|
|
116
|
+
├── client-holder.ts # Client lifecycle management
|
|
117
|
+
├── config.ts # Configuration loading
|
|
118
|
+
├── config-store.ts # Persistent config storage
|
|
119
|
+
├── types.ts # Shared TypeScript types
|
|
120
|
+
├── tools/ # MCP tool implementations
|
|
121
|
+
│ ├── configure.ts # Runtime configuration
|
|
122
|
+
│ ├── list-bugs.ts # Bug listing
|
|
123
|
+
│ ├── get-bug.ts # Bug details
|
|
124
|
+
│ ├── update-bug-status.ts # Bug status updates
|
|
125
|
+
│ ├── list-projects.ts # Project listing
|
|
126
|
+
│ ├── create-project.ts # Project creation
|
|
127
|
+
│ ├── update-project.ts # Project updates
|
|
128
|
+
│ ├── delete-project.ts # Project deletion
|
|
129
|
+
│ ├── list-environments.ts # Environment listing
|
|
130
|
+
│ ├── add-environment.ts # Environment creation
|
|
131
|
+
│ ├── update-environment.ts# Environment updates
|
|
132
|
+
│ ├── remove-environment.ts# Environment deletion
|
|
133
|
+
│ ├── list-requests.ts # Test request listing
|
|
134
|
+
│ ├── create-request.ts # Test request creation
|
|
135
|
+
│ ├── get-request.ts # Test request details
|
|
136
|
+
│ ├── get-report.ts # Report details
|
|
137
|
+
│ ├── download-report.ts # Report download URLs
|
|
138
|
+
│ └── list-dispatch-reports.ts # Reports for a dispatch
|
|
139
|
+
├── resources/ # MCP resource implementations
|
|
140
|
+
│ ├── bugs.ts # Bug resources
|
|
141
|
+
│ ├── projects.ts # Project resources
|
|
142
|
+
│ └── requests.ts # Request resources
|
|
143
|
+
└── prompts/ # MCP prompt templates
|
|
144
|
+
├── solve-bug.ts # Bug solving workflow
|
|
145
|
+
└── review-request.ts # Test request review
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Build and Run
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# Install dependencies
|
|
152
|
+
npm install
|
|
153
|
+
|
|
154
|
+
# Build TypeScript to JavaScript
|
|
155
|
+
npm run build
|
|
156
|
+
|
|
157
|
+
# Run the server (after building)
|
|
158
|
+
npm start
|
|
159
|
+
|
|
160
|
+
# Run tests
|
|
161
|
+
npm test
|
|
162
|
+
|
|
163
|
+
# Run tests in watch mode
|
|
164
|
+
npm run test:watch
|
|
165
|
+
|
|
166
|
+
# Development mode (watch for changes)
|
|
167
|
+
npm run dev
|
|
168
|
+
```
|
|
169
|
+
|
|
101
170
|
## Tools
|
|
102
171
|
|
|
103
172
|
### configure
|
|
@@ -115,18 +184,21 @@ Configure the server with an API token at runtime. Validates the token before pe
|
|
|
115
184
|
- On validation failure: returns an error without persisting
|
|
116
185
|
- On write failure: configures the current session and warns about persistence
|
|
117
186
|
|
|
118
|
-
###
|
|
187
|
+
### Bug Management
|
|
188
|
+
|
|
189
|
+
#### list_bugs
|
|
119
190
|
|
|
120
191
|
List bug reports filtered by status and project.
|
|
121
192
|
|
|
122
193
|
| Parameter | Type | Required | Default | Description |
|
|
123
194
|
|-----------|------|----------|---------|-------------|
|
|
124
|
-
| `status` | string | No |
|
|
195
|
+
| `status` | string | No | all non-closed | Filter: `open`, `in_progress`, `resolved`, `closed`. Omit to see all active bugs. Supports comma-separated values (e.g., `"open,in_progress"`) |
|
|
125
196
|
| `project` | string | No | n/a | Filter by project name |
|
|
126
|
-
| `
|
|
197
|
+
| `cursor` | string | No | n/a | Cursor token from a previous response for efficient pagination through large lists |
|
|
198
|
+
| `page` | number | No | `0` | Page number (0-indexed). Ignored when `cursor` is provided |
|
|
127
199
|
| `size` | number | No | `20` | Page size (max 200) |
|
|
128
200
|
|
|
129
|
-
|
|
201
|
+
#### get_bug
|
|
130
202
|
|
|
131
203
|
Get detailed information about a specific bug report, including description, reproduction steps, expected/actual behavior, and environment.
|
|
132
204
|
|
|
@@ -134,7 +206,7 @@ Get detailed information about a specific bug report, including description, rep
|
|
|
134
206
|
|-----------|------|----------|-------------|
|
|
135
207
|
| `id` | string | Yes | Bug report UUID |
|
|
136
208
|
|
|
137
|
-
|
|
209
|
+
#### update_bug_status
|
|
138
210
|
|
|
139
211
|
Update the status of a bug report.
|
|
140
212
|
|
|
@@ -144,15 +216,236 @@ Update the status of a bug report.
|
|
|
144
216
|
| `status` | enum | Yes | New status: `open`, `in_progress`, `resolved`, `closed` |
|
|
145
217
|
| `resolution` | string | No | Resolution notes (recommended when resolving) |
|
|
146
218
|
|
|
219
|
+
#### Bug Workflow
|
|
220
|
+
|
|
221
|
+
These examples show how to combine the bug management tools into a practical workflow for tracking and resolving bugs before they reach production.
|
|
222
|
+
|
|
223
|
+
##### See all active bugs
|
|
224
|
+
|
|
225
|
+
Call `list_bugs` with no `status` parameter to retrieve every bug that is not closed. This returns all OPEN, IN_PROGRESS, and RESOLVED bugs in a single request, giving you a complete picture of outstanding work.
|
|
226
|
+
|
|
227
|
+
```json
|
|
228
|
+
{ "project": "my-app" }
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
##### Filter by project
|
|
232
|
+
|
|
233
|
+
When working on a specific codebase, pass the `project` parameter to narrow results to bugs relevant to that project.
|
|
234
|
+
|
|
235
|
+
```json
|
|
236
|
+
{ "project": "checkout-service" }
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
This focuses your view so you can address bugs in the code you are actively changing.
|
|
240
|
+
|
|
241
|
+
##### Triage with multi-status filtering
|
|
242
|
+
|
|
243
|
+
Use comma-separated status values to see only bugs that still need attention. For example, filtering to `"open,in_progress"` excludes resolved bugs so you can focus on what remains.
|
|
244
|
+
|
|
245
|
+
```json
|
|
246
|
+
{ "status": "open,in_progress", "project": "checkout-service" }
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
##### Investigate and fix a bug
|
|
250
|
+
|
|
251
|
+
Once you identify a bug to work on, use the full lifecycle:
|
|
252
|
+
|
|
253
|
+
1. **List bugs** to find candidates:
|
|
254
|
+
```json
|
|
255
|
+
list_bugs { "status": "open", "project": "checkout-service" }
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
2. **Get details** to understand the issue, including reproduction steps and expected behavior:
|
|
259
|
+
```json
|
|
260
|
+
get_bug { "id": "bug-uuid-here" }
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
3. **Mark as in progress** to signal you are actively working on it:
|
|
264
|
+
```json
|
|
265
|
+
update_bug_status { "id": "bug-uuid-here", "status": "in_progress" }
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
4. **Fix the code** in your editor or through your AI agent.
|
|
269
|
+
|
|
270
|
+
5. **Mark as resolved** with notes describing what changed:
|
|
271
|
+
```json
|
|
272
|
+
update_bug_status { "id": "bug-uuid-here", "status": "resolved", "resolution": "Fixed null check in payment validation; added unit test" }
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
##### Paginate large bug lists with cursor
|
|
276
|
+
|
|
277
|
+
For projects with many bugs, use cursor-based pagination to walk through results efficiently. The response includes `hasMore` and `nextCursor` fields when additional pages exist.
|
|
278
|
+
|
|
279
|
+
First request:
|
|
280
|
+
```json
|
|
281
|
+
list_bugs { "project": "large-project", "size": 50 }
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
If the response contains `"hasMore": true` and a `"nextCursor"` value, pass that cursor to fetch the next page:
|
|
285
|
+
```json
|
|
286
|
+
list_bugs { "project": "large-project", "size": 50, "cursor": "returned-cursor-token" }
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Continue until `hasMore` is `false`. When a `cursor` is provided, the `page` parameter is ignored, so you do not need to track page numbers manually.
|
|
290
|
+
|
|
291
|
+
### Project Management
|
|
292
|
+
|
|
293
|
+
#### list_projects
|
|
294
|
+
|
|
295
|
+
List all projects for your organization.
|
|
296
|
+
|
|
297
|
+
| Parameter | Type | Required | Default | Description |
|
|
298
|
+
|-----------|------|----------|---------|-------------|
|
|
299
|
+
| `page` | number | No | `0` | Page number (0-indexed) |
|
|
300
|
+
| `size` | number | No | `20` | Page size (max 200) |
|
|
301
|
+
|
|
302
|
+
#### create_project
|
|
303
|
+
|
|
304
|
+
Create a new project in your organization.
|
|
305
|
+
|
|
306
|
+
| Parameter | Type | Required | Description |
|
|
307
|
+
|-----------|------|----------|-------------|
|
|
308
|
+
| `name` | string | Yes | Project name |
|
|
309
|
+
| `description` | string | No | Project description |
|
|
310
|
+
| `type` | string | No | Project type (UI, API, CLI, MCP) |
|
|
311
|
+
|
|
312
|
+
#### update_project
|
|
313
|
+
|
|
314
|
+
Update a project's name, description, or type.
|
|
315
|
+
|
|
316
|
+
| Parameter | Type | Required | Description |
|
|
317
|
+
|-----------|------|----------|-------------|
|
|
318
|
+
| `projectId` | string | Yes | Project UUID |
|
|
319
|
+
| `name` | string | No | New project name |
|
|
320
|
+
| `description` | string | No | New project description |
|
|
321
|
+
| `type` | string | No | New project type |
|
|
322
|
+
|
|
323
|
+
#### delete_project
|
|
324
|
+
|
|
325
|
+
Delete a project by ID.
|
|
326
|
+
|
|
327
|
+
| Parameter | Type | Required | Description |
|
|
328
|
+
|-----------|------|----------|-------------|
|
|
329
|
+
| `id` | string | Yes | Project UUID |
|
|
330
|
+
|
|
331
|
+
### Environment Management
|
|
332
|
+
|
|
333
|
+
#### list_environments
|
|
334
|
+
|
|
335
|
+
List environments for a project.
|
|
336
|
+
|
|
337
|
+
| Parameter | Type | Required | Description |
|
|
338
|
+
|-----------|------|----------|-------------|
|
|
339
|
+
| `projectId` | string | Yes | Project UUID |
|
|
340
|
+
|
|
341
|
+
#### add_environment
|
|
342
|
+
|
|
343
|
+
Add a new environment to a project.
|
|
344
|
+
|
|
345
|
+
| Parameter | Type | Required | Description |
|
|
346
|
+
|-----------|------|----------|-------------|
|
|
347
|
+
| `projectId` | string | Yes | Project UUID |
|
|
348
|
+
| `name` | string | Yes | Environment name (e.g., staging, production) |
|
|
349
|
+
| `baseUrl` | string | Yes | Base URL for the environment |
|
|
350
|
+
| `isDefault` | boolean | No | Whether this is the default environment |
|
|
351
|
+
|
|
352
|
+
#### update_environment
|
|
353
|
+
|
|
354
|
+
Update an environment's configuration.
|
|
355
|
+
|
|
356
|
+
| Parameter | Type | Required | Description |
|
|
357
|
+
|-----------|------|----------|-------------|
|
|
358
|
+
| `projectId` | string | Yes | Project UUID |
|
|
359
|
+
| `environmentId` | string | Yes | Environment UUID to update |
|
|
360
|
+
| `name` | string | No | New environment name |
|
|
361
|
+
| `baseUrl` | string | No | New base URL |
|
|
362
|
+
| `isDefault` | boolean | No | Set as the default environment |
|
|
363
|
+
|
|
364
|
+
#### remove_environment
|
|
365
|
+
|
|
366
|
+
Remove an environment from a project.
|
|
367
|
+
|
|
368
|
+
| Parameter | Type | Required | Description |
|
|
369
|
+
|-----------|------|----------|-------------|
|
|
370
|
+
| `projectId` | string | Yes | Project UUID |
|
|
371
|
+
| `environmentId` | string | Yes | Environment UUID to remove |
|
|
372
|
+
|
|
373
|
+
### Test Request Management
|
|
374
|
+
|
|
375
|
+
#### list_requests
|
|
376
|
+
|
|
377
|
+
List test requests for your account.
|
|
378
|
+
|
|
379
|
+
| Parameter | Type | Required | Default | Description |
|
|
380
|
+
|-----------|------|----------|---------|-------------|
|
|
381
|
+
| `page` | number | No | `0` | Page number (0-indexed) |
|
|
382
|
+
| `size` | number | No | `20` | Page size (max 200) |
|
|
383
|
+
|
|
384
|
+
#### create_request
|
|
385
|
+
|
|
386
|
+
Create a new manual test request (dispatch).
|
|
387
|
+
|
|
388
|
+
| Parameter | Type | Required | Description |
|
|
389
|
+
|-----------|------|----------|-------------|
|
|
390
|
+
| `projectId` | string | Yes | Project UUID to dispatch tests for |
|
|
391
|
+
| `environment` | string | No | Target environment (e.g., staging, production) |
|
|
392
|
+
| `buildUrl` | string | No | CI/CD build URL |
|
|
393
|
+
| `commitSha` | string | No | Git commit SHA |
|
|
394
|
+
| `branch` | string | No | Git branch name |
|
|
395
|
+
| `triggeredBy` | string | No | Who triggered this request |
|
|
396
|
+
|
|
397
|
+
#### get_request
|
|
398
|
+
|
|
399
|
+
Get detailed information about a specific dispatch.
|
|
400
|
+
|
|
401
|
+
| Parameter | Type | Required | Description |
|
|
402
|
+
|-----------|------|----------|-------------|
|
|
403
|
+
| `id` | string | Yes | Dispatch UUID |
|
|
404
|
+
|
|
405
|
+
### Report Management
|
|
406
|
+
|
|
407
|
+
#### get_report
|
|
408
|
+
|
|
409
|
+
Get detailed information about a specific report.
|
|
410
|
+
|
|
411
|
+
| Parameter | Type | Required | Description |
|
|
412
|
+
|-----------|------|----------|-------------|
|
|
413
|
+
| `id` | string | Yes | Report UUID |
|
|
414
|
+
|
|
415
|
+
#### download_report
|
|
416
|
+
|
|
417
|
+
Get a presigned download URL for a report attachment.
|
|
418
|
+
|
|
419
|
+
| Parameter | Type | Required | Description |
|
|
420
|
+
|-----------|------|----------|-------------|
|
|
421
|
+
| `id` | string | Yes | Report UUID |
|
|
422
|
+
|
|
423
|
+
**Note:** Presigned URLs expire in 1 hour.
|
|
424
|
+
|
|
425
|
+
#### list_dispatch_reports
|
|
426
|
+
|
|
427
|
+
List all reports for a specific dispatch event.
|
|
428
|
+
|
|
429
|
+
| Parameter | Type | Required | Description |
|
|
430
|
+
|-----------|------|----------|-------------|
|
|
431
|
+
| `dispatch_id` | string | Yes | Dispatch event UUID |
|
|
432
|
+
|
|
147
433
|
## Resources
|
|
148
434
|
|
|
435
|
+
Resources provide read-only access to Pinpoint data via URIs.
|
|
436
|
+
|
|
149
437
|
| URI | Format | Description |
|
|
150
438
|
|-----|--------|-------------|
|
|
151
|
-
| `pinpoint://bugs` | JSON | All
|
|
439
|
+
| `pinpoint://bugs` | JSON | All non-closed bugs as a JSON array (OPEN, IN_PROGRESS, RESOLVED) |
|
|
152
440
|
| `pinpoint://bugs/{id}` | Markdown | Detailed bug report rendered as Markdown |
|
|
441
|
+
| `pinpoint://projects` | JSON | All projects as a JSON array |
|
|
442
|
+
| `pinpoint://projects/{id}` | Markdown | Detailed project information rendered as Markdown |
|
|
443
|
+
| `pinpoint://requests/{id}` | Markdown | Detailed test request information rendered as Markdown |
|
|
153
444
|
|
|
154
445
|
## Prompts
|
|
155
446
|
|
|
447
|
+
Prompts provide structured workflows for common tasks.
|
|
448
|
+
|
|
156
449
|
### solve_bug
|
|
157
450
|
|
|
158
451
|
Structured prompt for analyzing and fixing a specific bug. Assembles the title, description, reproduction steps, expected/actual behavior, and environment into a context block, then asks the agent to identify the root cause, implement a fix, and create a merge request.
|
|
@@ -161,6 +454,20 @@ Structured prompt for analyzing and fixing a specific bug. Assembles the title,
|
|
|
161
454
|
|----------|------|----------|-------------|
|
|
162
455
|
| `bug_id` | string | Yes | UUID of the bug to solve |
|
|
163
456
|
|
|
457
|
+
### review_request
|
|
458
|
+
|
|
459
|
+
Analyze test request results and associated reports. Gathers all reports for a dispatch event and asks the agent to identify patterns across bugs and suggest improvements.
|
|
460
|
+
|
|
461
|
+
| Argument | Type | Required | Description |
|
|
462
|
+
|----------|------|----------|-------------|
|
|
463
|
+
| `request_id` | string | Yes | UUID of the test request to review |
|
|
464
|
+
|
|
465
|
+
## Prerequisites
|
|
466
|
+
|
|
467
|
+
- **Node.js:** Version 18 or higher
|
|
468
|
+
- **Pinpoint Account:** Sign up at [testwithpinpoint.com](https://testwithpinpoint.com)
|
|
469
|
+
- **API Token:** Generate from the Pinpoint dashboard (Settings > API Tokens)
|
|
470
|
+
|
|
164
471
|
## Troubleshooting
|
|
165
472
|
|
|
166
473
|
- **Server starts but tools return setup guidance:** No token is configured. Either set `PINPOINT_TOKEN`, create the dotfile, or ask the agent to call the `configure` tool.
|
|
@@ -169,3 +476,5 @@ Structured prompt for analyzing and fixing a specific bug. Assembles the title,
|
|
|
169
476
|
- **"Authentication failed" on tool calls:** Your stored or environment token may have expired. Re-run the `configure` tool with a fresh token.
|
|
170
477
|
- **Connection errors:** Check `PINPOINT_API_URL` and confirm network connectivity to the API.
|
|
171
478
|
- **Server not discovered by Claude Code:** Ensure `.mcp.json` exists in the project root and that `npm run build` has been executed so `dist/index.js` is present.
|
|
479
|
+
- **TypeScript compilation errors:** Ensure you have TypeScript 5.9+ installed and run `npm install` to install dependencies.
|
|
480
|
+
- **Test failures:** Run `npm test` to execute the test suite. Ensure all dependencies are installed and the build is up to date.
|
package/dist/client-holder.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { PinpointClient } from "./client.js";
|
|
2
2
|
export declare class ClientHolder {
|
|
3
3
|
private client;
|
|
4
|
-
|
|
4
|
+
private customerId;
|
|
5
|
+
constructor(client?: PinpointClient | null, customerId?: string | null);
|
|
5
6
|
isConfigured(): boolean;
|
|
6
7
|
getClient(): PinpointClient;
|
|
8
|
+
getCustomerId(): string;
|
|
7
9
|
setClient(client: PinpointClient): void;
|
|
10
|
+
setCustomerId(customerId: string): void;
|
|
8
11
|
}
|
package/dist/client-holder.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export class ClientHolder {
|
|
2
2
|
client;
|
|
3
|
-
|
|
3
|
+
customerId;
|
|
4
|
+
constructor(client = null, customerId = null) {
|
|
4
5
|
this.client = client;
|
|
6
|
+
this.customerId = customerId;
|
|
5
7
|
}
|
|
6
8
|
isConfigured() {
|
|
7
9
|
return this.client !== null;
|
|
@@ -12,7 +14,16 @@ export class ClientHolder {
|
|
|
12
14
|
}
|
|
13
15
|
return this.client;
|
|
14
16
|
}
|
|
17
|
+
getCustomerId() {
|
|
18
|
+
if (!this.customerId) {
|
|
19
|
+
throw new Error("Customer ID is not available. Call the configure tool first.");
|
|
20
|
+
}
|
|
21
|
+
return this.customerId;
|
|
22
|
+
}
|
|
15
23
|
setClient(client) {
|
|
16
24
|
this.client = client;
|
|
17
25
|
}
|
|
26
|
+
setCustomerId(customerId) {
|
|
27
|
+
this.customerId = customerId;
|
|
28
|
+
}
|
|
18
29
|
}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,10 +1,29 @@
|
|
|
1
|
-
import { BugReport, PaginatedResponse, ListBugsOptions } from "./types.js";
|
|
1
|
+
import { BugReport, PaginatedResponse, CursorPageResponse, ListBugsOptions, Project, TestRequest, DispatchResponse, Report, MeResponse, CreateProjectRequest, UpdateProjectRequest, ManualDispatchRequest, Environment, CreateEnvironmentRequest, UpdateEnvironmentRequest } from "./types.js";
|
|
2
2
|
export declare class PinpointClient {
|
|
3
3
|
private baseUrl;
|
|
4
4
|
private token;
|
|
5
5
|
constructor(baseUrl: string, token: string);
|
|
6
6
|
listBugs(options?: ListBugsOptions): Promise<PaginatedResponse<BugReport>>;
|
|
7
|
+
listBugsWithCursor(options?: ListBugsOptions): Promise<CursorPageResponse<BugReport>>;
|
|
7
8
|
getBug(id: string): Promise<BugReport>;
|
|
8
9
|
updateBugStatus(id: string, status: string, resolution?: string): Promise<BugReport>;
|
|
10
|
+
listProjects(customerId: string, page?: number, size?: number): Promise<PaginatedResponse<Project>>;
|
|
11
|
+
createProject(customerId: string, request: CreateProjectRequest): Promise<Project>;
|
|
12
|
+
deleteProject(customerId: string, projectId: string): Promise<void>;
|
|
13
|
+
listRequests(customerId: string, page?: number, size?: number): Promise<PaginatedResponse<TestRequest>>;
|
|
14
|
+
createRequest(customerId: string, request: ManualDispatchRequest): Promise<TestRequest>;
|
|
15
|
+
getDispatch(dispatchId: string): Promise<DispatchResponse>;
|
|
16
|
+
getReport(reportId: string): Promise<Report>;
|
|
17
|
+
getReportDownloadUrl(reportId: string): Promise<{
|
|
18
|
+
url: string;
|
|
19
|
+
}>;
|
|
20
|
+
getReportsForDispatch(dispatchId: string): Promise<Report[]>;
|
|
21
|
+
getMe(): Promise<MeResponse>;
|
|
22
|
+
updateProject(customerId: string, projectId: string, request: UpdateProjectRequest): Promise<Project>;
|
|
23
|
+
listEnvironments(customerId: string, projectId: string): Promise<Environment[]>;
|
|
24
|
+
createEnvironment(customerId: string, projectId: string, request: CreateEnvironmentRequest): Promise<Environment>;
|
|
25
|
+
updateEnvironment(customerId: string, projectId: string, environmentId: string, request: UpdateEnvironmentRequest): Promise<Environment>;
|
|
26
|
+
deleteEnvironment(customerId: string, projectId: string, environmentId: string): Promise<void>;
|
|
27
|
+
private handleErrorResponse;
|
|
9
28
|
private request;
|
|
10
29
|
}
|
package/dist/client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AuthenticationError, NotFoundError, ServerError, ConnectionError, } from "./types.js";
|
|
1
|
+
import { AuthenticationError, NotFoundError, ServerError, ConnectionError, ConflictError, BillingError, ProjectLimitError, } from "./types.js";
|
|
2
2
|
export class PinpointClient {
|
|
3
3
|
baseUrl;
|
|
4
4
|
token;
|
|
@@ -8,13 +8,25 @@ export class PinpointClient {
|
|
|
8
8
|
}
|
|
9
9
|
async listBugs(options) {
|
|
10
10
|
const params = new URLSearchParams();
|
|
11
|
-
|
|
11
|
+
if (options?.status)
|
|
12
|
+
params.set("status", options.status);
|
|
12
13
|
if (options?.project)
|
|
13
14
|
params.set("project", options.project);
|
|
14
15
|
params.set("page", String(options?.page ?? 0));
|
|
15
16
|
params.set("size", String(options?.size ?? 20));
|
|
16
17
|
return this.request(`/api/v1/bugs?${params.toString()}`);
|
|
17
18
|
}
|
|
19
|
+
async listBugsWithCursor(options) {
|
|
20
|
+
const params = new URLSearchParams();
|
|
21
|
+
if (options?.status)
|
|
22
|
+
params.set("status", options.status);
|
|
23
|
+
if (options?.project)
|
|
24
|
+
params.set("project", options.project);
|
|
25
|
+
if (options?.cursor)
|
|
26
|
+
params.set("cursor", options.cursor);
|
|
27
|
+
params.set("size", String(options?.size ?? 50));
|
|
28
|
+
return this.request(`/api/v1/bugs?${params.toString()}`);
|
|
29
|
+
}
|
|
18
30
|
async getBug(id) {
|
|
19
31
|
return this.request(`/api/v1/bugs/${encodeURIComponent(id)}`);
|
|
20
32
|
}
|
|
@@ -29,6 +41,171 @@ export class PinpointClient {
|
|
|
29
41
|
body: JSON.stringify(body),
|
|
30
42
|
});
|
|
31
43
|
}
|
|
44
|
+
async listProjects(customerId, page, size) {
|
|
45
|
+
const params = new URLSearchParams();
|
|
46
|
+
params.set("page", String(page ?? 0));
|
|
47
|
+
params.set("size", String(size ?? 20));
|
|
48
|
+
return this.request(`/api/v1/customers/${encodeURIComponent(customerId)}/projects?${params.toString()}`);
|
|
49
|
+
}
|
|
50
|
+
async createProject(customerId, request) {
|
|
51
|
+
const url = `${this.baseUrl}/api/v1/customers/${encodeURIComponent(customerId)}/projects`;
|
|
52
|
+
let response;
|
|
53
|
+
try {
|
|
54
|
+
response = await fetch(url, {
|
|
55
|
+
method: "POST",
|
|
56
|
+
headers: {
|
|
57
|
+
Authorization: `Bearer ${this.token}`,
|
|
58
|
+
Accept: "application/json",
|
|
59
|
+
"Content-Type": "application/json",
|
|
60
|
+
},
|
|
61
|
+
body: JSON.stringify(request),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
throw new ConnectionError(this.baseUrl);
|
|
66
|
+
}
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
if (response.status === 402) {
|
|
69
|
+
try {
|
|
70
|
+
const body = await response.json();
|
|
71
|
+
throw new BillingError(String(body.message ?? "Billing confirmation required"), Number(body.priceCents ?? 0), String(body.tierName ?? "unknown"), Number(body.includedProjects ?? 0), Number(body.currentCount ?? 0));
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
if (e instanceof BillingError)
|
|
75
|
+
throw e;
|
|
76
|
+
throw new BillingError("Billing confirmation required", 0, "unknown", 0, 0);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (response.status === 403) {
|
|
80
|
+
try {
|
|
81
|
+
const body = await response.json();
|
|
82
|
+
throw new ProjectLimitError(String(body.message ?? "Project limit exceeded"));
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
if (e instanceof ProjectLimitError)
|
|
86
|
+
throw e;
|
|
87
|
+
throw new ProjectLimitError("Project limit exceeded");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
this.handleErrorResponse(response);
|
|
91
|
+
}
|
|
92
|
+
return response.json();
|
|
93
|
+
}
|
|
94
|
+
async deleteProject(customerId, projectId) {
|
|
95
|
+
const url = `${this.baseUrl}/api/v1/customers/${encodeURIComponent(customerId)}/projects/${encodeURIComponent(projectId)}`;
|
|
96
|
+
let response;
|
|
97
|
+
try {
|
|
98
|
+
response = await fetch(url, {
|
|
99
|
+
method: "DELETE",
|
|
100
|
+
headers: {
|
|
101
|
+
Authorization: `Bearer ${this.token}`,
|
|
102
|
+
Accept: "application/json",
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
throw new ConnectionError(this.baseUrl);
|
|
108
|
+
}
|
|
109
|
+
if (!response.ok && response.status !== 204) {
|
|
110
|
+
this.handleErrorResponse(response);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async listRequests(customerId, page, size) {
|
|
114
|
+
const params = new URLSearchParams();
|
|
115
|
+
params.set("page", String(page ?? 0));
|
|
116
|
+
params.set("size", String(size ?? 20));
|
|
117
|
+
return this.request(`/api/v1/customers/${encodeURIComponent(customerId)}/requests?${params.toString()}`);
|
|
118
|
+
}
|
|
119
|
+
async createRequest(customerId, request) {
|
|
120
|
+
const url = `${this.baseUrl}/api/v1/customers/${encodeURIComponent(customerId)}/requests`;
|
|
121
|
+
let response;
|
|
122
|
+
try {
|
|
123
|
+
response = await fetch(url, {
|
|
124
|
+
method: "POST",
|
|
125
|
+
headers: {
|
|
126
|
+
Authorization: `Bearer ${this.token}`,
|
|
127
|
+
Accept: "application/json",
|
|
128
|
+
"Content-Type": "application/json",
|
|
129
|
+
},
|
|
130
|
+
body: JSON.stringify(request),
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
throw new ConnectionError(this.baseUrl);
|
|
135
|
+
}
|
|
136
|
+
if (!response.ok) {
|
|
137
|
+
if (response.status === 409) {
|
|
138
|
+
try {
|
|
139
|
+
const body = await response.json();
|
|
140
|
+
throw new ConflictError(String(body.message ?? "A dispatch is already in progress for this project"));
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
if (e instanceof ConflictError)
|
|
144
|
+
throw e;
|
|
145
|
+
throw new ConflictError("A dispatch is already in progress for this project");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
this.handleErrorResponse(response);
|
|
149
|
+
}
|
|
150
|
+
return response.json();
|
|
151
|
+
}
|
|
152
|
+
async getDispatch(dispatchId) {
|
|
153
|
+
return this.request(`/api/v1/dispatch/${encodeURIComponent(dispatchId)}`);
|
|
154
|
+
}
|
|
155
|
+
async getReport(reportId) {
|
|
156
|
+
return this.request(`/api/v1/bug-reports/${encodeURIComponent(reportId)}`);
|
|
157
|
+
}
|
|
158
|
+
async getReportDownloadUrl(reportId) {
|
|
159
|
+
return this.request(`/api/v1/bug-reports/${encodeURIComponent(reportId)}/download`);
|
|
160
|
+
}
|
|
161
|
+
async getReportsForDispatch(dispatchId) {
|
|
162
|
+
return this.request(`/api/v1/dispatch/${encodeURIComponent(dispatchId)}/reports`);
|
|
163
|
+
}
|
|
164
|
+
async getMe() {
|
|
165
|
+
return this.request("/api/v1/me");
|
|
166
|
+
}
|
|
167
|
+
async updateProject(customerId, projectId, request) {
|
|
168
|
+
return this.request(`/api/v1/customers/${encodeURIComponent(customerId)}/projects/${encodeURIComponent(projectId)}`, {
|
|
169
|
+
method: "PUT",
|
|
170
|
+
headers: { "Content-Type": "application/json" },
|
|
171
|
+
body: JSON.stringify(request),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
async listEnvironments(customerId, projectId) {
|
|
175
|
+
return this.request(`/api/v1/customers/${encodeURIComponent(customerId)}/projects/${encodeURIComponent(projectId)}/environments`);
|
|
176
|
+
}
|
|
177
|
+
async createEnvironment(customerId, projectId, request) {
|
|
178
|
+
return this.request(`/api/v1/customers/${encodeURIComponent(customerId)}/projects/${encodeURIComponent(projectId)}/environments`, {
|
|
179
|
+
method: "POST",
|
|
180
|
+
headers: { "Content-Type": "application/json" },
|
|
181
|
+
body: JSON.stringify(request),
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
async updateEnvironment(customerId, projectId, environmentId, request) {
|
|
185
|
+
return this.request(`/api/v1/customers/${encodeURIComponent(customerId)}/projects/${encodeURIComponent(projectId)}/environments/${encodeURIComponent(environmentId)}`, {
|
|
186
|
+
method: "PUT",
|
|
187
|
+
headers: { "Content-Type": "application/json" },
|
|
188
|
+
body: JSON.stringify(request),
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
async deleteEnvironment(customerId, projectId, environmentId) {
|
|
192
|
+
await this.request(`/api/v1/customers/${encodeURIComponent(customerId)}/projects/${encodeURIComponent(projectId)}/environments/${encodeURIComponent(environmentId)}`, { method: "DELETE" });
|
|
193
|
+
}
|
|
194
|
+
handleErrorResponse(response) {
|
|
195
|
+
switch (response.status) {
|
|
196
|
+
case 401:
|
|
197
|
+
throw new AuthenticationError();
|
|
198
|
+
case 404:
|
|
199
|
+
throw new NotFoundError();
|
|
200
|
+
case 409:
|
|
201
|
+
throw new ConflictError(response.statusText);
|
|
202
|
+
default:
|
|
203
|
+
if (response.status >= 500) {
|
|
204
|
+
throw new ServerError(`Server error: ${response.status} ${response.statusText}`, response.status);
|
|
205
|
+
}
|
|
206
|
+
throw new ServerError(`Request failed: ${response.status} ${response.statusText}`, response.status);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
32
209
|
async request(path, init) {
|
|
33
210
|
const url = `${this.baseUrl}${path}`;
|
|
34
211
|
let response;
|
|
@@ -46,17 +223,7 @@ export class PinpointClient {
|
|
|
46
223
|
throw new ConnectionError(this.baseUrl);
|
|
47
224
|
}
|
|
48
225
|
if (!response.ok) {
|
|
49
|
-
|
|
50
|
-
case 401:
|
|
51
|
-
throw new AuthenticationError();
|
|
52
|
-
case 404:
|
|
53
|
-
throw new NotFoundError();
|
|
54
|
-
default:
|
|
55
|
-
if (response.status >= 500) {
|
|
56
|
-
throw new ServerError(`Server error: ${response.status} ${response.statusText}`, response.status);
|
|
57
|
-
}
|
|
58
|
-
throw new ServerError(`Request failed: ${response.status} ${response.statusText}`, response.status);
|
|
59
|
-
}
|
|
226
|
+
this.handleErrorResponse(response);
|
|
60
227
|
}
|
|
61
228
|
return response.json();
|
|
62
229
|
}
|