mongodb-mcp-server 0.1.0 → 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 +39 -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)
100
+
101
+ #### Option 4: Standalone Service using environment variables
102
+
103
+ ```shell
104
+ npx -y mongodb-mcp-server
105
+ ```
89
106
 
90
- Alternatively you can use environment variables in the config file or set them and run the server via npx.
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)
@@ -227,7 +244,7 @@ To learn more about Service Accounts, check the [MongoDB Atlas documentation](ht
227
244
  - After creation, you'll be shown the Client ID and Client Secret
228
245
  - **Important:** Copy and save the Client Secret immediately as it won't be displayed again
229
246
 
230
- 3. **Add Access List Entry (Optional but recommended):**
247
+ 3. **Add Access List Entry:**
231
248
 
232
249
  - Add your IP address to the API access list
233
250
 
@@ -241,9 +258,9 @@ To learn more about Service Accounts, check the [MongoDB Atlas documentation](ht
241
258
  Set environment variables with the prefix `MDB_MCP_` followed by the option name in uppercase with underscores:
242
259
 
243
260
  ```shell
244
- # Set Atlas API credentials
245
- export MDB_MCP_API_CLIENT_ID="your-atlas-client-id"
246
- 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"
247
264
 
248
265
  # Set a custom MongoDB connection string
249
266
  export MDB_MCP_CONNECTION_STRING="mongodb+srv://username:password@cluster.mongodb.net/myDatabase"
@@ -258,7 +275,7 @@ export MDB_MCP_LOG_PATH="/path/to/logs"
258
275
 
259
276
  ```json
260
277
  {
261
- "servers": {
278
+ "mcpServers": {
262
279
  "MongoDB": {
263
280
  "command": "npx",
264
281
  "args": ["-y", "mongodb-mcp-server"],
@@ -274,13 +291,13 @@ export MDB_MCP_LOG_PATH="/path/to/logs"
274
291
 
275
292
  ```json
276
293
  {
277
- "servers": {
294
+ "mcpServers": {
278
295
  "MongoDB": {
279
296
  "command": "npx",
280
297
  "args": ["-y", "mongodb-mcp-server"],
281
298
  "env": {
282
- "MDB_MCP_API_CLIENT_ID": "your-atlas-client-id",
283
- "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"
284
301
  }
285
302
  }
286
303
  }
@@ -292,7 +309,7 @@ export MDB_MCP_LOG_PATH="/path/to/logs"
292
309
  Pass configuration options as command-line arguments when starting the server:
293
310
 
294
311
  ```shell
295
- 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
296
313
  ```
297
314
 
298
315
  #### MCP configuration file examples
@@ -301,7 +318,7 @@ npx -y mongodb-mcp-server --apiClientId="your-atlas-client-id" --apiClientSecret
301
318
 
302
319
  ```json
303
320
  {
304
- "servers": {
321
+ "mcpServers": {
305
322
  "MongoDB": {
306
323
  "command": "npx",
307
324
  "args": [
@@ -319,16 +336,16 @@ npx -y mongodb-mcp-server --apiClientId="your-atlas-client-id" --apiClientSecret
319
336
 
320
337
  ```json
321
338
  {
322
- "servers": {
339
+ "mcpServers": {
323
340
  "MongoDB": {
324
341
  "command": "npx",
325
342
  "args": [
326
343
  "-y",
327
344
  "mongodb-mcp-server",
328
345
  "--apiClientId",
329
- "your-atlas-client-id",
346
+ "your-atlas-service-accounts-client-id",
330
347
  "--apiClientSecret",
331
- "your-atlas-client-secret"
348
+ "your-atlas-service-accounts-client-secret"
332
349
  ]
333
350
  }
334
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
  }