mongodb-mcp-server 0.0.8 → 0.1.1

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 (90) hide show
  1. package/.github/CODEOWNERS +0 -2
  2. package/.github/ISSUE_TEMPLATE/bug_report.yml +8 -0
  3. package/.github/workflows/{lint.yml → check.yml} +22 -1
  4. package/.github/workflows/code_health.yaml +0 -22
  5. package/.github/workflows/code_health_fork.yaml +7 -63
  6. package/.vscode/extensions.json +9 -0
  7. package/.vscode/settings.json +11 -0
  8. package/README.md +41 -22
  9. package/dist/common/atlas/apiClient.js +141 -34
  10. package/dist/common/atlas/apiClient.js.map +1 -1
  11. package/dist/common/atlas/apiClientError.js +38 -5
  12. package/dist/common/atlas/apiClientError.js.map +1 -1
  13. package/dist/common/atlas/cluster.js +66 -0
  14. package/dist/common/atlas/cluster.js.map +1 -0
  15. package/dist/common/atlas/generatePassword.js +9 -0
  16. package/dist/common/atlas/generatePassword.js.map +1 -0
  17. package/dist/helpers/EJsonTransport.js +38 -0
  18. package/dist/helpers/EJsonTransport.js.map +1 -0
  19. package/dist/helpers/connectionOptions.js +10 -0
  20. package/dist/helpers/connectionOptions.js.map +1 -0
  21. package/dist/{packageInfo.js → helpers/packageInfo.js} +1 -1
  22. package/dist/helpers/packageInfo.js.map +1 -0
  23. package/dist/index.js +6 -3
  24. package/dist/index.js.map +1 -1
  25. package/dist/logger.js +2 -0
  26. package/dist/logger.js.map +1 -1
  27. package/dist/server.js +15 -11
  28. package/dist/server.js.map +1 -1
  29. package/dist/session.js +8 -3
  30. package/dist/session.js.map +1 -1
  31. package/dist/telemetry/constants.js +1 -3
  32. package/dist/telemetry/constants.js.map +1 -1
  33. package/dist/telemetry/eventCache.js.map +1 -1
  34. package/dist/telemetry/telemetry.js +46 -4
  35. package/dist/telemetry/telemetry.js.map +1 -1
  36. package/dist/tools/atlas/atlasTool.js +38 -0
  37. package/dist/tools/atlas/atlasTool.js.map +1 -1
  38. package/dist/tools/atlas/create/createDBUser.js +19 -2
  39. package/dist/tools/atlas/create/createDBUser.js.map +1 -1
  40. package/dist/tools/atlas/metadata/connectCluster.js +5 -22
  41. package/dist/tools/atlas/metadata/connectCluster.js.map +1 -1
  42. package/dist/tools/atlas/read/inspectCluster.js +4 -24
  43. package/dist/tools/atlas/read/inspectCluster.js.map +1 -1
  44. package/dist/tools/atlas/read/listClusters.js +9 -18
  45. package/dist/tools/atlas/read/listClusters.js.map +1 -1
  46. package/dist/tools/mongodb/tools.js +2 -4
  47. package/dist/tools/mongodb/tools.js.map +1 -1
  48. package/eslint.config.js +2 -1
  49. package/{jest.config.ts → jest.config.cjs} +1 -1
  50. package/package.json +4 -2
  51. package/scripts/apply.ts +4 -1
  52. package/scripts/filter.ts +4 -0
  53. package/src/common/atlas/apiClient.ts +179 -37
  54. package/src/common/atlas/apiClientError.ts +58 -7
  55. package/src/common/atlas/cluster.ts +95 -0
  56. package/src/common/atlas/generatePassword.ts +10 -0
  57. package/src/common/atlas/openapi.d.ts +438 -15
  58. package/src/helpers/EJsonTransport.ts +47 -0
  59. package/src/helpers/connectionOptions.ts +20 -0
  60. package/src/{packageInfo.ts → helpers/packageInfo.ts} +1 -1
  61. package/src/index.ts +7 -3
  62. package/src/logger.ts +2 -0
  63. package/src/server.ts +22 -14
  64. package/src/session.ts +8 -4
  65. package/src/telemetry/constants.ts +2 -3
  66. package/src/telemetry/eventCache.ts +1 -1
  67. package/src/telemetry/telemetry.ts +72 -6
  68. package/src/telemetry/types.ts +0 -1
  69. package/src/tools/atlas/atlasTool.ts +47 -1
  70. package/src/tools/atlas/create/createDBUser.ts +22 -2
  71. package/src/tools/atlas/metadata/connectCluster.ts +5 -27
  72. package/src/tools/atlas/read/inspectCluster.ts +4 -40
  73. package/src/tools/atlas/read/listClusters.ts +19 -36
  74. package/src/tools/mongodb/tools.ts +2 -4
  75. package/src/types/mongodb-connection-string-url.d.ts +69 -0
  76. package/tests/integration/helpers.ts +18 -2
  77. package/tests/integration/telemetry.test.ts +28 -0
  78. package/tests/integration/tools/atlas/dbUsers.test.ts +57 -32
  79. package/tests/integration/tools/mongodb/metadata/connect.test.ts +2 -6
  80. package/tests/integration/tools/mongodb/mongodbHelpers.ts +15 -24
  81. package/tests/integration/tools/mongodb/read/find.test.ts +28 -0
  82. package/tests/unit/EJsonTransport.test.ts +71 -0
  83. package/tests/unit/apiClient.test.ts +193 -0
  84. package/tests/unit/session.test.ts +65 -0
  85. package/tests/unit/telemetry.test.ts +165 -71
  86. package/tsconfig.build.json +1 -1
  87. package/dist/packageInfo.js.map +0 -1
  88. package/dist/telemetry/device-id.js +0 -20
  89. package/dist/telemetry/device-id.js.map +0 -1
  90. package/src/telemetry/device-id.ts +0 -21
@@ -1,3 +1 @@
1
1
  * @mongodb-js/mcp-server-developers
2
- **/atlas @blva @fmenezes
3
- **/mongodb @nirinchev @gagik
@@ -7,6 +7,14 @@ body:
7
7
  - type: markdown
8
8
  attributes:
9
9
  value: "Please fill out the following details to help us address the issue."
10
+ - type: textarea
11
+ id: version
12
+ attributes:
13
+ label: "Version"
14
+ description: "Please provide the version of the MCP Server where the bug occurred. (e.g., 0.1.0, main branch sha, etc.)"
15
+ placeholder: "e.g., 0.1.0"
16
+ validations:
17
+ required: true
10
18
  - type: checkboxes
11
19
  id: app
12
20
  attributes:
@@ -1,10 +1,13 @@
1
1
  ---
2
- name: Lint
2
+ name: Checks
3
3
  on:
4
4
  push:
5
5
  branches:
6
6
  - main
7
7
  pull_request:
8
+ pull_request_target:
9
+ branches:
10
+ - main
8
11
 
9
12
  permissions: {}
10
13
 
@@ -35,3 +38,21 @@ jobs:
35
38
  - name: Install dependencies
36
39
  run: npm ci
37
40
  - run: npm run generate
41
+
42
+ check-dep:
43
+ name: Check dependencies
44
+ runs-on: ubuntu-latest
45
+ steps:
46
+ - uses: GitHubSecurityLab/actions-permissions/monitor@v1
47
+ - uses: actions/checkout@v4
48
+ - uses: actions/setup-node@v4
49
+ with:
50
+ node-version-file: package.json
51
+ cache: "npm"
52
+ - name: Install dependencies, build and remove dev dependencies
53
+ run: |
54
+ npm ci
55
+ rm -rf node_modules
56
+ npm pkg set scripts.prepare="exit 0"
57
+ npm install --omit=dev
58
+ - run: npx -y @modelcontextprotocol/inspector --cli --method tools/list -- node dist/index.js --connectionString "mongodb://localhost"
@@ -62,26 +62,6 @@ jobs:
62
62
  name: atlas-test-results
63
63
  path: coverage/lcov.info
64
64
 
65
- dep-check:
66
- name: Check dependencies
67
- if: github.event.pull_request.user.login != 'dependabot[bot]' && github.event.pull_request.head.repo.full_name == github.repository
68
- runs-on: ubuntu-latest
69
- steps:
70
- - uses: GitHubSecurityLab/actions-permissions/monitor@v1
71
- - uses: actions/checkout@v4
72
- - uses: actions/setup-node@v4
73
- with:
74
- node-version-file: package.json
75
- cache: "npm"
76
- - name: Install dependencies & build
77
- run: npm ci
78
- - name: Remove dev dependencies
79
- run: |
80
- rm -rf node_modules
81
- npm pkg set scripts.prepare="exit 0"
82
- npm install --omit=dev
83
- - run: npx -y @modelcontextprotocol/inspector --cli --method tools/list -- node dist/index.js --connectionString "mongodb://localhost"
84
-
85
65
  coverage:
86
66
  name: Report Coverage
87
67
  if: always() && github.event.pull_request.user.login != 'dependabot[bot]' && github.event.pull_request.head.repo.full_name == github.repository
@@ -112,5 +92,3 @@ jobs:
112
92
  uses: coverallsapp/github-action@v2.3.6
113
93
  with:
114
94
  file: coverage/lcov.info
115
- git-branch: ${{ github.head_ref || github.ref_name }}
116
- git-commit: ${{ github.event.pull_request.head.sha || github.sha }}
@@ -11,9 +11,14 @@ jobs:
11
11
  run-tests:
12
12
  name: Run MongoDB tests
13
13
  if: github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.head.repo.full_name != github.repository
14
- runs-on: ubuntu-latest
14
+ strategy:
15
+ matrix:
16
+ os: [ubuntu-latest, macos-latest, windows-latest]
17
+ fail-fast: false
18
+ runs-on: ${{ matrix.os }}
15
19
  steps:
16
20
  - uses: GitHubSecurityLab/actions-permissions/monitor@v1
21
+ if: matrix.os != 'windows-latest'
17
22
  - uses: actions/checkout@v4
18
23
  - uses: actions/setup-node@v4
19
24
  with:
@@ -24,71 +29,12 @@ jobs:
24
29
  - name: Run tests
25
30
  run: npm test
26
31
  - name: Upload test results
27
- if: always()
32
+ if: always() && matrix.os == 'ubuntu-latest'
28
33
  uses: actions/upload-artifact@v4
29
34
  with:
30
35
  name: test-results
31
36
  path: coverage/lcov.info
32
37
 
33
- run-atlas-tests:
34
- name: Run Atlas tests
35
- if: github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.head.repo.full_name != github.repository
36
- runs-on: ubuntu-latest
37
- steps:
38
- - uses: GitHubSecurityLab/actions-permissions/monitor@v1
39
- - uses: actions/checkout@v4
40
- - uses: actions/setup-node@v4
41
- with:
42
- node-version-file: package.json
43
- cache: "npm"
44
- - name: Install dependencies
45
- run: npm ci
46
- - name: Run tests
47
- env:
48
- MDB_MCP_API_CLIENT_ID: ${{ secrets.TEST_ATLAS_CLIENT_ID }}
49
- MDB_MCP_API_CLIENT_SECRET: ${{ secrets.TEST_ATLAS_CLIENT_SECRET }}
50
- MDB_MCP_API_BASE_URL: ${{ vars.TEST_ATLAS_BASE_URL }}
51
- run: npm test -- --testPathIgnorePatterns "tests/integration/tools/mongodb" --testPathIgnorePatterns "tests/integration/[^/]+\.ts"
52
- - name: Upload test results
53
- uses: actions/upload-artifact@v4
54
- if: always()
55
- with:
56
- name: atlas-test-results
57
- path: coverage/lcov.info
58
-
59
- coverage:
60
- name: Report Coverage
61
- if: always() && github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.head.repo.full_name != github.repository
62
- runs-on: ubuntu-latest
63
- needs: [run-tests, run-atlas-tests]
64
- steps:
65
- - uses: actions/checkout@v4
66
- - uses: actions/setup-node@v4
67
- with:
68
- node-version-file: package.json
69
- cache: "npm"
70
- - name: Install dependencies
71
- run: npm ci
72
- - name: Download test results
73
- uses: actions/download-artifact@v4
74
- with:
75
- name: test-results
76
- path: coverage/mongodb
77
- - name: Download atlas test results
78
- uses: actions/download-artifact@v4
79
- with:
80
- name: atlas-test-results
81
- path: coverage/atlas
82
- - name: Merge coverage reports
83
- run: |
84
- npx -y lcov-result-merger@5.0.1 "coverage/*/lcov.info" "coverage/lcov.info"
85
- - name: Coveralls GitHub Action
86
- uses: coverallsapp/github-action@v2.3.6
87
- with:
88
- file: coverage/lcov.info
89
- git-branch: ${{ github.head_ref || github.ref_name }}
90
- git-commit: ${{ github.event.pull_request.head.sha || github.sha }}
91
-
92
38
  merge-dependabot-pr:
93
39
  name: Merge Dependabot PR
94
40
  if: github.event.pull_request.user.login == 'dependabot[bot]'
@@ -96,8 +42,6 @@ jobs:
96
42
  permissions:
97
43
  pull-requests: write
98
44
  contents: write
99
- needs:
100
- - coverage
101
45
  steps:
102
46
  - name: Enable auto-merge for Dependabot PRs
103
47
  run: gh pr merge --auto --squash "$PR_URL"
@@ -0,0 +1,9 @@
1
+ {
2
+ // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
3
+ // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
4
+
5
+ // List of extensions which should be recommended for users of this workspace.
6
+ "recommendations": ["firsttris.vscode-jest-runner", "orta.vscode-jest"],
7
+ // List of extensions recommended by VS Code that should not be recommended for users of this workspace.
8
+ "unwantedRecommendations": []
9
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "jestrunner.jestCommand": "npm test --",
3
+ "jestrunner.debugOptions": {
4
+ "runtimeExecutable": "node",
5
+ "runtimeArgs": [
6
+ "--experimental-vm-modules",
7
+ "node_modules/jest/bin/jest.js",
8
+ "--coverage"
9
+ ]
10
+ }
11
+ }
package/README.md CHANGED
@@ -29,7 +29,7 @@ node -v
29
29
  ```
30
30
 
31
31
  - A MongoDB connection string or Atlas API credentials, **_the Server will not start unless configured_**.
32
- - **_Atlas API credentials_** are required to use the Atlas tools. You can create a service account in MongoDB Atlas and use its credentials for authentication. See [Atlas API Access](#atlas-api-access) for more details.
32
+ - **_Service Accounts Atlas API credentials_** are required to use the Atlas tools. You can create a service account in MongoDB Atlas and use its credentials for authentication. See [Atlas API Access](#atlas-api-access) for more details.
33
33
  - If you have a MongoDB connection string, you can use it directly to connect to your MongoDB instance.
34
34
 
35
35
  ## Setup
@@ -38,8 +38,10 @@ node -v
38
38
 
39
39
  Most MCP clients require a configuration file to be created or modified to add the MCP server.
40
40
 
41
+ Note: The configuration file syntax can be different across clients. Please refer to the following links for the latest expected syntax:
42
+
41
43
  - **Windsurf**:https://docs.windsurf.com/windsurf/mcp
42
- - **VSCode**: https://docs.codeium.com/docs/mcp
44
+ - **VSCode**: https://code.visualstudio.com/docs/copilot/chat/mcp-servers
43
45
  - **Claude Desktop**: https://modelcontextprotocol.io/quickstart/user
44
46
  - **Cursor**: https://docs.cursor.com/context/model-context-protocol
45
47
 
@@ -49,7 +51,7 @@ You can pass your connection string via args, make sure to use a valid username
49
51
 
50
52
  ```json
51
53
  {
52
- "servers": {
54
+ "mcpServers": {
53
55
  "MongoDB": {
54
56
  "command": "npx",
55
57
  "args": [
@@ -65,29 +67,44 @@ You can pass your connection string via args, make sure to use a valid username
65
67
 
66
68
  #### Option 2: Atlas API credentials args
67
69
 
68
- Use your Atlas API Service Account credentials. More details in the [Atlas API Access](#atlas-api-access) section.
70
+ Use your Atlas API Service Accounts credentials. Must follow all the steps in [Atlas API Access](#atlas-api-access) section.
69
71
 
70
72
  ```json
71
73
  {
72
- "servers": {
74
+ "mcpServers": {
73
75
  "MongoDB": {
74
76
  "command": "npx",
75
77
  "args": [
76
78
  "-y",
77
79
  "mongodb-mcp-server",
78
80
  "--apiClientId",
79
- "your-atlas-client-id",
81
+ "your-atlas-service-accounts-client-id",
80
82
  "--apiClientSecret",
81
- "your-atlas-client-secret"
83
+ "your-atlas-service-accounts-client-secret"
82
84
  ]
83
85
  }
84
86
  }
85
87
  }
86
88
  ```
87
89
 
88
- #### Other options
90
+ ### Option 3: Standalone Service using command arguments
91
+
92
+ Start Server using npx command:
93
+
94
+ ```shell
95
+ npx -y mongodb-mcp-server --apiClientId="your-atlas-service-accounts-client-id" --apiClientSecret="your-atlas-service-accounts-client-secret"
96
+ ```
97
+
98
+ - For a complete list of arguments see [Configuration Options](#configuration-options)
99
+ - To configure your Atlas Service Accounts credentials please refer to [Atlas API Access](#atlas-api-access)
89
100
 
90
- Alternatively you can use environment variables in the config file or set them and run the server via npx.
101
+ #### Option 4: Standalone Service using environment variables
102
+
103
+ ```shell
104
+ npx -y mongodb-mcp-server
105
+ ```
106
+
107
+ You can use environment variables in the config file or set them and run the server via npx.
91
108
 
92
109
  - Connection String via environment variables in the MCP file [example](#connection-string-with-environment-variables)
93
110
  - Atlas API credentials via environment variables in the MCP file [example](#atlas-api-credentials-with-environment-variables)
@@ -220,12 +237,14 @@ To use the Atlas API tools, you'll need to create a service account in MongoDB A
220
237
  - Select appropriate permissions (for full access, use Organization Owner)
221
238
  - Click "Create"
222
239
 
240
+ To learn more about Service Accounts, check the [MongoDB Atlas documentation](https://www.mongodb.com/docs/atlas/api/service-accounts-overview/).
241
+
223
242
  2. **Save Client Credentials:**
224
243
 
225
244
  - After creation, you'll be shown the Client ID and Client Secret
226
245
  - **Important:** Copy and save the Client Secret immediately as it won't be displayed again
227
246
 
228
- 3. **Add Access List Entry (Optional but recommended):**
247
+ 3. **Add Access List Entry:**
229
248
 
230
249
  - Add your IP address to the API access list
231
250
 
@@ -239,9 +258,9 @@ To use the Atlas API tools, you'll need to create a service account in MongoDB A
239
258
  Set environment variables with the prefix `MDB_MCP_` followed by the option name in uppercase with underscores:
240
259
 
241
260
  ```shell
242
- # Set Atlas API credentials
243
- export MDB_MCP_API_CLIENT_ID="your-atlas-client-id"
244
- export MDB_MCP_API_CLIENT_SECRET="your-atlas-client-secret"
261
+ # Set Atlas API credentials (via Service Accounts)
262
+ export MDB_MCP_API_CLIENT_ID="your-atlas-service-accounts-client-id"
263
+ export MDB_MCP_API_CLIENT_SECRET="your-atlas-service-accounts-client-secret"
245
264
 
246
265
  # Set a custom MongoDB connection string
247
266
  export MDB_MCP_CONNECTION_STRING="mongodb+srv://username:password@cluster.mongodb.net/myDatabase"
@@ -256,7 +275,7 @@ export MDB_MCP_LOG_PATH="/path/to/logs"
256
275
 
257
276
  ```json
258
277
  {
259
- "servers": {
278
+ "mcpServers": {
260
279
  "MongoDB": {
261
280
  "command": "npx",
262
281
  "args": ["-y", "mongodb-mcp-server"],
@@ -272,13 +291,13 @@ export MDB_MCP_LOG_PATH="/path/to/logs"
272
291
 
273
292
  ```json
274
293
  {
275
- "servers": {
294
+ "mcpServers": {
276
295
  "MongoDB": {
277
296
  "command": "npx",
278
297
  "args": ["-y", "mongodb-mcp-server"],
279
298
  "env": {
280
- "MDB_MCP_API_CLIENT_ID": "your-atlas-client-id",
281
- "MDB_MCP_API_CLIENT_SECRET": "your-atlas-client-secret"
299
+ "MDB_MCP_API_CLIENT_ID": "your-atlas-service-accounts-client-id",
300
+ "MDB_MCP_API_CLIENT_SECRET": "your-atlas-service-accounts-client-secret"
282
301
  }
283
302
  }
284
303
  }
@@ -290,7 +309,7 @@ export MDB_MCP_LOG_PATH="/path/to/logs"
290
309
  Pass configuration options as command-line arguments when starting the server:
291
310
 
292
311
  ```shell
293
- npx -y mongodb-mcp-server --apiClientId="your-atlas-client-id" --apiClientSecret="your-atlas-client-secret" --connectionString="mongodb+srv://username:password@cluster.mongodb.net/myDatabase" --logPath=/path/to/logs
312
+ npx -y mongodb-mcp-server --apiClientId="your-atlas-service-accounts-client-id" --apiClientSecret="your-atlas-service-accounts-client-secret" --connectionString="mongodb+srv://username:password@cluster.mongodb.net/myDatabase" --logPath=/path/to/logs
294
313
  ```
295
314
 
296
315
  #### MCP configuration file examples
@@ -299,7 +318,7 @@ npx -y mongodb-mcp-server --apiClientId="your-atlas-client-id" --apiClientSecret
299
318
 
300
319
  ```json
301
320
  {
302
- "servers": {
321
+ "mcpServers": {
303
322
  "MongoDB": {
304
323
  "command": "npx",
305
324
  "args": [
@@ -317,16 +336,16 @@ npx -y mongodb-mcp-server --apiClientId="your-atlas-client-id" --apiClientSecret
317
336
 
318
337
  ```json
319
338
  {
320
- "servers": {
339
+ "mcpServers": {
321
340
  "MongoDB": {
322
341
  "command": "npx",
323
342
  "args": [
324
343
  "-y",
325
344
  "mongodb-mcp-server",
326
345
  "--apiClientId",
327
- "your-atlas-client-id",
346
+ "your-atlas-service-accounts-client-id",
328
347
  "--apiClientSecret",
329
- "your-atlas-client-secret"
348
+ "your-atlas-service-accounts-client-secret"
330
349
  ]
331
350
  }
332
351
  }
@@ -1,7 +1,7 @@
1
1
  import createClient from "openapi-fetch";
2
2
  import { ClientCredentials } from "simple-oauth2";
3
3
  import { ApiClientError } from "./apiClientError.js";
4
- import { packageInfo } from "../../packageInfo.js";
4
+ import { packageInfo } from "../../helpers/packageInfo.js";
5
5
  const ATLAS_API_VERSION = "2025-03-12";
6
6
  export class ApiClient {
7
7
  constructor(options) {
@@ -26,13 +26,6 @@ export class ApiClient {
26
26
  }
27
27
  },
28
28
  };
29
- this.errorMiddleware = {
30
- async onResponse({ response }) {
31
- if (!response.ok) {
32
- throw await ApiClientError.fromResponse(response);
33
- }
34
- },
35
- };
36
29
  this.options = {
37
30
  ...options,
38
31
  userAgent: options.userAgent ||
@@ -58,11 +51,13 @@ export class ApiClient {
58
51
  });
59
52
  this.client.use(this.authMiddleware);
60
53
  }
61
- this.client.use(this.errorMiddleware);
62
54
  }
63
55
  hasCredentials() {
64
56
  return !!(this.oauth2Client && this.accessToken);
65
57
  }
58
+ async validateAccessToken() {
59
+ await this.getAccessToken();
60
+ }
66
61
  async getIpInfo() {
67
62
  const accessToken = await this.getAccessToken();
68
63
  const endpoint = "api/private/ipinfo";
@@ -81,19 +76,53 @@ export class ApiClient {
81
76
  return (await response.json());
82
77
  }
83
78
  async sendEvents(events) {
84
- let endpoint = "api/private/unauth/telemetry/events";
79
+ if (!this.options.credentials) {
80
+ await this.sendUnauthEvents(events);
81
+ return;
82
+ }
83
+ try {
84
+ await this.sendAuthEvents(events);
85
+ }
86
+ catch (error) {
87
+ if (error instanceof ApiClientError) {
88
+ if (error.response.status !== 401) {
89
+ throw error;
90
+ }
91
+ }
92
+ // send unauth events if any of the following are true:
93
+ // 1: the token is not valid (not ApiClientError)
94
+ // 2: if the api responded with 401 (ApiClientError with status 401)
95
+ await this.sendUnauthEvents(events);
96
+ }
97
+ }
98
+ async sendAuthEvents(events) {
99
+ const accessToken = await this.getAccessToken();
100
+ if (!accessToken) {
101
+ throw new Error("No access token available");
102
+ }
103
+ const authUrl = new URL("api/private/v1.0/telemetry/events", this.options.baseUrl);
104
+ const response = await fetch(authUrl, {
105
+ method: "POST",
106
+ headers: {
107
+ Accept: "application/json",
108
+ "Content-Type": "application/json",
109
+ "User-Agent": this.options.userAgent,
110
+ Authorization: `Bearer ${accessToken}`,
111
+ },
112
+ body: JSON.stringify(events),
113
+ });
114
+ if (!response.ok) {
115
+ throw await ApiClientError.fromResponse(response);
116
+ }
117
+ }
118
+ async sendUnauthEvents(events) {
85
119
  const headers = {
86
120
  Accept: "application/json",
87
121
  "Content-Type": "application/json",
88
122
  "User-Agent": this.options.userAgent,
89
123
  };
90
- const accessToken = await this.getAccessToken();
91
- if (accessToken) {
92
- endpoint = "api/private/v1.0/telemetry/events";
93
- headers["Authorization"] = `Bearer ${accessToken}`;
94
- }
95
- const url = new URL(endpoint, this.options.baseUrl);
96
- const response = await fetch(url, {
124
+ const unauthUrl = new URL("api/private/unauth/telemetry/events", this.options.baseUrl);
125
+ const response = await fetch(unauthUrl, {
97
126
  method: "POST",
98
127
  headers,
99
128
  body: JSON.stringify(events),
@@ -104,67 +133,145 @@ export class ApiClient {
104
133
  }
105
134
  // DO NOT EDIT. This is auto-generated code.
106
135
  async listClustersForAllProjects(options) {
107
- const { data } = await this.client.GET("/api/atlas/v2/clusters", options);
136
+ const { data, error, response } = await this.client.GET("/api/atlas/v2/clusters", options);
137
+ if (error) {
138
+ throw ApiClientError.fromError(response, error);
139
+ }
108
140
  return data;
109
141
  }
110
142
  async listProjects(options) {
111
- const { data } = await this.client.GET("/api/atlas/v2/groups", options);
143
+ const { data, error, response } = await this.client.GET("/api/atlas/v2/groups", options);
144
+ if (error) {
145
+ throw ApiClientError.fromError(response, error);
146
+ }
112
147
  return data;
113
148
  }
114
149
  async createProject(options) {
115
- const { data } = await this.client.POST("/api/atlas/v2/groups", options);
150
+ const { data, error, response } = await this.client.POST("/api/atlas/v2/groups", options);
151
+ if (error) {
152
+ throw ApiClientError.fromError(response, error);
153
+ }
116
154
  return data;
117
155
  }
118
156
  async deleteProject(options) {
119
- await this.client.DELETE("/api/atlas/v2/groups/{groupId}", options);
157
+ const { error, response } = await this.client.DELETE("/api/atlas/v2/groups/{groupId}", options);
158
+ if (error) {
159
+ throw ApiClientError.fromError(response, error);
160
+ }
120
161
  }
121
162
  async getProject(options) {
122
- const { data } = await this.client.GET("/api/atlas/v2/groups/{groupId}", options);
163
+ const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}", options);
164
+ if (error) {
165
+ throw ApiClientError.fromError(response, error);
166
+ }
123
167
  return data;
124
168
  }
125
169
  async listProjectIpAccessLists(options) {
126
- const { data } = await this.client.GET("/api/atlas/v2/groups/{groupId}/accessList", options);
170
+ const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}/accessList", options);
171
+ if (error) {
172
+ throw ApiClientError.fromError(response, error);
173
+ }
127
174
  return data;
128
175
  }
129
176
  async createProjectIpAccessList(options) {
130
- const { data } = await this.client.POST("/api/atlas/v2/groups/{groupId}/accessList", options);
177
+ const { data, error, response } = await this.client.POST("/api/atlas/v2/groups/{groupId}/accessList", options);
178
+ if (error) {
179
+ throw ApiClientError.fromError(response, error);
180
+ }
131
181
  return data;
132
182
  }
133
183
  async deleteProjectIpAccessList(options) {
134
- await this.client.DELETE("/api/atlas/v2/groups/{groupId}/accessList/{entryValue}", options);
184
+ const { error, response } = await this.client.DELETE("/api/atlas/v2/groups/{groupId}/accessList/{entryValue}", options);
185
+ if (error) {
186
+ throw ApiClientError.fromError(response, error);
187
+ }
135
188
  }
136
189
  async listClusters(options) {
137
- const { data } = await this.client.GET("/api/atlas/v2/groups/{groupId}/clusters", options);
190
+ const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}/clusters", options);
191
+ if (error) {
192
+ throw ApiClientError.fromError(response, error);
193
+ }
138
194
  return data;
139
195
  }
140
196
  async createCluster(options) {
141
- const { data } = await this.client.POST("/api/atlas/v2/groups/{groupId}/clusters", options);
197
+ const { data, error, response } = await this.client.POST("/api/atlas/v2/groups/{groupId}/clusters", options);
198
+ if (error) {
199
+ throw ApiClientError.fromError(response, error);
200
+ }
142
201
  return data;
143
202
  }
144
203
  async deleteCluster(options) {
145
- await this.client.DELETE("/api/atlas/v2/groups/{groupId}/clusters/{clusterName}", options);
204
+ const { error, response } = await this.client.DELETE("/api/atlas/v2/groups/{groupId}/clusters/{clusterName}", options);
205
+ if (error) {
206
+ throw ApiClientError.fromError(response, error);
207
+ }
146
208
  }
147
209
  async getCluster(options) {
148
- const { data } = await this.client.GET("/api/atlas/v2/groups/{groupId}/clusters/{clusterName}", options);
210
+ const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}/clusters/{clusterName}", options);
211
+ if (error) {
212
+ throw ApiClientError.fromError(response, error);
213
+ }
149
214
  return data;
150
215
  }
151
216
  async listDatabaseUsers(options) {
152
- const { data } = await this.client.GET("/api/atlas/v2/groups/{groupId}/databaseUsers", options);
217
+ const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}/databaseUsers", options);
218
+ if (error) {
219
+ throw ApiClientError.fromError(response, error);
220
+ }
153
221
  return data;
154
222
  }
155
223
  async createDatabaseUser(options) {
156
- const { data } = await this.client.POST("/api/atlas/v2/groups/{groupId}/databaseUsers", options);
224
+ const { data, error, response } = await this.client.POST("/api/atlas/v2/groups/{groupId}/databaseUsers", options);
225
+ if (error) {
226
+ throw ApiClientError.fromError(response, error);
227
+ }
157
228
  return data;
158
229
  }
159
230
  async deleteDatabaseUser(options) {
160
- await this.client.DELETE("/api/atlas/v2/groups/{groupId}/databaseUsers/{databaseName}/{username}", options);
231
+ const { error, response } = await this.client.DELETE("/api/atlas/v2/groups/{groupId}/databaseUsers/{databaseName}/{username}", options);
232
+ if (error) {
233
+ throw ApiClientError.fromError(response, error);
234
+ }
235
+ }
236
+ async listFlexClusters(options) {
237
+ const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}/flexClusters", options);
238
+ if (error) {
239
+ throw ApiClientError.fromError(response, error);
240
+ }
241
+ return data;
242
+ }
243
+ async createFlexCluster(options) {
244
+ const { data, error, response } = await this.client.POST("/api/atlas/v2/groups/{groupId}/flexClusters", options);
245
+ if (error) {
246
+ throw ApiClientError.fromError(response, error);
247
+ }
248
+ return data;
249
+ }
250
+ async deleteFlexCluster(options) {
251
+ const { error, response } = await this.client.DELETE("/api/atlas/v2/groups/{groupId}/flexClusters/{name}", options);
252
+ if (error) {
253
+ throw ApiClientError.fromError(response, error);
254
+ }
255
+ }
256
+ async getFlexCluster(options) {
257
+ const { data, error, response } = await this.client.GET("/api/atlas/v2/groups/{groupId}/flexClusters/{name}", options);
258
+ if (error) {
259
+ throw ApiClientError.fromError(response, error);
260
+ }
261
+ return data;
161
262
  }
162
263
  async listOrganizations(options) {
163
- const { data } = await this.client.GET("/api/atlas/v2/orgs", options);
264
+ const { data, error, response } = await this.client.GET("/api/atlas/v2/orgs", options);
265
+ if (error) {
266
+ throw ApiClientError.fromError(response, error);
267
+ }
164
268
  return data;
165
269
  }
166
270
  async listOrganizationProjects(options) {
167
- const { data } = await this.client.GET("/api/atlas/v2/orgs/{orgId}/groups", options);
271
+ const { data, error, response } = await this.client.GET("/api/atlas/v2/orgs/{orgId}/groups", options);
272
+ if (error) {
273
+ throw ApiClientError.fromError(response, error);
274
+ }
168
275
  return data;
169
276
  }
170
277
  }